数组偶尔返回重复值

时间:2017-02-17 23:40:54

标签: javascript arrays

我正在尝试制作类似于游戏战争的纸牌游戏。游戏中有两个玩家,每个玩家都有自己的牌组 我有一个传递一个空数组的函数,这是每个玩家所拥有的牌组 此数组由另一个阵列中的一半项目填充,即整个卡组 大多数情况下,这是正常的,但有时,数组将有26个值,有时,某些值将被复制。
我的问题是,如何阻止重复传递到玩家的牌组?

Player = function(wonRound, currentCards, newCards) {
  this.wonRound = wonRound;
  this.currentCards = currentCards;
  this.newCards = newCards;
}

Deck = {
  suits: ["Clubs", "Diamonds", "Hearts", "Spades"],
  cards: ["Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"],
  deck: [],
  shuffledDeck: [],
  BuildDeck: function() {
    //Builds the deck
    for (var suit = 0; suit < this.suits.length; suit++) {
      for (var card = 0; card < this.cards.length; card++) {
        this.deck.push([this.cards[card], this.suits[suit]]);
      }
    }
    return this.deck;
  },
  ShuffleDeck: function() {
    //Shuffles the deck
    for (var card = 0; card < this.deck.length; card++) {
      this.shuffledDeck.push(this.deck[Math.floor(Math.random() * this.deck.length)]);
    }
    return this.shuffledDeck;
  },
  DistributeCards: function(playerDeck) {
    //Distributes half the deck to each player
    for (var i = 0; i < this.shuffledDeck.length / 2; i++) {
      playerDeck.push(this.shuffledDeck[i]);
    }
    return playerDeck;
  }
}
Player1 = new Player(false, [], []);
Player2 = new Player(false, [], []);
Deck.BuildDeck();
Deck.ShuffleDeck();
Deck.DistributeCards(Player1.currentCards);
for (var i = 0; i < Player1.currentCards.length; i++) {
  console.log(Player1.currentCards[i][0], Player1.currentCards[i][1], Player1.currentCards.indexOf(Player1.currentCards[i]));
}

5 个答案:

答案 0 :(得分:3)

您正在获取重复项,因为您从同一个数组中选择而不排除已选择的值。一种方法是删除(使用splice)选择的项目,这样他们就不会再次被选中。像这样:

ShuffleDeck: function() {                                         // while there still items in the deck
    while(this.deck.length) {
        var index = Math.floor(Math.random() * this.deck.length); // get a random index
        this.shuffledDeck.push(this.deck.splice(index, 1)[0]);    // remove the item at index (splice will return an array so we use [0] to get the item)
    }
    return this.shuffledDeck;
},

注意:之后牌组会变空,但由于你没有再使用它,这不会成为问题。

修改

DistributeCards更改为:

DistributeCards: function(player1, player2) {
    for (var i = 0; i < this.shuffledDeck.length / 2; i++) {
        player1.push(this.shuffledDeck[i]); // push the first half to player1's deck (0, 1, 2, ...)
        player2.push(this.shuffledDeck[this.shuffledDeck.length - i - 1]); // push the other half to player2's deck (len - 1, len - 2, len - 3, ...)
    }
    // no need for return if you won't use the return value (my advice is to remove return from all the function that you don't use their return value)
}

然后像这样使用它:

Deck.DistributeCards(Player1.currentCards, Player2.currentCards);

答案 1 :(得分:0)

问题主要在于你改组的方式!在声明中:

Math.floor(Math.random() * this.deck.length)

<div id="ytplayer"></div> <script> // Load the IFrame Player API code asynchronously. var tag = document.createElement('script'); .src = "https://www.youtube.com/player_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // Replace the 'ytplayer' element with an <iframe> and // YouTube player after the API code downloads. var player; function onYouTubePlayerAPIReady() { player = new YT.Player('ytplayer', { height: '360', width: '640', videoId: 'M7lc1UVf-VE' }); } </script> 逻辑可能会给出相同的数字两次,这将复制一张卡(并且可能不止一次),这不符合您的预期。
所以你真正需要的是创建一个逻辑,确保不重复任何数字,并且有很多方法可以做到这一点,请查看this SO帖子以获取多个示例。

