首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 數組實戰:模擬麻將洗牌發牌全過程

     編輯:PHP 相關知識

前言:從生活場景理解數據結構

PHP 數組以其動態、有序、鍵值共存的特性,成為處理批量數據的利器。不同於 C/Java 需預定長度,PHP 數組可隨意擴展。本文通過模擬「麻將洗牌發牌」這一經典場景,展示數組初始化、隨機打亂、多維切片等核心操作。

麻將規則建模

  • 3 種花色(萬、條、筒),各 1-9 號,每張 4 張 → 3×9×4 = 108 張
  • 4 人遊戲,莊家 14 張,閒家各 13 張,剩 55 張墩牌
  • 發牌規則:三輪「每人 4 張」→ 一輪「每人 1 張」→ 莊家再摸 1 張

核心代碼實現

1. 初始化有序牌庫

<?php
$majiang = []; // PHP 5.4+ 短語法
$majiang[] = '0'; // 佔位,索引從 1 開始

for ($suit = 1; $suit <= 3; $suit++) {       // 花色
    for ($rank = 1; $rank <= 9; $rank++) {   // 點數
        for ($copy = 1; $copy <= 4; $copy++) { // 4 張相同牌
            $majiang[] = "{$suit}_{$rank}.gif"; // 對應圖片文件名
        }
    }
}
// 此時 $majiang[1..108] 為有序牌庫
?>

2. 洗牌演算法:費雪-耶茨亂序

function shuffle_mahjong(&$deck, $times = 1000) {
    $n = count($deck) - 1; // 排除索引 0
    for ($i = 0; $i < $times; $i++) {
        $r1 = mt_rand(1, $n);
        $r2 = mt_rand(1, $n);
        // 交換
        [$deck[$r1], $deck[$r2]] = [$deck[$r2], $deck[$r1]];
    }
}

shuffle_mahjong($majiang, 2000); // 充分打亂

優化提示:PHP 內建 shuffle() 已實現 Fisher-Yates,生產代碼請直接使用 shuffle($majiang),效能更優且無偏差。

3. 發牌邏輯:指針推進法

$players = [1 => [], 2 => [], 3 => [], 4 => []];
$seek = 1; // 發牌指針

// 三輪:每人 4 張
for ($round = 1; $round <= 3; $round++) {
    for ($seat = 1; $seat <= 4; $seat++) {
        for ($c = 1; $c <= 4; $c++) {
            $players[$seat][] = $majiang[$seek++];
        }
    }
}

// 一輪:每人 1 張
for ($seat = 1; $seat <= 4; $seat++) {
    $players[$seat][] = $majiang[$seek++];
}

// 莊家(座位 4)再摸 1 張
$players[4][] = $majiang[$seek];

// 驗證:4×13 + 14 = 66 張,seek 應為 67
echo "發牌指針: $seek, 剩餘牌: " . (108 - $seek + 1);

4. 圖形化展示手牌

function render_hand($tiles) {
    foreach ($tiles as $tile) {
        echo '<img src="img/' . htmlspecialchars($tile) . '" alt="">';
    }
    echo '<br>';
}

foreach ($players as $seat => $hand) {
    echo "玩家 $seat (" . count($hand) . "張): ";
    render_hand($hand);
}

進階擴展:規則引擎化

將規則參數化,支援多地玩法:

class MahjongGame {
    public $suits = 3;
    public $ranks = 9;
    public $copies = 4;
    public $players = 4;
    public $dealer_extra = 1;
    public $rounds = 3;
    public $tiles_per_round = 4;

    public function generate_deck() { /* ... */ }
    public function deal() { /* ... */ }
}

總結與最佳實踐

  • 數組作序列:連續整數鍵 + count()/foreach 遍歷,效能最優
  • 引用傳遞:洗牌、發牌函數使用 &$arr 避免大數組複製
  • 隨機數品質:mt_rand() 優於 rand();加密級需求用 random_int()
  • 內建函數優先:shuffle()、array_slice()、array_chunk() 替代手寫循環

這個例子展示了 PHP 數組處理複雜業務邏輯的表達力。將現實規則映射為數據操作,是程式設計的核心樂趣所在。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved