1

Im learning JS and the new project Im working on is about a card game with 52 cards. Im trying to mix all the cards to give them out to places where the players are. I try to only deal player one's card first to see if my code works or not but it just shows one random card even though each player has to get 13 cards

function Start() {

  let Karten = new Array();

  Karten[0] = "1h.png";
  Karten[1] = "2h.png";
  Karten[2] = "3h.png";
  Karten[3] = "4h.png";
  Karten[4] = "5h.png";
  Karten[5] = "6h.png";
  Karten[6] = "7h.png";
  Karten[7] = "8h.png";
  Karten[8] = "9h.png";
  Karten[9] = "10h.png";
  Karten[10] = "soldath.png";
  Karten[11] = "queenh.png";
  Karten[12] = "kingh.png";
  Karten[13] = "1k.png";
  Karten[14] = "2k.png";
  Karten[15] = "3k.png";
  Karten[16] = "4k.png";
  Karten[17] = "5k.png";
  Karten[18] = "6k.png";
  Karten[19] = "7k.png";
  Karten[20] = "8k.png";
  Karten[21] = "9k.png";
  Karten[22] = "10k.png";
  Karten[23] = "soldatk.png";
  Karten[24] = "queenk.png";
  Karten[25] = "kingk.png";
  Karten[26] = "1ka.png";
  Karten[27] = "2ka.png";
  Karten[28] = "3ka.png";
  Karten[29] = "4ka.png";
  Karten[30] = "5ka.png";
  Karten[31] = "6ka.png";
  Karten[32] = "7ka.png";
  Karten[33] = "8ka.png";
  Karten[34] = "9ka.png";
  Karten[35] = "10ka.png";
  Karten[36] = "soldatka.png";
  Karten[37] = "queenka.png";
  Karten[38] = "kingka.png";
  Karten[39] = "1p.png";
  Karten[40] = "2p.png";
  Karten[41] = "3p.png";
  Karten[42] = "4p.png";
  Karten[43] = "5p.png";
  Karten[44] = "6p.png";
  Karten[45] = "7p.png";
  Karten[46] = "8p.png";
  Karten[47] = "9p.png";
  Karten[48] = "10p.png";
  Karten[49] = "soldap.png";
  Karten[50] = "queenp.png";
  Karten[51] = "king.png";





  var zufall = Math.floor(Math.random() * Karten.length);

  document.getElementById("Karten").src = Karten[zufall];

}
<div id="alles">
  <div id="Spieler1">
    spieler1
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
    <img id="Karten">
  </div>
  <div id="Spieler2">
    spieler2
  </div>
  <div id="Spieler3">
    spieler3
  </div>
  <div id="Spieler4">
    spieler4
  </div>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Amir004
  • 19
  • 3
  • 6
    Please note you Can't have multiple elements with the same id. – Carsten Løvbo Andersen Feb 23 '23 at 07:28
  • FYI: `Karten[51] = "king.png";` probably should be `Karten[51] = "kingp.png";` – DarkBee Feb 23 '23 at 07:42
  • it was hinted that you cannot have the same id repeated. An id should be unique. So one solution could be to just have 13 different img elements with a different id: `karten1`, `karten2`... or you could just use a class and select the img elements using `document.getElementsByClassName` – Diego D Feb 23 '23 at 07:47
  • 2
    personally, I would recommend the usage of an array literal. It would shorten the code. Then you should create a 2nd array that uses the first array in a randomized order. If you hand out cards, they need to be removed from the 2nd array so they can't be given out again. – tacoshy Feb 23 '23 at 07:48
  • i actually tried it with class but it didn´t work, and thank you for your note – Amir004 Feb 23 '23 at 07:48
  • why did it not work? what have you tried with class? – tacoshy Feb 23 '23 at 07:48
  • 1
    As @CarstenLøvboAndersen mentioned, the **id attribute must be unique** in your HTML. So you could do something like `...` etc, where the *class* attribute can have multiple classes separated by spaces but *card* or *karte* would be enough for CSS theming and the *id* would be a concatenation of the user and the card number because `karten1` proposed by @DiegoD would be repeated 4 times so not unique. – Patrick Janser Feb 23 '23 at 07:51
  • the images were not displayed, but when I tried it with IDs at least i got one random image displayed – Amir004 Feb 23 '23 at 07:54
  • Of course, that is because you overwriting the same image 4 times as you don't use unique id's as mentioned several times already. – DarkBee Feb 23 '23 at 08:14
  • @Amir004 it's not clear if you need to solve the problem you have in the code you shared or if you really mean to actually have a working deck. The correct way to address this challenge should be having a deck, shuffle it and just pick the card in the order they are after shuffling. My first suggestion was aimed at trying to make that code work with no errors. But it's not the correct strategy to begin with – Diego D Feb 23 '23 at 08:27
  • if you failed at using [document.getElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName) how did you fail? if you just have a class like `player1` and `player2` and no id at all, and you set the `class` attribute of the `img` elements so that when you do `document.getElementsByClassName('player1')` it will return a list of elements how it's failing in your scenario? There are dozen ways to attack this problem.. it's pointless to argue on details. By the way since it wasn't said clear, if the id isn't unique, `getElementById` will just fail – Diego D Feb 23 '23 at 08:30