答案 2 :(得分:0)

deck.sort(function(a, b){return 0.5 - Math.random()});

只是在甲板上做这个,你甚至不需要另一个套牌来洗牌。

https://www.w3schools.com/js/js_array_sort.asp有更多数组方法。

答案 3 :(得分:0)

您的问题在于ShuffleDeck功能。每次从现有套牌中挑选一张随机牌时,你都不会从游泳池中取出该牌以便再次挑选。您需要跟踪已经拾取的数字,或者在将数据拖入卡组后从阵列中删除该元素。也许最简单的混洗类型是Fisher-Yates shuffle

此外,您的发行版总是占用牌组的前半部分而不进行修改,因此在不从牌组中移除元素的情况下运行该功能只会给每个玩家提供同一手牌。

Player = function(wonRound, currentCards, newCards) {
  this.wonRound = wonRound;
  this.currentCards = currentCards;
  this.newCards = newCards;
  this.getCards = function ( cards ) {
    this.currentCards = cards;
  };
}

Deck = {
  suits: ["Clubs", "Diamonds", "Hearts", "Spades"],
  cards: ["Ace", "King", "Queen", "Jack", "10", "9", "8", "7", "6", "5", "4", "3", "2"],
  deck: [],
  shuffledDeck: [],
  BuildDeck: function() {
    //Builds the deck
    for (var suit = 0; suit < this.suits.length; suit++) {
      for (var card = 0; card < this.cards.length; card++) {
        this.deck.push([this.cards[card], this.suits[suit]]);
      }
    }
    return this.deck;
  },
  ShuffleDeck: function() {
    //Shuffles the deck
    var tempDeck = this.deck.slice(0); // Clone the deck, so the original deck still exists
    while ( tempDeck.length ) {
      var newItem = tempDeck.splice( Math.floor( Math.random() * tempDeck.length ), 1); // Pull one item from the array
      this.shuffledDeck.push( newItem[0] ); // Add it to the shuffled array
    }
    return this.shuffledDeck;
  },
  DistributeCards: function( len ) {
    //Distributes portion of the deck to each player
    // Note, if the length is greater than the length of the deck, it will return all remaining cards in the deck, even if they're less than what is requested. 
    return this.shuffledDeck.splice(0, len);
  }
}
Player1 = new Player(false, [], []);
Player2 = new Player(false, [], []);
Deck.BuildDeck();
Deck.ShuffleDeck();
Player1.getCards(Deck.DistributeCards(26)); // Get 26 cards from the shuffled deck and set them as the player's hand
for (var i = 0; i < Player1.currentCards.length; i++) {
  console.log(Player1.currentCards[i][0], Player1.currentCards[i][1], Player1.currentCards.indexOf(Player1.currentCards[i]));
}

注意添加Player.getCards方法,只是为了让事情更加清晰(它使玩家的“手”等于绘制和传入的牌),以及对Shuffle和分发方法。

我试图说明为什么我改变了我改变的内容,试图说明你的问题。随意询问您是否需要更多说明。

Array.splice documentation

答案 4 :(得分:0)

我已经改写了洗牌的逻辑,如下所示:

ShuffleDeck: function() {
    var i = this.deck.length;
    var j = 0;

    while (i--) {
      j = Math.floor(Math.random() * (i + 1));
      this.shuffledDeck.push(this.deck[j]);
      this.deck.splice(j, 1);
    }

    return this.shuffledDeck;   }

工作fidlle:https://jsfiddle.net/db6xmnrn/

<强>更新 从剩余的牌组向牌队2发牌的小提琴 https://jsfiddle.net/db6xmnrn/1/