在前段时间开发了一款斗牛士游戏,前面已经说到过是采用PHP开发的,这此我将详细描述此算法的实现过程。
由于此游戏逻辑较简单,仅判断牛型大小、并对牛型进行比较,所以我决定采用type、num、count的结构来表示一张牌对象。如下:
<?php
/**
* Created by PhpStorm.
* User: LiBing
* Date: 2017/9/28
* Time: 10:34
* 表示扑克牌的类
*/
class NiuNiuCard{
//type : 1 : 黑桃 2:红桃 3:梅花 4:方块
public $type;
//num: 1-13对应牌型
public $num;
//count:对应的点数
public $count;
/**
* NiuNiuCard constructor.
* @param $type 牌型
* @param $num 牌号
* @param $count 牌点数 >10都作为10
*/
function __construct($type, $num, $count)
{
$this->type = $type;
$this->num = $num;
$this->count = $count;
}
}
?>
所以我们斗牛中获得的对象便是五个这样的对象构成的数组,以下是算法代码:
<?php
/**
* Created by PhpStorm.
* User: LiBing
* Date: 2017/10/13
* Time: 下午3:29
* 用于判断牛牛的算法逻辑
*/
require_once ('NiuniuType.php');
require_once ('NiuNiuCard.php');
class NiuniuLogic{
/**
* 辅助函数,用于排序
* @param $cards 卡牌的引用
*/
public function sortPlayerCards(&$cards){
for($i = 0; $i < 5; $i++){
for($j = 0; $j < 4 - $i; $j++){
if($cards[$j]->num > $cards[$j + 1]->num ||
($cards[$j]->num == $cards[$j+1]->num && $cards[$j]->type < $cards[$j+1]->type)){
$t = $cards[$j];
$cards[$j] = $cards[$j+1];
$cards[$j+1] = $t;
}
}
}
}
/**
* @param $playerCards 玩家的手牌,这里假设的是以{玩家ID,Cards(array)}的方式传过来的数据
* @param $typeSelected 允许的可选牌型的数组,用于是否开启该牌型,包含数据为
* canShunDou: 能否顺斗; canKanDou: 能否坎斗
* canTongHuaShun: 能否同花顺
* canZhaDanNiu: 能否炸弹牛
* canWuXiaoNiu: 能否五小牛
* canWuHuaNiu: 能否五花牛
* canSiHuaNiu: 能否四花牛
* canHuLuNiu: 能否葫芦牛
* canTongHuaNiu: 能否同花牛
* canShunZiNiu: 能否顺子牛
* @return $resultArray 某一个玩家的结果数组,存放结果
* 'playerID' : 对应的玩家
* 'level': 牌的级别,按照同花顺 > 五小牛 > 五花牛 > 四花牛 > 炸弹牛 > 葫芦牛 > 同花
* > 顺子 > 牛牛 > 牛9-牛5 > 牛4-牛1 > 无牛进行排列
* 注意:坎斗、顺斗以及普通牛是同一级别,都看点数
* 'levelResult': 牌的级别对应的最大牌,用于同级别的判断
*
*/
public function getNiuniuResult($playerCards, $typeSelected){
$resultArray = array();//array('playerID'=>'', 'level'=>0, 'levelResult'=>'');
for($i = 0; $i < count($playerCards); $i++){
//初始化一个基本结果,然后和所有数据判断
$resultArray[$i]['playerID'] = $playerCards[$i]['playerID'];
$resultArray[$i]['level'] = -1;
$resultArray[$i]['levelResult'] = '';
$resultArray[$i]["douPai"]=array();
//保存一个临时牌组,并按从小到大排序
$cards = $playerCards[$i]['cards'];
$this->sortPlayerCards($cards);
//获取普通牛数据
$r = $this->getNiuniuCount($cards);
$this->processResult($resultArray[$i], $r);
if($typeSelected['canShunDou']){
//获取顺斗的数据
$r = $this->getShunDouPoint($cards);
$this->processResult($resultArray[$i], $r);
}
if($typeSelected['canCanDou']){
//获取豹子牛数据
$r = $this->getBaoZhiNiuPoint($cards);
if($r["level"]==BAOZHINIU){
$this->processResult($resultArray[$i], $r);
}
}
//可能出错
if($typeSelected['canWuHuaNiu']){
//获取五花牛
$r = $this->isWuHuaNiu($cards);
if($r["level"]==WUHUANIU){
$this->processResult($resultArray[$i], $r);
}
}
if($typeSelected['canShunZiNiu']){
//获取顺子牛数据
$r = $this->isShunZiNiu($cards);
if($r["level"]==SHUNZINIU){
$this->processResult($resultArray[$i], $r);
}
}
if($typeSelected['canTongHuaNiu']){
//获取同花牛
$r = $this->isTonghuaNiu($cards);
if($r["level"]==TONGHUANIU){
$this->processResult($resultArray[$i], $r);
}
}
if($typeSelected['canHuLuNiu']){
//获取葫芦牛
$r = $this->huluNiu($cards);
if($r["level"]==HULUNIU){