2017-02-17 7 views
3

私はゲームに似たカードゲームを作成しようとしています戦争。ゲームには2人のプレイヤーがいて、それぞれに自分のデッキがあります。
私は、各プレイヤーが持つデッキである空の配列を渡す関数を持っています。
この配列には、デッキ全体である別の配列の項目の半分が入力されます。
ほとんどの場合、これは正しく動作しますが、アレイには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])); 
 
}

+0

それを第2のプレーヤーにも配布するための私の答えを確認してください:) –

答えて

3

すでに選択されている値を除外せずに同じアレイから選択するため、重複が発生しています。それを行う1つの方法は、(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); 
+0

すべてを説明していただきありがとうございます。今問題は、2人の選手がいるときに何をすべきかということです。 – Robert

+0

@Robert **編集**セクションをチェック! –

+0

ああ、ありがとう、ありがとう。 – Robert

0

問題は主にあなたがをシャッフルある方法であります!声明の中で:

this.shuffledDeck.push(this.deck[Math.floor(Math.random() * this.deck.length)]); 

Math.floor(Math.random() * this.deck.length)ロジックはあなたのケースで期待されているものではありませんこれは(そして、それが複数回可能です)カードを複製するであろう、二度同じ番号を与えるかもしれません。
本当に必要なのは、何も繰り返されないことを保証するロジックを作成することです。これを行う方法はたくさんあります。this SO postで複数の例を確認してください。

+0

各プレイヤーのデッキに渡されたらカードをシャッフルしますか? – Robert

+1

@Robertおそらくそうではありません。配布はランダムではないからです。 –

+0

@Robert私はBrandonと全く同意します。 –

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

ただ、デッキ上でこれを行うuはいけませんシャッフルされたカードのための別のデッキも必要です。

https://www.w3schools.com/js/js_array_sort.aspさらに多くの配列メソッドがあります。

+0

なぜ0.5を使用しますか? – bormat

+1

@bormat 'Math.random'は' [0、1 ['、' 0.5 - ... 'は' Math.random'に応じて負数と正数の両方を返します。 'sort'は、コールバックが正または負の数を返した場合に応じてアイテムをスワップします。戻り値が常に正の場合、 'sort'は配列をそのまま、または尊重します。 [** MDN **](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)の 'sort'に関するドキュメントを参照してください! –

+0

それは正しくありがたいです – bormat

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メソッドとDistributeメソッドの変更。

私はあなたの問題を試して説明するために、なぜ私が変更したものを変更したのかを明確にしようとしました。より明確な説明が必要な場合はお気軽にお問い合わせください。

Array.splice documentation

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/1/からplayer2にカードを提供するためのhttps://jsfiddle.net/db6xmnrn/

UPDATE フィドルを

関連する問題