I;m working on a project with the card game War, butI’m having an issue with a variable combined with an array. It says Uncaught TypeError: player[0] is undefined
.
I tried making player[0][0]
into player[0,0]
, but to no avail, as it just says Uncaught DOMException: Node.appendChild: The new child is an ancestor of the parent
, so honestly I have no idea.
I’m sorry for wasting your time if this is a mere typo or can’t be reproduced.
Here’s my code like before:
var player = [];
var computer = [];
var playedCards = [];
var cards = [];
var $player = $("#player");
var $playerNumber = $("#playerNumber");
var $playerSuit = $("#playerSuit");
var $computer = $("#computer");
var $computerNumber = $("#computernumber");
var $computerSuit = $("#computerSuit");
var $draw = $("#draw");
var $winner = $("#winner");
var $playerCards = $("#playerCards");
var $computerCards = $("#computerCards");
var number1;
var number2;
var suit1;
var suit2;
var numberImg1;
var numberImg2;
for (i=1; i<14; i++){
for (k=1; k<5; k++) {
var j = [i,k];
playedCards.push(j);
}
}
cards.shuffle = function() {
console.log("shuffle");
var input = this
for (var i = cards.length-1; i >=0; i--) {
var randomIndex = Math.floor(Math.random()*(i+1));
var itemAtIndex = cards[randomIndex][0];
var itemAtSecond = cards[randomIndex][1];
input[randomIndex][0] = input[i][0];
input[randomIndex][1] = input[i][1];
input[i][0] = itemAtIndex;
input[i][1] = itemAtSecond;
}
return input
}
cards.shuffle();
function assign(){
if(player.length == 0 || computer.length == 0){
endgame();
}
$playerSuit.empty();
$computerSuit.empty();
var number1=player[0][0]; //This line has the error
var number2=computer[0][0]; //If that one ^ does, then this one likely will too
$playerNumber.html(number1);
$computernumber.html(number2);
suit1 = player[0][1]; //That also applies to this...
suit2 = computer[0][1]; //...and this
if (suit1 == 1) {
suit1 = "<img src='resources/images/heart.png"
}
if (suit1 == 2) {
suit1 = "<img src='resources/images/club.png"
}
if (suit1 == 3) {
suit1 = "<img src='resources/images/diamond.png"
}
if (suit1 == 4) {
suit1 = "<img src='resources/images/spade.png"
}
if (suit2 == 1) {
suit2 = "<img src='resources/images/heart.png"
}
if (suit2 == 2) {
suit2 = "<img src='resources/images/club.png"
}
if (suit2 == 3) {
suit2 = "<img src='resources/images/diamond.png"
}
if (suit2 == 4) {
suit2 = "<img src='resources/images/spade.png"
}
if (number1<11){
for (i=0; i<number1; i++) {
$firstPlayerSuit.append(suit1);
};
} else {
if (number1 == 11) {
numberImg1 = "<img src='resources/images/jack.png'/>";
$playerSuit.append(suit1);
$playerNumber.html(numberImg1);
}
if (number1 == 12) {
numberImg1 = "<img src='resources/images/queen.png'/>";
$playerSuit.append(suit1);
$playerNumber.html(numberImg1);
}
if (number1 == 13) {
numberImg1 = "<img src='resources/images/king.png'/>";
$playerSuit.append(suit1);
$playerNumber.html(numberImg1);
}
}
if (number2<11){
for (i=0; i<number2; i++) {
$computerSuit.append(suit2);
};
} else {
if (number2 == 11) {
numberImg2 = "<img src='resources/images/jack.png'/>";
$computerSuit.append(suit2);
$computerNumber.html(numberImg2);
}
if (number2 == 12) {
numberImg2 = "<img src='resources/images/queen.png'/>";
$computerSuit.append(suit2);
$firstPlayerNumber.html(numberImg2);
}
if (number2 == 13) {
numberImg2 = "<img src='resources/images/king.png'/>";
$computerSuit.append(suit2);
$computerNumber.html(numberImg2);
}
}
for (i=0; i<number1; i++) {
$playerSuit.append(suit1);
};
for (i=0; i<number2; i++) {
$computerSuit.append(suit2);
}
playedCards.push(player[0]);
playedCards.push(computer[0]);
player.splice(0,1);
computer.splice(0,1);
console.log("call greater");
greater();
}
function war(){
$winner.html("Time for a war!")
console.log("war");
for (i=0; i<3; i++){
playedCards.push(player[0]);
playedCards.push(computer[0]);
player.splice(0,1);
computer.splice(0,1);
}
$playerSuit.css("display", "none");
$computerSuit.css("display", "none");
numberImg1 = "<img style='height:14rem;' src='resources/images/card.png'/>";
numberImg2 = "<img style='height:14rem;' src='resources/images/card.png'/>";
console.log("call greater");
greater();
}
function greater(){
console.log("greater");
console.log("in greater how many played ", playedCards.length);
if (number1 > number2) {
$winner.html("Player Wins");
for (i=0; i<playedCards.length; i++) {
player.push(playedCards[i])
}
} else if (number1 < number2) {
$winner.html("Computer Wins");
for (i=0; i<playedCards.length; i++) {
computer.push(playedCards[i])
}
} else if (number1 == number2) {
console.log("call war");
war();
}
playedCards = [];
$playerCards.html(player.length);
$computerCards.html(computer.length);
}
$draw.on("click", function() {
assign();
})
function endgame(){
if(player.length == 0){
$winner.html("Game over </br> You have no more cards </br> You lose");
$computerNumber.html("Win");
$playerNumber.html("Lose");
}
if(computer.length == 0){
$winner.html("Game over </br> Computer has no more cards </br> You win");
$computerNumber.html("Lose");
$playerNumber.html("Win");
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="gameboard" class="flex">
<div class="flexColumn">
<h1>War</h1>
<h2 id="winner">Winner</h2>
<h3>Player has <span id="playerCards"></span> cards.</h3>
<h3>Computer has <span id="computerCards"></span> cards.</h3>
</div>
<div class="flex">
<div id="player" class="flexColumn player">
<h2>Player</h2>
<div id="playerNumber" class="number">
</div>
<div id="playerSuit" class="suit">
</div>
</div>
<h2 id="draw">Draw</h2>
<div id="computer" class="flexColumn player">
<h2>Computer</h2>
<div id="computerNumber" class="number">
</div>
<div id="computerSuit" class="suit">
</div>
</div>
</div>
</div>
</div>
and a screenshot so you can see for yourself (unrelated, but this time I didn’t use such grating colors)
[A screenshot of my project]
2
Answers
I think the problem is with the initialisation. I don’t understand what you want to achieve, but the declaration of
var player = [];
means that player is an array, so it is one-dimensional and accessing it’s element can be done only byplayer[i]
, and notplayer[i][j]
Try to declare
var player = [[]]
if you want to be able to accessplayer[i][j]
.In your JavaScript, you seem to be missing a return statement after calling
endgame()
. With this missing return statement, your check to ensure the player and computer 2D arrays aren’t empty fails to stop the execution of code that requires the 2 arrays to have at least one entry. The code below should fix your problem.