撲克牌發牌演算法是棋牌類遊戲開發中的核心基礎演算法,掌握這項技術對於遊戲開發者來說至關重要。本文將詳細介紹一種高效且實用的發牌演算法實作方式,包含完整的 Java 程式碼範例。
首先我們需要為每張撲克牌建立唯一的編號系統。這裡採用雙副牌(含大小王)共 108 張牌的編號規則:
因為使用雙副牌,所以每個編號會出現兩次,總共 108 張牌。
演算法採用「洗牌後依序發牌」的策略,具體步驟如下:
import java.util.*;
public class PokerDealer {
public static void main(String[] args) {
// 儲存 108 張牌的陣列
int[] deck = new int[108];
// 四位玩家,每人 25 張牌
int[][] players = new int[4][25];
int remainingCards = 108;
Random random = new Random();
// 初始化牌堆(雙副牌)
for (int i = 0; i < deck.length; i++) {
deck[i] = (i + 1) % 54;
if (deck[i] == 0) deck[i] = 54; // 處理大小王編號
}
// 發牌邏輯:每輪給 4 位玩家各發 1 張,共 25 輪
for (int round = 0; round < 25; round++) {
for (int player = 0; player < 4; player++) {
int randomIndex = random.nextInt(remainingCards);
players[player][round] = deck[randomIndex];
// 將最後一張牌移到被抽取的位置,實現 O(1) 移除
deck[randomIndex] = deck[remainingCards - 1];
remainingCards--;
}
}
// 輸出玩家手牌
for (int i = 0; i < 4; i++) {
System.out.print("玩家 " + (i+1) + ": ");
for (int card : players[i]) {
System.out.print(card + " ");
}
System.out.println();
}
// 輸出底牌(剩餘 8 張)
System.out.print("底牌: ");
for (int i = 0; i < 8; i++) {
System.out.print(deck[i] + " ");
}
System.out.println();
}
}
此演算法採用 Fisher-Yates 洗牌變體,具有以下優點:
實際專案中可考慮以下增強:
這個演算法不僅適用於撲克遊戲,同樣可擴展至麻將、大老二等各類棋牌遊戲開發中,是遊戲開發者必備的基礎工具。