[算法]麻将的"胡牌"算法

发布于 2022-06-18 05:56:01 字数 68 浏览 424 评论 3

我在一个论坛上看到一个"胡牌"的算法,感觉不错!!

不过,它也有点问题,贴出来大家讨论一下,看有没有改进!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吻安 2022-06-26 04:33:27

楼上的,是不是编译出错呀。。。

这个算法思路是很好的,我没有具体上机操作,有什么问题一起讨论

好吗??

此生挚爱伱 2022-06-24 02:47:48

[typhoon@TFW-RFL40 tmp]$ gcc hu.cpp
hu.cpp: In function `int Hu(int*)':
hu.cpp:59: name lookup of `i' changed for new ISO `for' scoping
hu.cpp:57:   using obsolete binding at `i'
[typhoon@TFW-RFL40 tmp]$

紫竹語嫣☆ 2022-06-23 11:00:59

/***************************************************************
* 文件名:hu.cpp                                              *
*                                                             *
* 功  能:演示一个简洁明了的递归函数——判断[麻将]的和牌。    *
*                                                             *
* 说  明:1.  此函数不判断七对和十三幺,读者不难自行判断;    *
*     同时由于麻将的规则各不相同,也请读者自己添加和修改。*
*                                                             *
*     2.  其他与麻将类似的游戏,如[字牌](又称跑胡子、    *
*     二七十)等牌类游戏,也可采用类似的判断函数。        *
*                                                             *
* 环  境: VC 6.0,  但符合ANSI C标准,随便移植 ^_^             *
*                                                             *
* 作  者:shyworm(怕怕虫)                                     *
* E_Mail: shyworm@sina.com                                    *
***************************************************************/
#include <stdio.h>;

int Hu(int PAI[38]);
int Remain(int PAI[38]);

int main()
{
    // 把一副牌放在下面的数组里,可以任意填入数字来测试函数正确与否。
    // 为了方便,PAI[0],PAI[10],PAI[20],PAI[30]都弃之不用,并且必须
    // 置为0,千万注意!
    int PAI[38] = { 0,
                    1,1,1,0,1,1,1,0,0,    // PAI[ 1- 9]  壹万~玖万的个数
                    0,
                    0,0,0,0,0,3,0,0,0,    // PAI[11-19]  壹铜~玖铜的个数
                    0,
                    0,0,0,0,0,0,0,0,0,    // PAI[21-29]  壹条~玖条的个数
                    0,
                    0,1,1,1,0,0,0         // PAI[31-37]  东南西北中发白的个数
                    };

    // 请务必先排除“七对” 和“十三幺”,由于简单,所以不提供了
    // if( QIDUI(PAI) )...
    // if( SHISANYAO(PAI) )...

    if( Hu(PAI) )  
        printf("哈!我和啦!n";
    else
        printf("哎,和不成!n";

    return 1;
}

// 判断和牌的递归函数,不考虑“七对” 和“十三幺”。因为如果
// 把“七对” 和“十三幺”的判断放在递归函数里,将得不偿失。
int Hu(int PAI[38])
{
    static int JIANG = 0;            // 将牌标志,即牌型“三三三三二”中的“二”

    if( !Remain(PAI) ) return 1;     // 递归退出条件:如果没有剩牌,则和牌返回。

    for(int i=1;!PAI&&i<38;i++);  // 找到有牌的地方,i就是当前牌, PAI是个数

    printf("i = %dn",i);            // 跟踪信息

    // 4张组合(杠子)
    if ( PAI == 4 )               // 如果当前牌数等于4张
    {
        PAI = 0;                  // 除开全部4张牌
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,和牌
        PAI = 4;                  // 否则,取消4张组合
    }

    // 3张组合(大对)
    if ( PAI >;= 3 )               // 如果当前牌不少于3张
    {
        PAI -= 3;                 // 减去3张牌
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,和牌
        PAI += 3;                 // 取消3张组合
    }

    // 2张组合(将牌)
    if ( !JIANG && PAI >;= 2 )     // 如果之前没有将牌,且当前牌不少于2张
    {
        JIANG = 1;                   // 设置将牌标志
        PAI -= 2;                 // 减去2张牌
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,和牌
        PAI += 2;                 // 取消2张组合
        JIANG = 0;                   // 清除将牌标志
    }

   
    if ( i >; 30 )    return 0;       // “东南西北中发白”没有顺牌组合,不和

    // 顺牌组合,注意是从前往后组合!
    if( i%10 != 8 && i%10 != 9  &&   // 排除数值为8和9的牌
         PAI[i+1] && PAI[i+2] )      // 如果后面有连续两张牌
    {
        PAI--;
        PAI[i+1]--;
        PAI[i+2]--;                  // 各牌数减1
        if( Hu(PAI) ) return 1;      // 如果剩余的牌组合成功,和牌
        PAI++;
        PAI[i+1]++;
        PAI[i+2]++;                  // 恢复各牌数
    }

    // 无法全部组合,不和!
    return 0;
}

// 检查剩余牌数
int Remain(int PAI[38])
{
    int sum = 0;
    for(int i=1;i<38;i++)
        sum += PAI;
    return sum;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文