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

PHP 實作撲克牌「扎金花」大小比較邏輯:從牌型判定到分值計算完整解析

     編輯:PHP 相關知識

PHP 實作扎金花(撲克牌)大小比較演算法

遊戲規則與牌型優先級

扎金花為三張牌比大小,牌型由強至弱:

  1. 豹子(筒子):三張點數相同(如 666、JJJ)
  2. 順金(同花順):同花色且點數連續
  3. 金花(同花):三張花色相同
  4. 順子:點數連續(特殊:JQK < A23 < QKA)
  5. 對子:兩張點數相同
  6. 單張(散牌):以上皆非,比較最大單張

核心思路:量化分值法

將每手牌轉換為數值分數,直接比較大小:

  • 每張牌點數轉為兩位數(A=14, K=13, Q=11, 10=10, 2=02, 7=07...)
  • 三張牌由大到小排序,組成 6 位數基礎分(如 A27 → 140702)
  • 針對特殊牌型加權:
    • 對子:對子點數前置 + 10 * 100000
    • 順子:+ 20 * 100000
    • 金花:+ 30 * 100000
    • 順金:+ 50 * 100000(金花+順子)
    • 豹子:+ 60 * 100000

完整 PHP 實作代碼

<?php
class PlayCards {
    public $suits = ['Spade', 'Heart', 'Diamond', 'Club'];
    public $figures = ['2','3','4','5','6','7','8','9','10','J','Q','K','A'];
    public $cards = [];

    public function __construct() {
        $cards = [];
        foreach ($this->suits as $suit) {
            foreach ($this->figures as $figure) {
                $cards[] = [$suit, $figure];
            }
        }
        $this->cards = $cards;
    }

    public function getCard() {
        shuffle($this->cards);
        return [array_pop($this->cards), array_pop($this->cards), array_pop($this->cards)];
    }

    public function compareCards($card1, $card2) {
        $score1 = $this->ownScore($card1);
        $score2 = $this->ownScore($card2);
        if ($score1 > $score2) return 1;
        elseif ($score1 < $score2) return -1;
        return 0;
    }

    private function ownScore($card) {
        $suit = $figure = [];
        foreach ($card as $v) {
            $suit[] = $v[0];
            $figure[] = array_search($v[1], $this->figures) + 2;
        }
        // 補齊前導零
        for ($i = 0; $i < 3; $i++) {
            $figure[$i] = str_pad($figure[$i], 2, '0', STR_PAD_LEFT);
        }
        rsort($figure);

        // 對子特殊處理:將對子點數移至前兩位
        if ($figure[1] == $figure[2]) {
            $temp = $figure[0];
            $figure[0] = $figure[2];
            $figure[2] = $temp;
        }

        $score = (int)($figure[0].$figure[1].$figure[2]);

        // 豹子
        if ($figure[0] == $figure[1] && $figure[0] == $figure[2]) {
            $score += 60 * 100000;
        }
        // 金花
        if ($suit[0] == $suit[1] && $suit[0] == $suit[2]) {
            $score += 30 * 100000;
        }
        // 順子(含 A23 特例)
        if (($figure[0] == $figure[1]+1 && $figure[1] == $figure[2]+1) || implode($figure) == '140302') {
            $score += 20 * 100000;
        }
        // 對子(非豹子)
        if ($figure[0] == $figure[1] && $figure[1] != $figure[2]) {
            $score += 10 * 100000;
        }
        return $score;
    }
}

// 測試
$playCard = new PlayCards();
$card1 = $playCard->getCard();
$card2 = $playCard->getCard();
$result = $playCard->compareCards($card1, $card2);

function printCard($card) {
    $str = '(';
    foreach ($card as $v) { $str .= $v[0].$v[1].','; }
    return trim($str, ',').')';
}

echo 'card1: '.printCard($card1).'<br/>';
echo 'card2: '.printCard($card2).'<br/>';
$str = 'card1 equit card2';
if ($result == 1) $str = 'card1 is larger than card2';
elseif ($result == -1) $str = 'card1 is smaller than card2';
echo $str;
?>

關鍵設計細節

  • 對子點數前置:確保對子比較時優先看對子點數,再看單張
  • A23 特殊順子判定:140302 對應 A(14) 2(02) 3(03) 排序後
  • 加權權重設計:層級分明,避免牌型衝突
  • 花色不參與基礎分:僅用於金花/順金判定

擴充建議

  • 加入莊家/閒家邏輯、下注系統
  • 實作多副牌、防作弊洗牌演算法
  • 前端串接 WebSocket 實現即時對戰
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved