1. 程式人生 > >用PHP實現一個關於德州撲克演算法的程式(一):發牌

用PHP實現一個關於德州撲克演算法的程式(一):發牌

最近在自學PHP,感覺PHP很靈活。通過學習PHP,把以前學習C#、java時沒有弄清楚的概念都理順了,對OOP的認識又上升了一個臺階。為了檢驗最近的學習成果,決定寫一個德撲的演算法程式。

這個程式很簡單,只實現如下功能:
1、按照玩家的數量分配手牌;
2、把手牌和公牌進行組合後計算出勝負結果,以及獲勝玩家和所有玩家的牌型;不考慮玩牌的過程,即沒有下注這個階段。

====以下為正文====
根據需求進行設計,至少需要三個類:
1、撲克牌類Cards
2、玩家類Player
3、牌桌類(包含核心演算法邏輯)Table

====Cards類====
在德撲中不需要用到大王和小王,所以使用的牌數為52張。在本程式中紅桃用H代替、梅花用C代替、黑桃用S代替、方塊用D代替;點數則分別為2、3、4、5、6、7、8、9、T(10)、J、Q、K、A
以下程式碼建立一副撲克牌

        $cards=array();
        $suit=array("H","S","D","C");
        $p=array("T","J","Q","K","A");

        for($i=0;$i<count($suit);$i++){
            for($j=2;$j<=9;$j++){
                $cards[]=$suit[$i].$j;
            }
            for($k=0;$k<count($p);$k++){
                $cards
[]=$suit[$i].$p[$k]; } } return $cards;

這樣生成的撲克牌是按順序的,所以必須洗牌,用系統函式shuffle可以模擬實現。Cards類的目前程式碼如下:

class Cards{
    public $Cards=array();

    function __construct()
    {
        $this->Cards=$this->createCards();
        shuffle($this->Cards);
    }

    private
function createCards() { $cards=array(); $suit=array("H","S","D","C"); $p=array("T","J","Q","K","A"); for($i=0;$i<count($suit);$i++){ for($j=2;$j<=9;$j++){ $cards[]=$suit[$i].$j; } for($k=0;$k<count($p);$k++){ $cards[]=$suit[$i].$p[$k]; } } return $cards; } }

====Player類====
按照德撲的規則,每個玩家手中會有2張手牌。這2張牌是隨機分發的。所以這裡會用到系統函式array_rand。為了便於計算勝負,Player類有一個成員屬性為score用來計算玩家的得分以及一個記錄玩家手牌的屬性CardInHand。

初步設計的得分規則如下:
皇家同花順 900   
同花順   800
四條    700
滿堂紅   600 
同花   500 
順子   400  
三條 300   
兩對    200
一對    100
高牌 按實際最大一張牌計算

Cards類的目前程式碼如下:

class Player{

    public $score=0;
    public $CardInHand=array();

    function __construct($cards)
    {
        $this->getCardInHand($cards);
    }

    private function getCardInHand($cards){
        $randkey=array_rand($cards,2);
        $this->CardInHand[]=$cards[$randkey[0]];
        $this->CardInHand[]=$cards[$randkey[1]];
        return $this->CardInHand;
    }

}

====Table類====
當前階段Table類實現玩家的初始化功能。在Table類的建構函式中需要設定玩家的數量。

//在引數中傳遞玩家的數量num,和cards陣列
function __construct($num,$cards)
    {
        //迴圈初始化玩家
        for($i=0;$i<$num;$i++){
            $this->players[$i]=new Player($cards);
            //把已經分配出去的手牌從牌池中取掉,使用系統函式array_diff計算差集
            $cards=array_diff($cards,$this->players[$i]->CardInHand);            
            $k=$i+1;
            echo "玩家".$k."的手牌為<br>";
            $this->showCard($this->players[$i]->CardInHand);
            echo "<br>==========<br>";
        }

    }

為了能夠直觀看到撲克牌而不是用字母和數字組成的符號,在程式資料夾中包含了一套所有撲克牌的圖片,圖片的名稱按照Card類生成撲克牌的規則去設定。所以Table類中有一個方法來顯示撲克牌:

private function showCard($cards){
        foreach ($cards as $ca) {
            $path.= "<img src='./pukeImage/". $ca . ".jpg'>";
        }
        echo $path;
    }

Table類目前的程式碼如下:

include "Cards.class.php";
include "Player.class.php";

class  Table{

    public $players=array();

    function __construct($num,$cards)
    {
        for($i=0;$i<$num;$i++){
            $this->players[$i]=new Player($cards);
            $cards=array_diff($cards,$this->players[$i]->CardInHand);
            //echo count($cards).'<br>';
            $k=$i+1;
            echo "玩家".$k."的手牌為<br>";
            $this->showCard($this->players[$i]->CardInHand);
            echo "<br>==========<br>";
        }

    }

    private function showCard($cards){
        foreach ($cards as $ca) {
            $path.= "<img src='./pukeImage/". $ca . ".jpg'>";
        }
        echo $path;
    }


}

==============
在主程式中按照如下程式碼進行呼叫:

include "Table.class.php";
$c=new Cards();
$table=new Table(5,$c->Cards);

即可顯示5個玩家所分配到的手牌。