您的位置:首页 > 其它

斗地主

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;
}
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: