用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個玩家所分配到的手牌。