php麻将,php实现麻将牌型的胡牌检测算法

2023-05-16

麻将基本牌型的胡牌检测算法,不包含小七对,针对小七对可以增加牌型检测,与此组成牌型树。

此类可以获得胡牌的牌型组合,取得后针对组合可以进行牌型名称检测。

先上一个,后面会持续更新各地特殊的胡牌算法,如癞子

/**

* 麻将基本胡牌 (不包含小七对)

*

* 此类检测是否胡牌,返回胡牌的组合, 你可以再将获得的胡牌组合,进行相应牌型检测获得牌型

* 不能用于小七对的胡牌检测

*

* @package

* @author sunshine

*

* $Id: HuAlgorithm.php 2017.12.05 $

*/

class HuAlgorithm

{

private $stack = []; # 牌组栈

private $cards = []; # 剩余手牌

private $pairs = 0; # 将对个数

private $raw = false; # 是否直接返牌组栈

private $number = [];# 牌堆

public function __construct($number = [], $raw = false)

{

$this->number = $number;

$this->raw = $raw;

}

public function clear($raw = false)

{

$this->stack = [];

$this->cards = [];

$this->pairs = 0;

$this->raw = $raw;

}

public function start($cards)

{

$this->cards = $cards;

sort($this->cards);

if ($this->try_hu())

{

if ($this->raw)

{

# 直接返回牌组栈

return $this->stack;

}

else

{

# 返回胡牌的排列

$win_cards = [];

foreach ($this->stack as $e)

{

$win_cards[] = $e;

}

return $win_cards;

}

}

else

{

return [];

}

}

# 将牌组压栈

private function push($group)

{

array_push($this->stack, $group);

}

# 牌组出栈

private function roll_back()

{

$group = array_pop($this->stack);

array_push($this->cards, $group);

sort($this->cards);

}

# 刻子,则将此组牌压栈

private function try_triplet($card)

{

if ($this->array_count($this->cards, $card) >= 3)

{

$this->cards = $this->array_remove($this->cards, $card, 3);

$this->push([$card, $card, $card]);

return true;

}

else

return false;

}

# 顺子,则将此组牌压栈

private function try_along($card)

{

if (!in_array($card, $this->number))

return false;

if (in_array($card, $this->cards) && in_array($card + 1, $this->cards) && in_array($card + 2, $this->cards))

{

$this->cards = $this->array_remove($this->cards, $card);

$this->cards = $this->array_remove($this->cards, $card + 1);

$this->cards = $this->array_remove($this->cards, $card + 2);

$this->push([$card, $card + 1, $card + 2]);

return true;

}

else

return false;

}

# 对子,对子只能有一个

private function try_sub($card)

{

if ($this->pairs == 1)

return false;

if ($this->array_count($this->cards, $card) >= 2)

{

$this->cards = $this->array_remove($this->cards, $card, 2);

$this->push([$card, $card]);

$this->pairs = 1;

return true;

}

else

return false;

}

# 回溯尝试组成顺子刻子对子

private function try_hu()

{

if (!$this->cards)

{

if ($this->pairs == 1)

return true;

else

return false;

}

$active_card = reset($this->cards);

if ($this->try_triplet($active_card))

{

if (!$this->try_hu())

$this->roll_back();

else

return true;

}

if ($this->try_sub($active_card))

{

if (!$this->try_hu())

{

$this->roll_back();

$this->pairs = 0;

}

else

return true;

}

if ($this->try_along($active_card))

{

if (!$this->try_hu())

$this->roll_back();

else

return true;

}

return false;

}

private function array_remove($cards, $card, $d = 1)

{

foreach ($cards as $k => $v)

{

if ($v == $card && $d)

{

$d--;

unset($cards[$k]);

}

}

return $cards;

}

private function array_count($cards, $card)

{

$rs = array_count_values($cards);

foreach ($rs as $k => $v)

{

if ($card == $k) return $v;

}

return 0;

}

}

##############################################################

# 牌

# 万 筒 条 东南西北 中发白 花

$wan = [17, 18, 19, 20 ,21, 22, 23, 24, 25];

$dot = [33, 34, 35, 36, 37, 38, 39, 40, 41];

$suo = [49, 50, 51, 52, 53, 54, 55, 56, 57];

$win = [61, 62, 63, 64];

$dragon = [71, 72, 73];

$flower = [];

$number = array_merge($wan, $dot, $suo);

##############################################################

# test 平胡

$cards = [17, 18, 19, 19, 19, 21, 22, 23, 35, 37, 36, 38, 36, 37];

# test 大对子

// $cards = [17, 17, 17, 19, 19, 19, 23, 23, 23, 36, 36, 36, 37, 37];

$ha = new HuAlgorithm($number);

$rs = $ha->start($cards);

print_r($rs);

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php麻将,php实现麻将牌型的胡牌检测算法 的相关文章

随机推荐