有趣的洗牌演算法
最近因為一些專案,所以需要實做一些撲克牌的洗牌機制。雖然這個動作看起來簡單,但其實對於開發者來說相當有趣,因為真的除了做這種牌類遊戲之外,平常很少用到這樣演算法,也由於有太多種做法,不免著迷於其中。 洗牌目的就是讓結果隨機、不能預期,只不過雖然很多遊戲同樣都是圍繞在亂數產生上面,但撲克牌遊戲(或麻將遊戲)最大的不同,就是同一排組每次發出來的牌,一但發過了就不會再出現一次。這一點,和每次都可以出一到六點數的骰子遊戲,就完全不一樣,不是隨機出一個亂數就可以搞定。 準備工作:先準備個牌組 開始前,先準備四種花色、A 到 K 的牌組,使我們可以以 0 至 51 的號碼去取得任意一張牌。 const suits = [ 'S', 'H', 'D', 'C' ]; const points = [ 'A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K' ]; const cards = []; for (let i = 0; i < 4; i++) { for (let j = 0; j < 13; j++) { cards.push(points[j] + suits[i]); } } console.log(cards[10]); // 10S(黑桃10) 方法一:硬幹 最直覺的方法,不外乎就是不斷產生 52 張牌的亂數(0 ~ 51),然後檢查這張牌發過沒,如果牌發過了就重新產生一個新的亂數,持續這個步驟。 let shuffledCards = []; while(shuffledCards.length != 52) { // 取得 0 ~ 51 的亂數 let idx = Math.floor(Math.random() * 51); let card = cards[idx]; // 檢查這張牌是否已經出現過 if (shuffledCards.indexOf(card) !== -1) continue; // 沒出現過則放入陣列 sh...