- 论坛徽章:
- 0
|
麻将游戏开发
- /***************************************************************
- * 文件名: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]&&i<38;i++); // 找到有牌的地方,i就是当前牌, PAI[i]是个数
- printf("i = %d\n",i); // 跟踪信息
- // 4张组合(杠子)
- if ( PAI[i] == 4 ) // 如果当前牌数等于4张
- {
- PAI[i] = 0; // 除开全部4张牌
- if( Hu(PAI) ) return 1; // 如果剩余的牌组合成功,和牌
- PAI[i] = 4; // 否则,取消4张组合
- }
- // 3张组合(大对)
- if ( PAI[i] >;= 3 ) // 如果当前牌不少于3张
- {
- PAI[i] -= 3; // 减去3张牌
- if( Hu(PAI) ) return 1; // 如果剩余的牌组合成功,和牌
- PAI[i] += 3; // 取消3张组合
- }
- // 2张组合(将牌)
- if ( !JIANG && PAI[i] >;= 2 ) // 如果之前没有将牌,且当前牌不少于2张
- {
- JIANG = 1; // 设置将牌标志
- PAI[i] -= 2; // 减去2张牌
- if( Hu(PAI) ) return 1; // 如果剩余的牌组合成功,和牌
- PAI[i] += 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[i]--;
- PAI[i+1]--;
- PAI[i+2]--; // 各牌数减1
- if( Hu(PAI) ) return 1; // 如果剩余的牌组合成功,和牌
- PAI[i]++;
- 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[i];
- return sum;
- }
复制代码 |
|