第52節 - Java: Blackjack Shuffle Methods
這一節我會介紹Java的Blackjack Shuffle Methods(洗牌方法),我會介紹以下三種方法:
- Method 1 - Knuth Shuffle Method (a.k.a Fisher–Yates Shuffle Method)
- Method 2 - Fisher–Yates Modern Shuffle Method
- Method 3 - Java Build-in Collections Shuffle Method
為甚麼要學Java的Shuffle Methods?
因為我會在下幾節開始介紹Java的Blackjack紙牌遊戲(文字版),而這文字版就會用到shuffle方法。
注意: 當我們掌握了Java Blackjack(文字版)的程式設計技考後,我會在下幾節介紹如何把Java的Blackjack紙牌遊戲(文字版)改寫為最後的LibGDX的Blackjack紙牌遊戲(2D動畫版)。
Method 1 - Knuth Shuffle Method (a.k.a Fisher–Yates Shuffle Method)
最早提出這個Shuffle方法的是Ronald A. Fisher和Frank Yates,之後由Donald Knuth實作,所以叫做Knuth Shuffle Method,這個方法主要在原始數組中隨機取一個之前沒取過的數字到新的數組中:
- 初始化數組,按序(升序或者降序)排列;
- 從還沒處理的數組(假如還剩k個)中,隨機產生一個(0, k)之間的數字p(假設數組從0開始);
- 從剩下的k個數中把第p個數取出(還剩k-1個);
- 重複步驟2和3直到數字全部取完;
- 從步驟3取出的數字序列便是一個打亂了的數列。

- 建立一個cards[] Array (陣列),大小為0 - 51,則Array index(索引)由cards[0]至cards[51]共52個;
- 隨機產生一個(0, 51)之間的數字p(例如:7),暫時儲存在tempCards[0]上;
- 把第p個數(a[7]=8)刪除,(還剩52-1=51個);
- 重複步驟2和3直到數字全部取完;
- 最後把tempCards[]陣列複製回到收cards[]陣列上,便是一個打亂了的數列。
程式部分

- 建立一個shuffle1()方法;
- 在main()主程式內建立一個ArrayList類別的物件(cards);
注意: 我在第27節 - Java: Array, Arrays, List, ArrayList & LibGDX: Array介紹過List和ArrayList的用法和分別,因為ArrayList類別內有不同的方法(例如:get(), add(), remove()等等),方便我們使用。
- 把0 - 51數值存入cards陣列內,則Array index(索引)由cards[0]至cards[51]共52個;
- 把cards陣列存入新增的Shuffle1類別的start()方法內,最後複製回到收cards陣列上,便是一個打亂了的數列。
執行程式結果

- 把0 - 51數值存入cards陣列內,則Array index(索引)由cards[0]至cards[51]共52個;
- 把cards陣列存入新增的Shuffle類別的start()方法內,顯示tempCards陣列的執行結果;
- 最後複製回到收cards陣列上,執行結果和tempCards陣列一樣。
Method 2 - Fisher–Yates Modern Shuffle Method
Fisher–Yates Modern Shuffle Method(現代版),是專供電腦使用,是由Richard Durstenfeld於1964年提出和由Donald Knuth普及:
- 初始化數組,按序(升序或者降序)排列;
- 從還沒處理的數組(假如還剩k個)中,隨機產生一個(0, k)之間的數字p(假設數組從0開始);
- 把步驟2的數字p和第1個數字交換(或把步驟2的數字p和最後一個數字交換也可以);
- 重複步驟2,再把數字p和第2個數字交換(或把步驟2的數字p和尾二數字交換也可以);
- 重複步驟2和3直到數字全部交換完,便是一個打亂了的數列。

- 建立一個cards[] Array (陣列),大小為0 - 51,則Array index(索引)由cards[0]至cards[51]共52個;
- 隨機產生一個(0, 51)之間的數字p(例如:7),把a[7]和第1個數字a[0]交換;
- 隨機產生一個(0, 51)之間的數字p(例如:3),把a[3]和第2個數字a[1]交換;
- 重複步驟2和3直到數字全部交換完,便是一個打亂了的數列;
- 最後把a[]陣列複製回到收cards[]陣列上,便是一個打亂了的數列。
程式部分

- 建立一個shuffle2()方法;
- 在main()主程式內建立一個ArrayList類別的物件(cards);
注意: 我在第27節 - Java: Array, Arrays, List, ArrayList & LibGDX: Array介紹過List和ArrayList的用法和分別,因為ArrayList類別內有不同的方法(例如:get(), add(), remove()等等),方便我們使用。
- 把0 - 51數值存入cards陣列內,則Array index(索引)由cards[0]至cards[51]共52個;
- 把cards陣列存入新增的Shuffle2類別的start()方法內,最後複製回到收cards陣列上,便是一個打亂了的數列。
執行程式結果

- 把0 - 51數值存入cards陣列內,則Array index(索引)由cards[0]至cards[51]共52個;
- 把cards陣列存入新增的Shuffle類別的start()方法內,顯示a陣列的執行結果;
- 最後複製回到收cards陣列上,執行結果和a陣列一樣。
Method 3 - Java Build-in Collections Shuffle Method
方法3運用了解Java預設的Shuffle方法,只須一行程式碼,十分方便。
程式部分

- 加入import java.util.Collections;
- 執行Collections.shuffle()方法便可。
執行程式結果

- 把0 - 51數值存入cards陣列內,則Array index(索引)由cards[0]至cards[51]共52個;
- 把cards陣列存入shuffle()方法內,顯示cards陣列的執行結果;