我的对象内部有属性。但仍然出现错误“无法读取未定义的属性”值”

时间:2019-04-15 04:07:47

标签: javascript

我正在用Javascript开发战争游戏的纸牌游戏。但是在使用Object.value时出现错误,无法读取未定义的属性。该对象内部有属性。为什么读取未定义?

在此代码中,当玩家1玩纸牌时,它与玩家2的纸牌值匹配,并且拥有较高纸牌的人获胜。获胜者将两张牌都拿到手中。游戏将继续进行,直到其中一位玩家拥有52张卡。

此代码有时会给赢家。但是大多数情况下,如果其中一位玩家的卡牌超过45张,就会出现错误。此后,错误提示是

  

console.log(播放器1播放的$ {player1Card.value}为   $ {player1Card.suit} );                                                   ^

     

TypeError:无法读取未定义的属性“值”

错误在

  

类游戏-> turn()方法

let draw = false;
let cardOfPlayer1 = [];
let cardOfPlayer2 = [];

class Deck {
  constructor() {
    this.cards = [];
    ["spades","diamonds",'heart','clubs'].forEach(suit => {
      [2,3,4,5,6,7,8,9,10,11,12,13,14].forEach(value => {
        this.cards.push(new Card(suit, value));
      })
    })
  }

  shuffle() {
    let currentIndex = this.cards.length, temporaryValue, randomIndex;

    while (currentIndex !== 0) {
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;
      temporaryValue = this.cards[currentIndex];
      this.cards[currentIndex] = this.cards[randomIndex];
      this.cards[randomIndex] = temporaryValue;
    }
  }
}

class Card {
  constructor(suit, value) {
    this.suit = suit;
    this.value = value;
  }
}

class Player {
  constructor() {
    this.hand = [];
  }
}

class Game {
  constructor(player1, player2, deck) {
    this.players = [player1, player2];
    this.deck = deck;
    this.done = false;
    this.deck.shuffle();
    
  }

  deal() {
    this.deck.cards.forEach((card, index) => {
      this.players[index % 2].hand.push(card);
    });

    console.log(this.players[0].hand, this.players[1].hand);
  }

  play() {
    let count = 0;
    while(!this.done) {
      console.log(`Turn #${count++}`);
      this.turn();
      this.checkWinner();
    }
  }

  turn() {
    const player1Card = this.players[0].hand.shift();
    const player2Card = this.players[1].hand.shift();

    console.log(`Player 1 plays a ${player1Card.value} of ${player1Card.suit}`);
    console.log(`Player 2 plays a ${player2Card.value} of ${player2Card.suit}`);

    if(player1Card.value > player2Card.value) {
      console.log(`Player 1 plays wins this hand`);
      if(!draw){
      this.players[0].hand.push(player1Card);
      this.players[0].hand.push(player2Card);
      }else{
        this.players[0].hand.push(player1Card);
        this.players[0].hand.push(player2Card);
        this.players[0].hand.concat(cardOfPlayer1);
        this.players[0].hand.concat(cardOfPlayer2);
        cardOfPlayer1 = [];
        cardOfPlayer2 = [];
        draw = false;
      }
      console.log(`Player 1 has ${this.players[0].hand.length} cards`);

    } else if(player1Card.value < player2Card.value){
      console.log(`Player 2 plays wins this hand`);
      if(!draw){
        this.players[1].hand.push(player2Card);
        this.players[1].hand.push(player1Card);
        }else{
          this.players[1].hand.push(player2Card);
          this.players[1].hand.push(player1Card);
          this.players[1].hand.concat(cardOfPlayer1);
          this.players[1].hand.concat(cardOfPlayer2);
          cardOfPlayer1 = [];
          cardOfPlayer2 = [];
          draw = false;
        }
      console.log(`Player 2 has ${this.players[1].hand.length} cards`);

    } else if(player1Card.value === player2Card.value){
      
       cardOfPlayer1.push(player1Card);
       cardOfPlayer2.push(player2Card);
      console.log(cardOfPlayer1);
      console.log(cardOfPlayer2);

      draw = true;
      this.turn();

    }
  }

  checkWinner() {
    if (this.players[0].hand.length === this.deck.length) {
      console.log('Player 1 Wins');
      this.done = true;
    } else if (this.players[1].hand.length === this.deck.length) {
      console.log('Player 2 Wins');
      this.done = true;
    }
  }
}

const game = new Game(new Player(), new Player(), new Deck())

game.deal();
game.play();

2 个答案:

答案 0 :(得分:1)

您的代码每次只能保存2张纸牌-如果连续2张纸牌,您只会丢掉纸牌

您还检查this.deck.length,但是this.deck是Deck的一个实例-您需要检查this.deck.cards.length

