关于扎金花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             }else
21             {
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                 }else
111                 {
112                     //即card1和card2和card3 一同胜利
113                     return 5;
114                 }
115             }else
116             {
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                 }else
127                 {
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=11
148                 //小于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                 //对子分数前面加10
190                 $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             //顺子条件 每张牌相差1
201             if($shu[1]==$shu[0]+1 && $shu[2]==$shu[1]+1)
202             {
203                 $score += 100000*20;
204             }
205 
206             //同花  由于1副牌中 每个牌都不同 所以不存在同花对
207             //同花顺 分数为顺子+同花 50*100000
208             //同花顺存在分数相同的情况所以
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写游戏,进而产生的想法.

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

 

转载于:https://www.cnblogs.com/yilianjimao/p/7220037.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值