用PHP實現一個關於德州撲克演算法的程式(四):程式碼
阿新 • • 發佈:2019-01-28
程式主入口
<?php
include "Table.class.php";
//顯示函式
function pre($str){
echo '<pre>';
print_r($str);
echo '</pre>';
}
//建立撲克牌
$c=new Cards();
//初始化玩家數量
$table=new Table(2,$c->Cards);
撲克牌類 Cards.class.php
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.class.php
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.class.php
include "Cards.class.php";
include "Player.class.php";
class Table{
public $players=array();
public $tablecards=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>";
}
array_shift($cards);
for($i=0;$i<3;$i++) {
$this->tablecards[] = $cards[$i];
}
$cards=array_diff($cards,$this->tablecards);
for($i=0;$i<2;$i++){
array_shift($cards);
$this->tablecards[] = $cards[0];
}
echo "<br>====公牌為====<br>";
$this->showCard($this->tablecards);
for($i=0;$i<count($this->players);$i++){
$k=$i+1;
echo "<br>----玩家{$k}的結果為----<br>";
$this->result($this->players[$i]);
echo "<br>-----------------------<br>";
}
}
private function showCard($cards){
foreach ($cards as $ca) {
$path.= "<img src='./pukeImage/". $ca . ".jpg'>";
}
echo $path;
}
private function pre($str,$comment){
echo "<pre>=={$comment}===<br>";
print_r($str);
echo '</pre>====<br>';
}
private function result(Player $p){
$result=array_merge($p->CardInHand,$this->tablecards);
//pre($result);
foreach($result as $c){
$suit.=$c[0];
$point.=$c[1];
}
//字串轉換為陣列
$su=str_split($suit);
$po=str_split($point);
//統計花色和點數
$su_count=array_count_values($su);
$po_count=array_count_values($po);
switch(max($su_count)){
case "5":
echo "這是".array_keys($su_count,"5")[0]."同花"."<br>";
break;
default:
switch(max($po_count)){
case "4":
echo "這是".array_keys($po_count,"4")[0]."四條"."<br>";
$this->showCard($this->pukesort($result));
break;
case "3":
//echo "這是".array_keys($po_count,"3")[0]."三條"."<br>";
$this->isStraight($result);
break;
case "2":
//echo "這是".array_keys($po_count,"2")[0]."對子"."<br>";
$this->isStraight($result);
break;
default:
$this->isStraight($result);
}
break;
}
}
private function pukesort($cards){
foreach($cards as $ca){
$arr[]=$ca[1];
}
$arr=array_count_values($arr);
foreach(array_keys($arr) as $v) {
switch ($v) {
case "A":
$poi[] = 14;
break;
case "K":
$poi[] = 13;
break;
case "Q":
$poi[] = 12;
break;
case "J":
$poi[] = 11;
break;
case "T":
$poi[] = 10;
break;
default:
$poi[] = $v;
break;
}
}
$puke=array(
"num"=>array_values($arr),
"poi"=>$poi
);
array_multisort($puke["num"], SORT_NUMERIC, SORT_DESC,
$puke["poi"],SORT_NUMERIC, SORT_DESC
);
$arr= array_combine($puke["poi"],$puke["num"]);
foreach($arr as $key=>$value){
switch($key){
case "14":
$arr1["A"]=$arr["14"];
break;
case "13":
$arr1["K"]=$arr["13"];
break;
case "12":
$arr1["Q"]=$arr["12"];
break;
case "11":
$arr1["J"]=$arr["11"];
break;
case "10":
$arr1["T"]=$arr["10"];
break;
default:
$arr1[$key]=$value;
break;
}
}
$keys=array_keys($arr1);
foreach($keys as $v){
$pstr= '/.'.$v.'/';
foreach($cards as $c) {
if(preg_match($pstr,$c)){
$maxcard[]=$c;
}
}
}
$maxcard=array_slice($maxcard,0,5);
return $maxcard;
}
private function pointToNum($arr){
$num=0;
//統計在這副牌型中點數為數字的情況,從而判斷A是做14合適還是作1合適
foreach($arr as $p){
if(!is_numeric($p))
$num++;
}
foreach($arr as $p){
switch($p){
case "A":
if($num>=5){
$poi[]=14;
}else{
$poi[]=1;//A還可以作為1使用
}
break;
case "K":
$poi[]=13;
break;
case "Q":
$poi[]=12;
break;
case "J":
$poi[]=11;
break;
case "T":
$poi[]=10;
break;
default:
$poi[]=$p;
break;
}
}
return $poi;
}
private function numToPoint($arr){
foreach($arr as $p){
switch($p){
case "14":
case "1":
$poi[]="A";
break;
case "13":
$poi[]="K";
break;
case "12":
$poi[]="Q";
break;
case "11":
$poi[]="J";
break;
case "10":
$poi[]="T";
break;
default :
$poi[]=$p;
}
}
return $poi;
}
private function isStraight($cards){
foreach($cards as $c){
$point.=$c[1];
}
$po=array_unique(str_split($point));
//如果元素不為5個,則不滿足順子成牌的基本條件
if(count($po)<5){
$this->showCard($this->pukesort($cards));
}else{
$po=$this->pointToNum($po);
arsort($po);
$a1=array_values($po);
$j=0;
for($i=1;$i<count($a1);$i++){
if($a1[$i]==$a1[$i-1]-1){
$j++;
$a2[]=array_search($a1[$i-1],$po);
$a2[]=array_search($a1[$i],$po);
}else{
$j=0;
}
}
if($j>=4){
$a2=array_unique($a2);//去掉重複值
$a2=array_values($a2);//重建索引
$a2=array_slice($a2,0,5);//取出5個元素
for($i=0;$i<count($a2);$i++){
$result[]=$po[$a2[$i]];
}
$arr=$this->numToPoint($result);
foreach($arr as $v){
$pstr= '/.'.$v.'/';
foreach($cards as $c) {
if(preg_match($pstr,$c)){
$maxcard[]=$c;
break;
}
}
}
$this->showCard($this->pukesort($maxcard));
}else{
$this->showCard($this->pukesort($cards));
}
}
}
}
執行顯示效果:
ps:以上算是德州撲克的演算法程式的90%內容,還有10%的內容是同花順的判斷,以及玩家分數的計算和勝負的判斷,但是這些內容已經很簡單,已經沒有演算法上的挑戰性,因此《用PHP實現一個關於德州撲克演算法的程式》就告一段落了。