斗地主
2016-01-06 17:18
281 查看
<?php /* * 黑桃 @ * 红桃 # * 片花 % * 梅花 * * */ //fwrite(STDOUT,'name ?'.PHP_EOL); //fscanf(STDIN,"%s",$name); /* * 可配置参数: * 一副牌54张 * 一局n副牌 * 一局m个人 * 一局分成x组 * * 0.是否开始 * 1.初始化数据54张牌,抽出3张底牌,3个人,分成2组,A组1人,B组2人 * 2.51张牌,发牌给3个人,先发给A组 * 3.随机一人开始出牌 * 4.接下来一人出牌 * 5.一人手中无牌,该组胜利 * 6.计算输赢,一张牌1分,把得分平均发给赢组的人员 * */ class game { private static $playCards = [ 2,2,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5, 6,6,6,6, 7,7,7,7, 8,8,8,8, 9,9,9,9, 10,10,10,10, 11,11,11,11, //J 12,12,12,12, //Q 13,13,13,13, //K 14,14,14,14, //A 20, //小王 21 //大王 ]; public $playCardsNum; public $peopleNum; public $termNum; public $people = array(); private $landlord=null; //当前地主id做个标记 private $prevPerson=null; //上个出牌人的id private $currPerson=null; //当前出牌人id private $prevCard; //上个人出的牌 private $prevCardType; //上个人出牌型 private $cardTpyeObj; public static $input=null; public static $start; public function __construct($playCardsNum=1, $peopleNum=3, $termNum=2) { $this->playCardsNum = $playCardsNum; $this->peopleNum = $peopleNum; $this->termNum = $termNum; $this->cardTpyeObj = CardTpye::obj(); self::start() && $this->run(); } public function run() { $this->peopleInit(); while(self::$start) { //发牌 $this->cardInit(); //争地主 $this->landlord(); $this->showPerson(); //出牌 $this->playHand(); //清空每局的垃圾信息 $this->clean(); //重新开始 self::start(); } self::notice("bye ~"); } //询问是否开始 public static function start() { self::notice("start or close ?"); self::notice("start:1 close:0"); self::getInput(); if(self::$input == 0) { self::$start = false; self::delInput(); return false; }else{ self::$start = true; self::delInput(); return true; } } //初始化人员 public function peopleInit() { //初始化人员 for($peoson=0; $peoson<$this->peopleNum; $peoson++) { self::notice($peoson." name ?"); self::getInput(); $peosonInfo = array( "name" => self::$input, "win" => 0, "status" => 0, //0农民 1地主 "cards" => array() ); if(empty(self::$input)) { $peoson--; }else { array_push($this->people, $peosonInfo); } self::delInput(); } } //开始发牌 public function cardInit() { shuffle(self::$playCards); foreach(self::$playCards as $key=>$card) { $tmpNum = $key % $this->peopleNum; array_push($this->people[$tmpNum]['cards'], $card); } array_walk($this->people,function(&$peoson){ sort($peoson['cards']); }); } //显示每个人的牌 public function showPerson($id=null) { $status = array("peasant","landlord"); if($id === null){ array_walk($this->people,function(&$peoson) use($status){ $notice = $status[$peoson['status']]." ".$peoson['name'].": ".implode(',',$peoson['cards']); self::notice($notice); }); }else{ $notice = $status[$this->people[$id]['status']]." ".$this->people[$id]['name'].": ".implode(',',$this->people[$id]['cards']); self::notice($notice); } } //争地主 public function landlord() { $id = 0; $score = 0; foreach($this->people as $key=>$peoson) { self::notice($key." ".$peoson['name']." ".": please input score [1,2,3]"); self::getInput(); if(self::$input>$score) { $score=self::$input; $id=$key; } self::notice("s:".$score." id:".$id); } $this->people[$id]['status'] = 1; $this->landlord = $id; self::delInput(); } //出牌 public function playHand() { $play = true; while($play) { //计算该谁出牌了 if(is_null($this->currPerson)){ $this->currPerson = $this->landlord; }else{ $needPlay = $this->currPerson + 1; $this->currPerson = !isset($this->people[$needPlay]) ? 0:$needPlay; } //没通过就重出 do { self::notice(PHP_EOL . PHP_EOL . "please play"); $this->showPerson($this->currPerson); self::getInput(); //验证出牌规则 $pass = $this->ruleCheck(); !$pass && self::notice("error."); }while(!$pass); //把出的牌删除 if(!empty(self::$input)) { self::notice("play: " . self::$input); $playCards = explode(',', self::$input); foreach ($playCards as $card) { $key = array_search($card, $this->people[$this->currPerson]['cards']); unset($this->people[$this->currPerson]['cards'][$key]); } //记录下出的牌和个人id $this->prevPerson = $this->currPerson; $this->prevCard = self::$input; self::log("p:".$this->prevPerson." c:".$this->prevCard); } //赢了 if(empty($this->people[$this->currPerson]['cards'])) { $this->people[$this->currPerson]['win'] ++ ; self::notice($this->people[$this->currPerson]['name']." win"); $play = false; } self::delInput(); } self::notice("game over"); } //验证规则 public function ruleCheck() { /* * 牌型验证,和上局人出的牌型一致 * 0.单张 一张牌一样 * 1.两对 两张牌一样 * 2.三对 三张牌一样 * 3.三队带一 * 4.三队带二对 * 5.四张炸 * 6.炸带单张 * 6.炸带两队 * 7.单顺最小5张 连续的牌,差为1 * 8.两对顺 最小三对 * 9.三队顺 最小2对 * 10.三队顺带2个单牌 * 11.三队顺带2个两对 * 12.四炸顺 * 13.四炸顺带两个单牌 * 14.四炸顺带两个对 * */ //如果出空 if(is_null(self::$input)) { //第一次不能出空 if(empty($this->prevCard)){ return false; } //转一圈到自己了,不能出空 if($this->currPerson == $this->prevPerson){ return false; } return true; } $cards = explode(',',self::$input); $type = $this->cardTpyeObj->getType($cards); //第一次出,或其他人都不要,转一圈到自己了 if(is_null($this->prevPerson) || $this->currPerson==$this->prevPerson) { if($type==0){ return false; }else{ $this->prevCardType = $type; return true; } }else{ //根据类型验证大小 if($type==0 || $type!=$this->prevCardType){ return false; }else{ $prevCards = explode(",",$this->prevCard); $big = $this->cardTpyeObj->size($type, $prevCards, $cards); return $big; } } } //清空每局的垃圾信息 public function clean() { array_walk($this->people,function(&$person){ $person['staus'] = 0; $person['cards'] = array(); }); $this->landlord = null; $this->prevPerson = null; $this->prevCard = ""; } public static function notice($message) { fwrite(STDOUT,$message.PHP_EOL); } public static function getInput() { fscanf(STDIN,'%s',self::$input); } public static function delInput() { self::$input = null; } public static function log($message) { $str = time()." ".$message."\r\n"; file_put_contents("log.txt", $str, FILE_APPEND); } } $game = new game(); class CardTpye { private static $obj; private function __construct(){} private function __clone(){} public static function obj() { if(!isset(self::$obj)) { self::$obj = new self; } return self::$obj; } //类型验证 public function getType(array $cards) { $type = 0; switch(count($cards)){ case 1: $type=1;break; case 2: $this->dui_2($cards) && $type=2; break; case 3: $this->dui_3($cards) && $type=3; break; case 4: $this->dui_3_1($cards) && $type=4; $this->bomb_4($cards) && $type=5; break; case 5: $this->dui_3_2($cards) && $type=6; $this->bomb_4_1($cards) && $type=7; break; default: $type=0; } return $type; } //大小验证 public function size($type, array $prev, array $current) { $big = false; switch($type){ case 1: $big = $this->one_size($prev, $current); break; case 2: $big = $this->dui_2_size($prev, $current); break; case 3: $big = $this->dui_3_size($prev, $current); break; case 4: $big = $this->dui_3_1_size($prev, $current); break; case 5: $big = $this->bomb_4_size($prev, $current); break; case 6: $big = $this->dui_3_2_size($prev, $current); break; case 7: $big = $this->bomb_4_1_size($prev, $current); break; default: break; } return $big; } /********************验证大小***************************/ private function one_size(array $prev, array $current) { return self::bigOrSmall($prev[0],$current[0]); } private function dui_2_size(array $prev, array $current) { return self::bigOrSmall($prev[0],$current[0]); } private function dui_3_size(array $prev, array $current) { return self::bigOrSmall($prev[0],$current[0]); } private function dui_3_1_size(array $prev, array $current) { //获取三张 $getDui_3 = function (array $cards){ if($cards[0] == $cards[1]){ return array_slice($cards,0,3); }else{ return array_slice($cards,1,3); } }; $prevDui_3 = $getDui_3($prev); $currDui_3 = $getDui_3($current); return self::bigOrSmall($prevDui_3[0], $currDui_3[0]); } private function bomb_4_size(array $prev, array $current) { return self::bigOrSmall($prev[0], $current[0]); } private function dui_3_2_size(array $prev, array $current) { $getDui_3 = function (array $cards) { sort($cards); if($cards[0]==$cards[1] && $cards[1]==$cards[2]) { return array_slice($cards, 0, 3); }else{ return array_slice($cards, 2, 3); } }; $prevDui_3 = $getDui_3($prev); $currDui_3 = $getDui_3($current); return self::bigOrSmall($prevDui_3[0], $currDui_3[0]); } private function bomb_4_1_size(array $prev, array $current) { $getDui_4 = function (array $cards) { sort($cards); if($cards[0] == $cards[1]) { return array_slice($cards, 0, 4); }else{ return array_slice($cards, 1, 4); } }; $prevDui_4 = $getDui_4($prev); $currDui_4 = $getDui_4($current); return self::bigOrSmall($prevDui_4[0], $currDui_4[0]); } private static function bigOrSmall($pre, $cur) { if($cur <= $pre) { return false; }else{ return true; } } /*****************验证牌型*************************/ /* * type=2 * 两张牌---对子验证 * 规则:两张牌型一样 * */ private function dui_2(array $input) { if($input[0] == $input[1]) { return true; }else{ return false; } } /* * type=3 * 三张牌---三对验证 * 规则:三张牌一样 * */ private function dui_3(array $input) { if($input[0]==$input[1] && $input[1]==$input[2]) { return true; }else{ return false; } } /* * type=4 * 四张牌---三带一 * 规则:前三张一样,第四张随便 * */ private function dui_3_1(array $input) { //前三张一样 if($input[0]==$input[1]) { if($input[1]==$input[2]) { return true; }else{ return false; } }else{ if($input[1]==$input[2] && $input[2]==$input[3]) { return true; }else{ return false; } } } /* * type=5 * 四张牌---炸弹 * 规则:四张一样 * */ private function bomb_4(array $input) { if($input[0]==$input[1] && $input[1]==$input[2] && $input[2]==$input[3]) { return true; }else{ return false; } } /* * type=6 * 五张牌---三带二 * 规则:前三张一样,后两张一样 * */ private function dui_3_2(array $input) { sort($input); if($input[0]==$input[1] && $input[1]==$input[2]) { $dui_3 = array_slice($input, 0, 3); $dui_2 = array_slice($input, 3, 2); }else{ $dui_2 = array_slice($input, 0, 2); $dui_3 = array_slice($input, 2, 3); } if($this->dui_3($dui_3) && $this->dui_2($dui_2)) { return true; }else{ return false; } } /* * type=7 * 五张牌---四带一 * 规则:四张一样的,一张单个 * */ private function bomb_4_1(array $input) { if($input[0] == $input[1]) { if($input[1]==$input[2] && $input[2]==$input[3]){ return true; }else{ return false; } }else{ if($input[1]==$input[2] && $input[2]==$input[3] && $input[3]==$input[4]) { return true; }else{ return false; } } } }
相关文章推荐
- eval解析JSON中的注意点
- zabbix------关于微信报警的尝试
- maven 插件_1 Maven Clean Plugin
- 采用UDP传输音视频时的效果
- Android 签名机制
- 用Mikrotik Router搭建GRE over IPSec 备用链路 推荐
- Map side join
- 结构体初始化
- Backup and restore the disk table on linux
- 更新二进制位——LintCode
- STM32F103 扩展以太网口
- finecms
- Convert.ToInt32( null or "")
- Java中hashCode的作用
- PDU的编码--EMS编码
- php 加密压缩
- 如何解析oracle执行计划
- android studio 常用快捷键
- 给jdk写注释系列之jdk1.6容器(10)-Stack&Vector源码解析
- 使用Android-PullToRefresh库中的PullToRefreshListView添加headerView