目的:完成炸金花游戏,判断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写游戏,进而产生的想法.
大致对纸牌类游戏明白了,如何计算每张牌,和手上牌大小的算法.纸牌补位的应用,和如何判断出牌的大小
心中有愿望一定要去闯,努力实现最初的梦想,