我建议checkWinner应该是

  checkWinner() {
    if (this.players[0].hand.length === 0 && this.players[1].hand.length === 0) {
      console.log("It's a draw!!!!!");
    } else if (this.players[0].hand.length === 0) {
      console.log('Player 2 Wins');
      this.done = true;
    } else if (this.players[1].hand.length === 0) {
      console.log('Player 1 Wins');
      this.done = true;
    }
  }
}

因为如果最后一手是平局,那么您将看不到有一个玩家没有任何纸牌,因此,实际上,当另一名玩家没有纸牌时,该玩家获胜-这就是上面代码的作用< / p>

对于这种情况下出现平局时发生的情况,您可能想考虑逻辑上的其他策略

在极少但统计上可能的情况下,也有连续26次平局的情况-即在游戏中某个时刻,两名玩家都有26张卡,然后连续26次平局...两名玩家都将拥有最后一次抽奖后还剩下零张牌...所以,这是(很少)平局:p

所以,下面的错误已纠正

  • 请勿在绘制条件下调用this.turn()
  • 比较每个玩家的手长为0,看看对方是否赢了
  • 如果是平局,则将当前卡推到一个数组
  • 如果不是平局,则将先前绘制的卡的阵列从其所在位置推入,然后清除这些阵列

let draw = false;
let cardOfPlayer1 = [];
let cardOfPlayer2 = [];

class Deck {
  constructor() {
    this.cards = [];
    ["spades", "diamonds", 'heart', 'clubs'].forEach(suit => {
      [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14].forEach(value => {
        this.cards.push(new Card(suit, value));
      })
    })
  }

  shuffle() {
    let currentIndex = this.cards.length,
      temporaryValue, randomIndex;

    while (currentIndex !== 0) {
      randomIndex = Math.floor(Math.random() * currentIndex);
      currentIndex -= 1;
      temporaryValue = this.cards[currentIndex];
      this.cards[currentIndex] = this.cards[randomIndex];
      this.cards[randomIndex] = temporaryValue;
    }
  }
}

class Card {
  constructor(suit, value) {
    this.suit = suit;
    this.value = value;
  }
}

class Player {
  constructor() {
    this.hand = [];
  }
}

class Game {
  constructor(player1, player2, deck) {
    this.players = [player1, player2];
    this.deck = deck;
    this.done = false;
    this.deck.shuffle();

  }

  deal() {
    this.deck.cards.forEach((card, index) => {
      this.players[index % 2].hand.push(card);
    });

    //console.log(this.players[0].hand, this.players[1].hand);
  }
  play() {
    let count = 0;
    while (!this.done) {
      console.log(`Turn #${count++}`);
      this.turn();
      this.checkWinner();
    }
  }

  turn() {
    const player1Card = this.players[0].hand.shift();
    const player2Card = this.players[1].hand.shift();

    console.log(`Player 1 plays a ${player1Card.value} of ${player1Card.suit}`);
    console.log(`Player 2 plays a ${player2Card.value} of ${player2Card.suit}`);

    if (player1Card.value > player2Card.value) {
      console.log(`Player 1 plays wins this hand`);
      if (!draw) {
        this.players[0].hand.push(player1Card);
        this.players[0].hand.push(player2Card);
      } else {
        this.players[0].hand.push(player1Card);
        this.players[0].hand.push(player2Card);
        this.players[0].hand.push(...cardOfPlayer1.splice(0,26));
        this.players[0].hand.push(...cardOfPlayer2.splice(0,26));
        draw = false;
      }
      console.log(`Player 1 has ${this.players[0].hand.length} cards`);

    } else if (player1Card.value < player2Card.value) {
      console.log(`Player 2 plays wins this hand`);
      if (!draw) {
        this.players[1].hand.push(player2Card);
        this.players[1].hand.push(player1Card);
      } else {
        this.players[1].hand.push(player2Card);
        this.players[1].hand.push(player1Card);
        this.players[1].hand.push(...cardOfPlayer1.splice(0,26));
        this.players[1].hand.push(...cardOfPlayer2.splice(0,26));
        draw = false;
      }
      console.log(`Player 2 has ${this.players[1].hand.length} cards`);

    } else if (player1Card.value === player2Card.value) {
      console.log('Draw');
      cardOfPlayer1.push(player1Card);
      cardOfPlayer2.push(player2Card);
      draw = true;
      //this.turn();

    }
  }

  checkWinner() {
    if (this.players[0].hand.length === 0 && this.players[1].hand.length === 0) {
      console.log("It's a draw!!!!!");
    } else if (this.players[0].hand.length === 0) {
      console.log('Player 2 Wins');
      this.done = true;
    } else if (this.players[1].hand.length === 0) {
      console.log('Player 1 Wins');
      this.done = true;
    }
  }
}

const game = new Game(new Player(), new Player(), new Deck())

game.deal();
game.play();

答案 1 :(得分:-1)

发生这种情况是因为shift()删除了数组的第一项。