最近有时间了,重新学习一下基础知识。工作中一直都只关注业务实现,丢了很多基础的东西。今天遇到一道题目问斗地主的数据结构要怎么设计,当时初步构思了一下,今晚把构思写出来,并加上洗牌的简单实现。
思路:理清斗地主的出牌逻辑,如
炸弹:王炸、4炸;
3带1对,3带1个,3个不带;
飞机:3+3,3+3+1+1,3+3+2+2;
顺子:牌3到牌A连续,5张起
一对
单个
等
按照这个思路逻辑,我计划用数字大小来做牌的主key,方便后续实现运算,王+13个牌,分别设计为王-14,二-13,A-12...三-1 ,一个牌有4个花色,分别用4到1来区分。大小王分别用142、141,二用134,133,132,131,依此类推来设计牌的数据结构。
/**
* @name 简单版 斗地主洗牌、发牌
* @return array
*/
public function randPuker()
{
$puker = [
142 => '大王',
141 => '小王',
134 => '黑桃2',
133 => '红心2',
132 => '梅花2',
131 => '方块2',
124 => '黑桃A',
123 => '红心A',
122 => '梅花A',
121 => '方块A',
114 => '黑桃K',
113 => '红心K',
112 => '梅花K',
111 => '方块K',
104 => '黑桃Q',
103 => '红心Q',
102 => '梅花Q',
101 => '方块Q',
94 => '黑桃J',
93 => '红心J',
92 => '梅花J',
91 => '方块J',
84 => '黑桃10',
83 => '红心10',
82 => '梅花10',
81 => '方块10',
74 => '黑桃9',
73 => '红心9',
72 => '梅花9',
71 => '方块9',
64 => '黑桃8',
63 => '红心8',
62 => '梅花8',
61 => '方块8',
54 => '黑桃7',
53 => '红心7',
52 => '梅花7',
51 => '方块7',
44 => '黑桃6',
43 => '红心6',
42 => '梅花6',
41 => '方块6',
34 => '黑桃5',
33 => '红心5',
32 => '梅花5',
31 => '方块5',
24 => '黑桃4',
23 => '红心4',
22 => '梅花4',
21 => '方块4',
14 => '黑桃3',
13 => '红心3',
12 => '梅花3',
11 => '方块3',
];
//随机打乱数组,由于shuffle函数会重置key值,所以使用key值来打乱,再通过key值把牌生成好
$randKeys = array_keys($puker);
shuffle($randKeys);
//重新按打乱顺序排好牌
foreach ($randKeys as $k){
$pukerTemp[$k] = $puker[$k];
}
//重组完毕
$puker = $pukerTemp;
//先抽3张作为底牌
$keys = array_rand($puker,3);
$arrCover = [];
foreach ($keys as $key){
$arrCover[$key] = $puker[$key];
unset($puker[$key]);
}
$i = 0;
//将剩下的数组分3份,发牌
foreach($puker as $key => $val){
$arrPlayer[$i % 3][$key] = $val;
$i++;
}
return array('cover'=> $arrCover, 'player'=> $arrPlayer);
}
拿到牌以后,可以按顺序排列。
public function test()
{
echo '<pre>';
$data = $this->randPuker();
//如果玩家1叫地主,则把底牌给他
$i = 0;//0,1,2
$data['player'][$i] = $data['player'][$i] + $data['cover'];
krsort($data['player'][0]);
krsort($data['player'][1]);
krsort($data['player'][2]);
print_r($data);
die();
}
运行结果:
Array
(
[cover] => Array
(
[114] => 黑桃K
[12] => 梅花3
[51] => 方块7
)
[player] => Array
(
[0] => Array
(
[141] => 小王
[133] => 红心2
[122] => 梅花A
[114] => 黑桃K
[113] => 红心K
[112] => 梅花K
[111] => 方块K
[104] => 黑桃Q
[84] => 黑桃10
[82] => 梅花10
[73] => 红心9
[64] => 黑桃8
[63] => 红心8
[61] => 方块8
[51] => 方块7
[34] => 黑桃5
[24] => 黑桃4
[21] => 方块4
[13] => 红心3
[12] => 梅花3
)
[1] => Array
(
[142] => 大王
[134] => 黑桃2
[132] => 梅花2
[131] => 方块2
[121] => 方块A
[103] => 红心Q
[101] => 方块Q
[93] => 红心J
[83] => 红心10
[74] => 黑桃9
[52] => 梅花7
[44] => 黑桃6
[41] => 方块6
[31] => 方块5
[23] => 红心4
[14] => 黑桃3
[11] => 方块3
)
[2] => Array
(
[124] => 黑桃A
[123] => 红心A
[102] => 梅花Q
[94] => 黑桃J
[92] => 梅花J
[91] => 方块J
[81] => 方块10
[72] => 梅花9
[71] => 方块9
[62] => 梅花8
[54] => 黑桃7
[53] => 红心7
[43] => 红心6
[42] => 梅花6
[33] => 红心5
[32] => 梅花5
[22] => 梅花4
)
)
)
另再写了个出牌key值获取的方法,方便后续出牌判断。
public function getPukerKey($k)
{
//提取牌的大小及花色,斗地主除了大小王,其他牌与花色无关,通过判断数字大小及打牌规则来看是否可以出牌
if($k < 100){
$pk = substr($k,0,1);
//$hs = substr($k,-1);
}else{
$pk = substr($k,0,2);
//$hs = substr($k,-1);
}
//echo $pk.'<br/>';
return $pk;
}