2 Answers2

2
  1. IDs need to be unique
  2. DRY, do not repeat yourself
  3. Shuffle the array before using it

Here is an advanced version that is worth studying

const getShuffledArr = arr => { if (arr.length === 1) { return arr}; const rand = Math.floor(Math.random() * arr.length); return [arr[rand], ...getShuffledArr(arr.filter((_, i) => i != rand))]; }; // https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
const karten = getShuffledArr(["h", "k", "a", "p"].flatMap(farbe => Array.from({length: 10})
  .map((_, i) => `${i+1}${farbe}.png`).concat(["soldat", "queen", "kingh"].map(card => `${card}${farbe}.png`)))); // shuffled array

const len = karten.length;
const handLength = 13;
const start = () => { 
  document.getElementById("alles").innerHTML = Array.from({length: 4})
    .map((_, i) => `<div class="spieler" id="spieler${i+1}"><h3>Spieler ${i+1}</h3>
    ${Array.from({length: 13})
      .map((_, i) => `<img src="${karten.pop()}" />`).join('')} // we could sort here
  </div>`).join('');
};
window.addEventListener("DOMContentLoaded",start)
<div id="alles">
 
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

There are many issues in your code that start with a faulty concept.

You have an array of 52 cards, pick then a random card and display it to the hand of player 1.

There your concept already fails. It allows the script to theoretically give all 4 players the same card 13 times. If you hand out cards to players, then the same card can in reality only exist once.

  1. You should shuffle your deck of cards where you can use shuffling algorithms as explained here
  2. You need to create a copy of your array by using the Array.from() method
  3. Then you need to hand out the cards to the players and remove that card from the deck by using the Array.prototype.shift() method
  4. Last but not least you should display the cards by adding the images dynamically with the createElement function

// creates a deck of 52 cards dynamically
const KARTEN = [
  'Karo 2',
  'Karo 3',
  'Karo 4',
  'Karo 5',
  'Karo 6',
  'Karo 7',
  'Karo 8',
  'Karo 9',
  'Karo 10',
  'Karo Bube',
  'Karo Dame',
  'Karo König',
  'Karo Ass',
  'Herz 2',
  'Herz 3',
  'Herz 4',
  'Herz 5',
  'Herz 6',
  'Herz 7',
  'Herz 8',
  'Herz 9',
  'Herz 10',
  'Herz Bube',
  'Herz Dame',
  'Herz König',
  'Herz Ass',
  'Pik 2',
  'Pik 3',
  'Pik 4',
  'Pik 5',
  'Pik 6',
  'Pik 7',
  'Pik 8',
  'Pik 9',
  'Pik 10',
  'Pik Bube',
  'Pik Dame',
  'Pik König',
  'Pik Ass',
  'Kreuz 2',
  'Kreuz 3',
  'Kreuz 4',
  'Kreuz 5',
  'Kreuz 6',
  'Kreuz 7',
  'Kreuz 8',
  'Kreuz 9',
  'Kreuz 10',
  'Kreuz Bube',
  'Kreuz Dame',
  'Kreuz König',
  'Kreuz Ass'
];
const HAND_SPIELER_EINS = document.querySelector('#kartenSpieler1');

document.querySelector('button').addEventListener('click', function() {
  leereHaende();
  mischeKarten();
});

// clears the hands of the players 
function leereHaende() {
  while (HAND_SPIELER_EINS.firstChild) {
    HAND_SPIELER_EINS.removeChild(HAND_SPIELER_EINS.lastChild);
  }
  kartenSpielerEins = [];
}

// creates a shuffled copy of the deck
let gemischteKarten;

function mischeKarten() {
    for (let i = KARTEN.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [KARTEN[i], KARTEN[j]] = [KARTEN[j], KARTEN[i]];
    }
    
    gemischteKarten = Array.from(KARTEN);
    
    verteileKarten();
}


// distribute cards to 4 players
let kartenSpielerEins = [];
  
function verteileKarten() {
  for (let i = 13; i > 0; i--) { 
    kartenSpielerEins.push(gemischteKarten.shift());
  }
  
  kartenAnzeigen();
}


// displays the cards
function kartenAnzeigen() {
  for (let i = 0; i < kartenSpielerEins.length; i++) {
    let neueKarte = document.createElement('img');
    neueKarte.alt = kartenSpielerEins[i];
    HAND_SPIELER_EINS.appendChild(neueKarte);
  }
}
img {
  display: block;
}
<button>Teile Karten Aus</button>

<div id="kartenSpieler1"></div>
tacoshy
  • 10,642
  • 5
  • 17
  • 34