当前位置: 首页 > news >正文

【PHP】模拟斗地主后端编写

PHP写的斗地主功能开发,可以完成基础的斗地主功能

  1. 初始化游戏
//初始化游戏public function gameInit($room,$GameList){$redis = new Redis();$init   = $this->LicenSing($room);if ($init && $room){$roomGame1 = json_decode($redis->get('room_'.$room.'_game1'),true);$roomGame2 = json_decode($redis->get('room_'.$room.'_game2'),true);$roomGame3 = json_decode($redis->get('room_'.$room.'_game3'),true);$roomBottom = json_decode($redis->get('room_'.$room.'_bottom'),true);$roomGameInit = $GameList[rand(0,2)];//初始化默认玩家$redis->hset('room_'.$room.'_game','roomGameInit',$roomGameInit['id']);//初始化当前牌库$redis->hset('room_'.$room.'_game','thisGame',json_encode([],true));return  [$roomGame1,$roomGame2,$roomGame3,$roomBottom,$roomGameInit];}else{echo "游戏初始化失败";}}//初始发牌public function LicenSing(int $room){$design =  ['♠', '♥', '♦', '♣'];$card = ['3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K','A', '2'];$CardLibrary = [];foreach ($design as $value){foreach ($card as $k=>$v){$CardLibrary[] = ['design' => $value,'card' => $v,'weight'=>array_search($v, $card),];}}$CardLibrary [] = ['design' => '','card' => 'joke 小王','weight'=>13,];$CardLibrary [] = ['design' => '','card' => 'joke 大王','weight'=>14,];//洗牌shuffle($CardLibrary);//留下3张牌$bottom []= $CardLibrary[51];$bottom []= $CardLibrary[52];$bottom []= $CardLibrary[53];unset($CardLibrary[51], $CardLibrary[52], $CardLibrary[53]);//模拟发牌for ($i=0;$i<3;$i++){for ($i1=0;$i1<17;$i1++){$game[($i+1)][] = $CardLibrary[$i + (3*$i1)];}}//玩家牌进行排序foreach ($game as $k=>$v){$game[$k]=$this->sortOut($game[$k]);}//redis -持久化 本局游戏$room_1_game1 = $game[1];$room_1_game2 = $game[2];$room_1_game3 = $game[3];$room_1_bottom = $bottom;$redis = new Redis();
//        redis -持久化 玩家牌$redis->set('room_'.$room.'_game1', json_encode($room_1_game1,true),86400);$redis->set('room_'.$room.'_game2', json_encode($room_1_game2,true),86400);$redis->set('room_'.$room.'_game3', json_encode($room_1_game3,true),86400);$redis->set('room_'.$room.'_bottom', json_encode($room_1_bottom,true),86400);return true;}//抢到地主public function cryHost($game,$di,$room,$thisGameId){$redis =RedisTool::table();if ($redis->hget('room_'.$room.'_game','landlord')){return false;}$game = array_merge($game, $di);$game = $this->sortOut($game);$redis->hset('room_'.$room.'_game','landlord',$thisGameId);$redis->set('room_'.$room.'_game'.$thisGameId, json_encode($game,true),86400);return $game;}/*** @param $cardArr 当前出牌的牌* @param $roomGame  当前玩家的牌信息* @return array|int[] type 牌型 1单张 2对子 3三张 4炸弹 5三带一 6顺子 7三带二 8连对 9飞机 10四带二单 11飞机带单 12飞机带对 13四带二对 999王炸  -1不符合规则* @return array|int[] value 牌型值* @return array|int[] length 牌型长度*/public function checkCardType($cardArr,$roomGame){if (count($cardArr) == 0 && count($roomGame) == 0) {return ['type'=>0,'value'=>[],'length'=>0];}$GameCard = array_column($roomGame, 'weight');$cardArr = array_column($cardArr, 'weight');$totalCard = count($cardArr);if ($totalCard >0){foreach ($cardArr as $k=>$v){if (!in_array($v,$GameCard)){return ['type'=>-1,'value'=>[],'length'=>0];}}}//单张if ($totalCard == 1){if (in_array($cardArr[0],$GameCard)){return ['type'=>1,'value'=>array_sum($cardArr),'length'=>1];}return ['type'=>-1,'value'=>[],'length'=>0];}//对子if ($totalCard == 2) {if ($cardArr[0] == $cardArr[1]) {return ['type'=>2,'value'=>array_sum($cardArr),'length'=>2];}//是否王炸if ($cardArr[0] == 13 && $cardArr[1] == 14) {return ['type'=>999,'value'=>9999,'length'=>2];}return ['type'=>-1,'value'=>[],'length'=>0];}//三张if ($totalCard == 3) {if($cardArr[0] == $cardArr[1]&& $cardArr[0] ==$cardArr[2]){return ['type'=>3,'value'=>array_sum($cardArr),'length'=>3];}return ['type'=>-1,'value'=>[],'length'=>0];}//4张if ($totalCard == 4) {$newCardArr = $this->groupSameValues($cardArr);//是炸弹if (isset($newCardArr[1]) === false){return ['type'=>4,'value'=>array_sum($newCardArr[0]),'length'=>4];}//三带一if (count($newCardArr[0]) == 3){return ['type'=>5,'value'=>array_sum($newCardArr[0]),'length'=>4];}return ['type'=>-1,'value'=>[],'length'=>0];}//5张if ($totalCard == 5) {//判断是否顺子if ($this->isConsecutive($cardArr)) {//含有2 或者大小王if (in_array(12,$cardArr) || in_array(13,$cardArr) || in_array(14,$cardArr)){return ['type'=>-1,'value'=>[],'length'=>0];}return ['type'=>6,'value'=>array_sum($cardArr),'length'=>5];}$newCardArr = $this->groupSameValues($cardArr);//三带2if (count($newCardArr[0]) == 3){return ['type'=>7,'value'=>array_sum($newCardArr[0]),'length'=>5];}return ['type'=>-1,'value'=>[],'length'=>0];}//6张if ($totalCard == 6 ) {//判断是否对顺子if ($this->hasUniformRepetition($cardArr)){if ($this->isConsecutive($cardArr)) {//含有2if (in_array(12,$cardArr)){return ['type'=>-1,'value'=>[],'length'=>0];}return ['type'=>8,'value'=>array_sum($cardArr),'length'=>6];}}//是否顺子if ($this->isConsecutive($cardArr)) {//含有2 或者大小王if (in_array(12,$cardArr) || in_array(13,$cardArr) || in_array(14,$cardArr)){return ['type'=>-1,'value'=>[],'length'=>0];}return ['type'=>9,'value'=>array_sum($cardArr),'length'=>6];}//四带二$newCardArr = $this->groupSameValues($cardArr);if (count($newCardArr[0]) == 4){return ['type'=>10,'value'=>array_sum($newCardArr[0]),'length'=>6];}return ['type'=>-1,'value'=>[],'length'=>0];}//判断是否连续顺子if ($this->hasUniformRepetition($cardArr)){if ($this->isConsecutive($cardArr)) {//含有2if (in_array(12,$cardArr)){return ['type'=>-1,'value'=>[],'length'=>0];}return ['type'=>8,'value'=>array_sum($cardArr),'length'=>$totalCard];}return ['type'=>-1,'value'=>[],'length'=>0];}//是否单顺子if ($this->isConsecutive($cardArr)) {//含有2 或者大小王if (in_array(12,$cardArr) || in_array(13,$cardArr) || in_array(14,$cardArr)){return ['type'=>-1,'value'=>[],'length'=>0];}return ['type'=>9,'value'=>array_sum($cardArr),'length'=>$totalCard];}//是否飞机带单if ($totalCard >= 8 && $totalCard%4 == 0) {$newCardArr = $this->groupSameValues($cardArr);$tripleGroups = array_filter($newCardArr, function($group) {return count($group) === 3;});$tripleGroups2 = array_filter($newCardArr, function($group) {return count($group) != 3;});$valueNum= 0;foreach ($tripleGroups as $value) {$valueNum+=array_sum($value);}$tripleCount = count($tripleGroups);$tripleCount2 = count($tripleGroups2);if ($tripleCount == $tripleCount2) {return ['type'=>11,'value'=>$valueNum,'length'=>$totalCard];}}//是否飞机带对子if ($totalCard >= 10 && $totalCard%5 == 0) {$newCardArr = $this->groupSameValues($cardArr);$tripleGroups = array_filter($newCardArr, function($group) {return count($group) === 3;});$tripleGroups2 = array_filter($newCardArr, function($group) {return count($group) == 2;});$valueNum= 0;foreach ($tripleGroups as $value) {$valueNum+=array_sum($value);}$tripleCount = count($tripleGroups);$tripleCount2 = count($tripleGroups2);if ($tripleCount == $tripleCount2) {return ['type'=>12,'value'=>$valueNum,'length'=>$totalCard];}//是否含有2王if(in_array(13,$cardArr) && in_array(14,$cardArr)){if ($tripleCount == ($tripleCount2+1)) {return ['type'=>12,'value'=>$valueNum,'length'=>$totalCard];}}}//是否4带2对if ($totalCard >= 12 && $totalCard%6 == 0) {$newCardArr = $this->groupSameValues($cardArr);$tripleGroups = array_filter($newCardArr, function($group) {return count($group) === 4;});$valueNum= 0;foreach ($tripleGroups as $value) {$valueNum+=array_sum($value);}$tripleGroups2 = array_filter($newCardArr, function($group) {return count($group) == 2;});$tripleCount = count($tripleGroups);$tripleCount2 = count($tripleGroups2);if ($tripleCount == $tripleCount2) {if ($tripleCount == ($tripleCount2+1)) {return ['type'=>13,'value'=>$valueNum,'length'=>$totalCard];}}//是否含有2王if(in_array(13,$cardArr) && in_array(14,$cardArr)){if ($tripleCount == ($tripleCount2+1)) {if ($tripleCount == ($tripleCount2+1)) {return ['type'=>13,'value'=>$valueNum,'length'=>$totalCard];}}}}return ['type'=>-1,'value'=>[],'length'=>0];}//根据牌型分组public function groupSameValues(array $array){// 统计每个值的出现次数$counts = array_count_values($array);// 按出现次数降序排序arsort($counts);// 构建分组结果$result = [];foreach ($counts as $value => $count) {$result[] = array_fill(0, $count, $value);}return $result;}//验证是否连续public function isConsecutive(array $array): bool {if (empty($array)) return false;sort($array);// 去除重复值并排序$unique = array_unique($array);sort($unique);// 检查是否连续return $unique === range($unique[0], $unique[count($unique) - 1]);}//验证是否相同public function hasUniformRepetition(array $array): bool {if (empty($array)) return false;$counts = array_count_values($array);$firstCount = reset($counts);foreach ($counts as $count) {if ($count !== $firstCount) {return false;}}return true;}//整理玩家牌型public function sortOut($game){usort($game, function($a, $b) {return $b['weight'] <=> $a['weight'];});return $game;}
/*** 出牌* @param $goOutCard 出牌数组* @param $thisGame 当前玩家的牌信息* @param $thisGameCard  上一家出牌信息* @param $room  房间号* @param $gameId   当前玩家id* @param $roomGameId 上一次出牌人id* @param $roomLandId 地主id* @return array|void*/public function gameCard($goOutCard,$thisGame,$thisGameCard,$room,$gameId,$roomGameId,$roomLandId){$gameStatus = 0; //游戏状态 0 未结束 1 结束$isLandlord = 0; //是否地主 0 否 1 是$thisCard = ['type'=>0, 'value'=>[], 'length'=>0];//自己出牌if ($gameId != $roomGameId){//上一家出牌内容$thisCard = $this->checkCardType($thisGameCard,$thisGameCard);}//当前玩家出牌内容$checkCard = $this->checkCardType($goOutCard,$thisGame);if($checkCard && $this->compareCard($thisCard,$checkCard)){//删除玩家牌$GameList = $this->deleteCard($goOutCard,$thisGame,$room,$gameId);//判断是否有人出完牌if(count($GameList) == 0){$gameStatus = 1;//地主胜利if($gameId == $roomLandId){$isLandlord = 1;}}return ['gameStatus'=>$gameStatus,'gameList'=>$GameList,'isLandlord'=>$isLandlord];} else{echo "出牌错误";}}//删除玩家牌public function deleteCard($goOutCard,$thisGame,$room,$gameId){foreach ($thisGame as $key =>$value) {foreach ($goOutCard as $k => $v) {if ($value['card'] == $v['card'] && $value['design'] == $v['design']) {unset($thisGame[$key]);break;}}}$redis = new Redis();$redis->set('room_'.$room.'_game'.$gameId, json_encode($thisGame,true),86400);//记录当前出牌$redis->hset('room_'.$room.'_game','thisGame',json_encode($goOutCard,true));//当前出牌人$redis->hset('room_'.$room.'_game','roomGameInit',$gameId);return $thisGame;}//比较牌大小public function compareCard($thisGameCard,$gameCard){//没人出牌if ($thisGameCard['type'] == 0) {return true;}//王炸最大if ($gameCard['type'] == 999) {return true;}//炸弹压制非王炸和其他牌型if ($gameCard['type'] == 4) {if ($thisGameCard['type'] == 999) {return false;}if ($thisGameCard['type'] == 4) {return $gameCard['value'] > $thisGameCard['value'];}return true;}// 同类型牌比较if ($thisGameCard['type'] === $gameCard['type'] &&$thisGameCard['length'] === $gameCard['length']) {return $gameCard['value'] > $thisGameCard['value'];}return false;}

模拟玩法

    $redis = new Redis();$room = 1; //房间号$GameInit =[ //模拟玩家信息0=>['name'=>'玩家1','id'=>1],1=>['name'=>'玩家2','id'=>2],2=>['name'=>'玩家3','id'=>3],];$thisUid = 2; //当前玩家id$roomGame1 = json_decode($redis->get('room_'.$room.'_game1'),true);$roomGame2 = json_decode($redis->get('room_'.$room.'_game2'),true);$roomGame3 = json_decode($redis->get('room_'.$room.'_game3'),true);$roomBottom = json_decode($redis->get('room_'.$room.'_bottom'),true);//模拟初始化游戏$gameInit = $this->gameInit($room,$GameInit);//获取房间默认信息$roomGame = $redis->hGetAll('room_'.$room.'_game');//模拟抢到地主$dizhu = $this->cryHost($roomGame2, $roomBottom, $room, 2, $GameInit);if ($dizhu === false) {echo '抢地主失败,已经抢过地主了';}//模拟出牌$gameRoom = [$roomGame2[15], $roomGame2[13], $roomGame2[11], $roomGame2[9], $roomGame2[8]];//模拟出牌$cardArr = $this->gameCard($gameRoom,$roomGame2,json_decode($roomGame['thisGame'],true),$room,$thisUid,$roomGame['roomGameInit'],$roomGame['landlord']);
http://www.dtcms.com/a/339459.html

相关文章:

  • Matplotlib数据可视化实战:Matplotlib图表美化与进阶教程
  • 软件系统运维常见问题
  • idea中如何设置文件的编码格式
  • Python Day31 JavaScript 基础核心知识点详解 及 例题分析
  • 【完整源码+数据集+部署教程】太阳能板表面损伤检测图像分割系统源码和数据集:改进yolo11-DynamicHGNetV2
  • 服务器Linux防火墙怎样实现访问控制
  • Nginx前后端分离反代(VUE+FastAPI)
  • (一)八股(数据库/MQ/缓存)
  • 深入理解抽象类
  • C#三大核心特性
  • 小程序插件使用
  • Win/Linux笔记本合盖不睡眠设置指南
  • UART串口通信编程自学笔记30000字,嵌入式编程,STM32,C语言
  • 【软件安装】VScode介绍安装步骤及中文界面设置方法
  • 移动端即时通讯源码/IM聊天源码RainbowChat,纯原生体验丝滑、全源码易二开
  • NestJS 依赖注入方式全解
  • jmetergrafanainfluxdb搭建压测监控平台
  • JavaScript 性能优化实战:从分析到落地的全指南
  • Spring 的 setter 注入可以解决某些类型的循环依赖问题
  • 白光干涉 3D 表面轮廓仪的原理解析
  • 高频PCB厂家及工艺能力分析
  • proDAD VitaScene:专业视频转场特效滤镜软件
  • 算法第五十一天:图论part02(第十一章)
  • 【算法专题训练】14、链表
  • 2025年09月计算机二级Python选择题每日一练——第一期
  • 【CPP】一个CPP的Library(libXXXcore)和测试程序XXX_main的Demo
  • 【服务器】Apache Superset功能、部署与体验
  • Leetcode 深度优先搜索 (7)
  • 支持冲刺规划的敏捷开发任务分配工具推荐(附对比)
  • Flask 路由详解:构建灵活的 URL 映射系统