【算法】PHP简单实现斗地主洗牌和发牌

最近有时间了,重新学习一下基础知识。工作中一直都只关注业务实现,丢了很多基础的东西。今天遇到一道题目问斗地主的数据结构要怎么设计,当时初步构思了一下,今晚把构思写出来,并加上洗牌的简单实现。

思路:理清斗地主的出牌逻辑,如

炸弹:王炸、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;

}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
斗地主多人网页版游戏插件,完美与论坛积分结合,消耗会员积分,支持X2.5版本! 游戏特点: 1.可与社区积分数据共享-消耗用户积分(站长可在启动.exe里控制积分消耗数量) 论坛积分就像是一个国家的货币一样,只有流动起来才能发挥价值,进而提升社区价值;而实际情况是,一些发展有些年限的社区,其会员往往积累了大量积分,而且这些积分的消费处于停滞状态; 让会员参与游戏,那么又要花力气赚取积分,又要消费积分,对社区来说将增加会员活跃度以及促进社区积分流动两不误,用途还是非常大的 底分,消耗分,指定存入,严防作弊 完美扣分系统,让社区的积分流动起来! 2.提高用户之间的粘度与活跃度 有了积分消耗,提高了用户发贴的积极性,增加了用户交流的途径 同时提升社区和其他社区相比的竞争力。 3.多人同时在线的大型社区游戏(斗地主斗地主是一种扑克游戏。游戏最少由3个玩家进行,用一副54张牌,其中一方为地主,其余两家为另一方,双方对战,先出完牌的一方获胜。 该扑克游戏最初流行于中国湖北,现已逐漸在各地流行 。 斗地主网络版是问答娱乐推出的一套多人网络联机牌类游戏,网络版包括高性能服务端+纯Flash客户端 。 --------------------------------------------------------------------------------------- 多人斗地主在线游戏插件 特别说明本版是本地安装服务端版,服务端需要有VPS或独立主机才能运行起来 用户数据全部储存您的服务器上,而非第三方应用 游戏是flash网页版,可以和论坛很好的整合在一起 需要独立主机或VPS方可架设, 客户端是flash版,有一个ddz.php,网页上加个链接就可以了 服务端需要运行在有EXE权限的主机上,设好IP, 本次V2 SP2的更新,提高了服务器的稳定性,减少了出现卡死的情况, 从以前每天重启一次服务端,到现在只需3天或一星期重启一次,减少了管理员的维护工作量。 客户端则提高了浏览器的兼容性,各种浏览器都可以正常登陆。 斗地主最近更新: 明牌模式扣分加成 90秒不准备自动退出房间 不叫分退出房间实施惩罚性扣分(底分按2分来算) discuz头像读取 discuz自定积分字段 增加一套全新木头桌子界面 增加一套全新美女十三钗桃色界面 空闲用户列表从10人增加至50人可选 自动登录 智能出牌提示 托管模式 明牌模式 报警设置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值