关于扎金花php版

目的:完成炸金花游戏,判断3人中的牌谁最大

思路:

制作1副扑克牌,不包括大小王为每个人发牌,每个牌唯一计算每张牌的大小比较每张牌的大小

扑克牌 分析,4种花色,每种花色13张牌

 1         public $cards =array(); 2  3         /** 4          * 生成扑克牌 5          */ 6         public function __construct() 7         { 8             //花色  黑桃 红桃 梅花 方块 9             $hua = array('黑桃','红桃','梅花','方块');10             //牌面11             $shu = array('2','3','4','5','6','7','8','9','10','J','Q','K','A');12             foreach ($hua as $k) 13             {14                 foreach($shu as $j)15                 {16                     $cards[] =array($k,$j);17                 }18             }19             $this->cards = $cards;20         }

关于发牌 每个人发三张牌,发一张牌牌池少一张

 1         /** 2          * 发牌三张 3          * @return array 所发牌的数组 4          */ 5         public function getCards() 6         { 7             //shuffle 把数组中的元素按随机顺序重新排序 返回true false 8             shuffle($this->cards); 9             // array_shift 删除第一个元素   array_pop 删除最后一个元素10             $pai = array(array_shift($this->cards),array_shift($this->cards),array_shift($this->cards));11 12             return $pai;            13         }

计算规则:

为了方便计算,将每张牌的数值都改为两位, K=13, Q=12, J=11, A=14炸弹>同花顺>顺子>对子>其他牌有对子,需要先算对子同花的情况下 黑桃>红桃>梅花>方片

顺子中 AKQ最大 A32 最小

  1 /**  2          * 计算牌面上的分数,由于规则只能内部调用所以应为私有属性  3          * @param array  需要计算分数的牌  4          * @return   输出每副牌的得分  5          */  6         private function calculated($card)  7         {  8             //将花色和值分开计算  9             $hua = $shu = array();  10             foreach ($card as $v) 11             { 12                 $hua[] =$v[0]; 13                 //由于牌的值 A =14 k =13 Q=12 J=11 14                 //小于10补0 使每张牌都是有2位数和一个花色组成 15                 switch ($v[1])  16                 { 17                     case 'J': 18                         $shu[] = '11'; 19                         break; 20  21                     case 'Q': 22                         $shu[] = '12'; 23                         break; 24  25                     case 'K': 26                         $shu[] = '13'; 27                         break; 28  29                     case 'A': 30                         $shu[] = '14'; 31                         break; 32                      33                     default: 34                     //str_pad() 函数把字符串填充为新的长度 35                         $shu[] = str_pad($v[1],2,"0",STR_PAD_LEFT); 36                         break; 37                 } 38             } 39             //将索引数组排列 由大到小 40             rsort($shu); 41             //如果牌面上有对子 需要重新排列数值,需要将对子放在前面 42             //如果非对子数大于对子的值才需要重新排列 43             if($shu[2]==$shu[1]){ 44                 //将最大值取出 45                 $temp = $shu[0]; 46                 //把对子移到前两位 47                 $shu[0] = $shu[2]; 48                 //把取出的值放回数组 49                 $shu[2] = $temp; 50             } 51             //算分,每张牌2位 52             $score = $shu[0].$shu[1].$shu[2]; 53             //对子,且不是炸弹(同样三张) 54             if($shu[0] == $shu[1]&&$shu[1]!=$shu[2]){ 55                 //对子分数前面加10 56                 $score += 100000*10; 57             } 58  59             //顺子 AKQ最大 A23最小 AKQ的分数141312 已经为最大 A23 位140302 不为最小 60             //将A32也是顺子 分数重新计算 61             if(implode($shu)=='140302'){ 62                 $score = '030214'; 63                 $score += 100000*20; 64             } 65  66             //顺子条件 每张牌相差1 67             if($shu[1]==$shu[0]+1 && $shu[2]==$shu[1]+1) 68             { 69                 $score += 100000*20; 70             } 71  72             //同花  由于1副牌中 每个牌都不同 所以不存在同花对 73             //同花顺 分数为顺子+同花 50*100000 74             //同花顺存在分数相同的情况所以 75             if($hua[0]==$hua[1] && $hua[0]==$hua[2]){ 76                 $score += 100000*30; 77  78                 switch ($hua[0]) 79                 { 80                     case '黑桃': 81                         $score += 0.8; 82                         break; 83                     case '红桃': 84                         $score += 0.6; 85                         break; 86                     case '草花': 87                         $score += 0.4; 88                         break; 89                     case '方片': 90                         $scroe += 0.2; 91                         break; 92  93                     default: 94                         break; 95                 }  96                  97             } 98  99             //炸弹 由于对子的情况已经将炸弹删除 所以只需判断后两位是否相等100             if($shu[1]==$shu[2])101             {102                 $score += 100000*60;103             }104 105             return $score;106         }

比较每个人手中牌的大小

先比较2个人的再比较3个人的

情况要分清楚 ,3个人一共7中情况需要分清楚这里只贴两个人的比较方法了

 1         /** 2          * 比较发的牌哪副比较大 3          * @param  array $card1 牌1 4          * @param  array $card2 牌2 5          * @return int  根据比较的结果不同返回的值不同 6          */ 7         public function compare($card1,$card2) 8         { 9             //将牌转化为分数10             $score1 = $this->Calculated($card1);11             $score2 = $this->Calculated($card2);12             // $score3 = $this->Calculated($card3);13             // 比较结果返回值14             if($score1 > $score2 )15             {16                 return 2;17             }elseif($score1 < $score2)18             {19                 return 0;20             }else21             {22                 return 1;23             }24         }

所有代码

  1 <?php   2     //参考  3     // http://blog.csdn.net/q718330882/article/details/38778273  4       5     /**  6     * 炸金花游戏  7     */  8     class PlayCard   9     { 10         //牌池 11         public $cards =array(); 12  13         /** 14          * 生成扑克牌 15          */ 16         public function __construct() 17         { 18             //花色  黑桃 红桃 梅花 方块 19             $hua = array('黑桃','红桃','梅花','方块'); 20             //牌面 21             $shu = array('2','3','4','5','6','7','8','9','10','J','Q','K','A'); 22             foreach ($hua as $k)  23             { 24                 foreach($shu as $j) 25                 { 26                     $cards[] =array($k,$j); 27                 } 28             } 29             $this->cards = $cards; 30         } 31  32         /** 33          * 发牌三张 34          * @return array 所发牌的数组 35          */ 36         public function getCards() 37         { 38             //shuffle 把数组中的元素按随机顺序重新排序 返回true false 39             shuffle($this->cards); 40             // array_shift 删除第一个元素   array_pop 删除最后一个元素 41             $pai = array(array_shift($this->cards),array_shift($this->cards),array_shift($this->cards)); 42  43             return $pai;             44         } 45  46         /** 47          * 比较发的牌哪副比较大 48          * @param  array $card1 牌1 49          * @param  array $card2 牌2 50          * @return int  根据比较的结果不同返回的值不同 51          */ 52         public function compare($card1,$card2) 53         { 54             //将牌转化为分数 55             $score1 = $this->Calculated($card1); 56             $score2 = $this->Calculated($card2); 57             // $score3 = $this->Calculated($card3); 58             // 比较结果返回值 59             if($score1 > $score2 ) 60             { 61                 return 2; 62             }elseif($score1 < $score2) 63             { 64                 return 0; 65             }else 66             { 67                 return 1; 68             } 69         } 70         /** 71          * [compare3 description] 72          * @param  array $card1 牌1 73          * @param  array $card2 牌2 74          * @param  array $card2 牌3 75          * @return int    根据比较的结果不同返回的值不同 76          */ 77         public function compare3($card1,$card2,$card3) 78         { 79             $calc1 = $this->compare($card1,$card2); 80             //总共七种情况 A,B,C单独获胜 或者AB BC AC 获胜 或者 ABC 同大小 81             // 82              83             if($calc1==2) 84             { 85                 $calc2=$this->compare($card1,$card3); 86                 if($calc2 == 2) 87                 { 88                     //即card1单独胜利 89                     return 1; 90                 }elseif($calc2 ==0) 91                 { 92                     //即card3 单独胜利 93                     return 2; 94                 }else 95                 { 96                     //即card1和card3 一同胜利 97                     return 3; 98                 } 99             }elseif($calc1==1)100             {101                 $calc2=$this->compare($card1,$card3);102                 if($calc2 == 2)103                 {104                     //即card1和card2 一同胜利105                     return 4;106                 }elseif($calc2 ==0)107                 {108                     //即card3 单独胜利109                     return 2;110                 }else111                 {112                     //即card1和card2和card3 一同胜利113                     return 5;114                 }115             }else116             {117                 $calc2=$this->compare($card2,$card3);118                 if($calc2 == 2)119                 {120                     //即card2 单独胜利121                     return 6;122                 }elseif($calc2 ==0)123                 {124                     //即card3 单独胜利125                     return 2;126                 }else127                 {128                     //即card2和card3 一同胜利129                     return 7;130                 }131             }132 133         }134 135         /**136          * 计算牌面上的分数,由于规则只能内部调用所以应为私有属性137          * @param array  需要计算分数的牌138          * @return   输出每副牌的得分139          */140         private function calculated($card)141         {142             //将花色和值分开计算143             $hua = $shu = array(); 144             foreach ($card as $v)145             {146                 $hua[] =$v[0];147                 //由于牌的值 A =14 k =13 Q=12 J=11148                 //小于10补0 使每张牌都是有2位数和一个花色组成149                 switch ($v[1]) 150                 {151                     case 'J':152                         $shu[] = '11';153                         break;154 155                     case 'Q':156                         $shu[] = '12';157                         break;158 159                     case 'K':160                         $shu[] = '13';161                         break;162 163                     case 'A':164                         $shu[] = '14';165                         break;166                     167                     default:168                     //str_pad() 函数把字符串填充为新的长度169                         $shu[] = str_pad($v[1],2,"0",STR_PAD_LEFT);170                         break;171                 }172             }173             //将索引数组排列 由大到小174             rsort($shu);175             //如果牌面上有对子 需要重新排列数值,需要将对子放在前面176             //如果非对子数大于对子的值才需要重新排列177             if($shu[2]==$shu[1]){178                 //将最大值取出179                 $temp = $shu[0];180                 //把对子移到前两位181                 $shu[0] = $shu[2];182                 //把取出的值放回数组183                 $shu[2] = $temp;184             }185             //算分,每张牌2位186             $score = $shu[0].$shu[1].$shu[2];187             //对子,且不是炸弹(同样三张)188             if($shu[0] == $shu[1]&&$shu[1]!=$shu[2]){189                 //对子分数前面加10190                 $score += 100000*10;191             }192 193             //顺子 AKQ最大 A23最小 AKQ的分数141312 已经为最大 A23 位140302 不为最小194             //将A32也是顺子 分数重新计算195             if(implode($shu)=='140302'){196                 $score = '030214';197                 $score += 100000*20;198             }199 200             //顺子条件 每张牌相差1201             if($shu[1]==$shu[0]+1 && $shu[2]==$shu[1]+1)202             {203                 $score += 100000*20;204             }205 206             //同花  由于1副牌中 每个牌都不同 所以不存在同花对207             //同花顺 分数为顺子+同花 50*100000208             //同花顺存在分数相同的情况所以209             if($hua[0]==$hua[1] && $hua[0]==$hua[2]){210                 $score += 100000*30;211 212                 switch ($hua[0])213                 {214                     case '黑桃':215                         $score += 0.8;216                         break;217                     case '红桃':218                         $score += 0.6;219                         break;220                     case '梅花':221                         $score += 0.4;222                         break;223                     case '方片':224                         $scroe += 0.2;225                         break;226 227                     default:228                         break;229                 } 230                 231             }232 233             //炸弹 由于对子的情况已经将炸弹删除 所以只需判断后两位是否相等234             if($shu[1]==$shu[2])235             {236                 $score += 100000*60;237             }238 239             return $score;240         }241 242 243         //打印牌244         public function printcards($card)245         {246             $str = '';247             foreach($card as $v)248             {249                 $str .= $v[0].$v[1].',';250             }251             return $str;252         }253     }254 255     $Puke = new PlayCard();256     // var_dump($Puke->getCards());257     // $card1 = $Puke->getCards();258     // $card1 = [['黑桃','10'],['梅花','J'],['黑桃','Q']];259     // $card2 = [['梅花','10'],['红桃','J'],['梅花','Q']];260     // $card3 = [['红桃','10'],['黑桃','J'],['红桃','Q']];261     $card1 = $Puke->getCards();262     $card2 = $Puke->getCards();263     $card3 = $Puke->getCards();264 265     echo '赌圣1的牌:'.$Puke->printcards($card1).'<br/><br/>';266     echo '赌圣2的牌:'.$Puke->printcards($card2).'<br/><br/>';267     echo '赌圣3的牌:'.$Puke->printcards($card3).'<br/><br/>';268     echo '<hr/>';269 270     $res = $Puke->compare3($card1,$card2,$card3);271 272     switch ($res) {273         case 1:274             echo'本届赌圣为赌圣1';275             break;276         case 2:277             echo'本届赌圣为赌圣3';278             break;279         case 3:280             echo'本届赌圣为赌圣1和赌圣3';281             break;282         case 4:283             echo'本届赌圣为赌圣1和赌圣2';284             break;285         case 5:286             echo'本届赌圣为赌圣1,赌圣2,赌圣3';287             break;288         case 6:289             echo'本届赌圣为赌圣2';290             break;291         case 6:292             echo'本届赌圣为赌圣2和赌圣3';293             break;294         295         default:296             echo '错误';297             break;298     }299 300 301 302 303 304  ?>

View Code

截一张成功的图

对于这个程序,是偶尔在浏览网页时发现可以用php写游戏,进而产生的想法.

大致对纸牌类游戏明白了,如何计算每张牌,和手上牌大小的算法.纸牌补位的应用,和如何判断出牌的大小

心中有愿望一定要去闯,努力实现最初的梦想,

关于扎金花php版

相关文章:

你感兴趣的文章:

标签云: