编程练习场————还说不是炸胡

还说不是炸胡

麻将是国粹,是成都的生活重心。作为一个成都人,一定要把麻将发扬光大。

现在组织有一个重要的任务交给你:请你设计一个判断是否炸胡的程序。

什么是炸胡? 炸胡,是指达不到胡牌条件就把牌推倒了。 那什么是胡牌呢? 胡牌代表你赢了。

当你手上的牌符合三种胡牌牌型之一时,就是胡牌,可以推倒牌收钱啦。

三种胡牌牌型

  1. 普通牌型,14张牌,形如:3+3+3+3+2。其中数字2代表两张相同的牌可成一组,形如XX。数字3代表三张相同或者连续的牌可成一组,形如XXX、XYZ。
  2. 龙七对,14张形如:2+2+2+2+2+2+2
  3. 带杠,即普通牌型里三张一样的牌XXX可以升级成XXXX,称为一道杠。每多一道杠,牌总数可以增加一张。最多可以有4道杠,因此带杠的胡牌,牌总数最多可以达18张。

牌的表示方式

下面我们用 ABCDEFGHI代表一到九萬,abcdefghi代表一到九条,123456789代表一到九饼。

先来练习一下:

  • ABCeee345456DD 胡牌,组牌方式为 ABC+eee+345+456+DD,普通牌型。
  • ABeeee345456DD 炸胡,因为AB两张牌未能形成组牌。
  • AAAABC123456333 炸胡,虽然看似组牌OK(AAA+ABC+124+345+456+333)但是不符合任何一种胡牌牌型。
  • AADDFF1133aagg 胡牌,暗七对。
  • AAAABBBBCCCCDDDD88 胡牌,3+3+3+3+2牌型,升级了4道杠。
  • AAA123789 炸胡,不符合任何一种牌型。
  • AAA111345666DEF88 炸胡,不符合任何一种牌型。

学会了吗?

现在给你一副牌,请用你的程序来判断这副牌是胡牌还是炸胡。

输入说明

程序从命令行参数取得输入数据。

测试数据为一个字符串,代表一副牌,请参考上面牌的表示方式。 注意:牌序是乱的。

输出说明

若这副牌达到胡牌条件,输出GOOD,炸胡则输出BAD

示例

测试数据:123BCD999abd66

预期输出:BAD

思路::

 

1.贷gang
2.一对将
3.取3个一样或连续,满足则不要了,直到没牌
先getchar将牌放到
1.存放在一个18数组char a里面,不管重复,最多18个牌,计数,判定1条件14 17
/sort排序,需要?
2.再来个数组int b计算每个牌个数对应同万条0-8,9-17,18-26,27个牌一眼看出,比如b【0】=2,说明同1有2个
for循环a数组,switch(a【i】),比如a【i】==‘1’,就b【0】++
所以,如果加一个sort排序a,按1 A a, 11AAABBBaaabbb,排序好之后,哦,还是不可以节省break,还是要for循环. 所以还是不排序省一点运行时间
3.判定条件二,for循环数组b,if》=2,OK,并且让他减2
这里有个问题????????????????????,要找到正确的将,因为可能有很多牌都不止》=2,所以要先找=2的,等于二的也不一定,比如123345 AABCD DDD,正确的将是AA,但遍历会先找到33,  
所以遍历所有将牌的情况来解决这里的问号

并且这里D不是gang
如果是正确的gang牌还要先减去gang-4再判定2,3条件 ,怎样找到是真正的gang???????????????????所以找到所有的4张牌的,分为-4与不-4,(ps:但还有种胡是七对,拿来单独判定吧,遍历 有对y++, if y==7就可以,不可以正常判定,goto) 15-4,11等于9+2,真正的gang,16-8=8=6+2,两gang,17-12=5=3+2,3gang,还有4gang,但不带gang就是14张,所以之间for加起来,if =14,不带,》14带,减4再找牌判定
所以根据牌的个数解决这里的问好
4。找到了将,判定三张一样的,有就-3,然后判定三张连续的,whileb数字不全为0,即还有牌,for找到》=1的,下表为x,然后if(x+1和+2也》=1),分别减去1

 

主要看看这里如何遍历所有对牌

 

for (i = 0; i < 27; i++)
		c[i] = b[i];
	
	for (int k = 0; k < 27; k++)
	{
		if (c[k] < 2)
			continue;
		c[k] -= 2;
		for (i = 0; i < 27; i++) {//除开三个牌一样的
			if (c[i] == 3)
				c[i] -= 3;
		}
		for (i = 0; i < 27; i++) {
			if ((c[i] >= 1) && (c[i + 1] >= 1) && (c[i + 2] >= 1)) {
				c[i] -= 1;
				c[i + 1] -= 1;
				c[i + 2] -= 1;
			}
		}
		sum = 0;
		for (i = 0; i < 27; i++)
			sum += c[i];
		for (i = 0; i < 27; i++)
			c[i] = b[i];
		if (!sum) {
			printf("GOOD");
			return 0;
		}
	}

 

此时已经没有了gang

效率不高,27个对牌都测试一下,但还好,没有就continue

主要在这个思路

每次取对牌前都要个原始的牌,每次都是重新测试,所有要找一个备份!!!

#include<stdlib.h>

int main(int argc,char *argv[])
{
	char *majong = argv[1];
	int b[27] = { 0 };
	int i,sum=0,dui=0,gang=0;
	for (i = 0; i <18 ; i++)
	{
		char ch = majong[i];
		switch (ch)
		{
		    case '1':b[0]++; break;case '2':b[1]++; break;case '3':b[2]++; break;case '4':b[3]++; break;case '5':b[4]++; break;
			case '6':b[5]++; break;case '7':b[6]++; break;case '8':b[7]++; break;case '9':b[8]++; break;case 'A':b[9]++; break;
			case 'B':b[10]++; break;case 'C':b[11]++; break;case 'D':b[12]++; break;case 'E':b[13]++; break;case 'F':b[14]++; break;
			case 'G':b[15]++; break;case 'H':b[16]++; break;case 'I':b[17]++; break;case 'a':b[18]++; break;case 'b':b[19]++; break;
			case 'c':b[20]++; break;case 'd':b[21]++; break;case 'e':b[22]++; break;case 'f':b[23]++; break;case 'g':b[24]++; break;
			case 'h':b[25]++; break;case 'i':b[26]++; break;
			default: break;//其他的直接过滤掉,比如后面的\0和未知?
		}
	}
	for (i = 0; i < 27; i++) {
		sum += b[i];
	}
	if (sum < 14) {
		printf("BAD");
		return 0;
	}
	else if (sum == 14) {//14情况下龙七对判定
		for (i = 0; i < 27; i++) {
			if (b[i] == 2)
				dui++;
			else if (b[i] == 4)
				dui += 2;
		}
		if (dui == 7) {
			printf("GOOD");
			return 0;
		}
	}
	else if (sum == 15||sum==16||sum==17||sum==18) {//杠
		for (i = 0; i < 27; i++) {
			if (b[i] == 4) {
				gang++;
				b[i] = 0;
			}//这里有问题,万一去掉的不是正确的gang
			else {
				printf("BAD");
				return 0;
			}

		}
	}
	//现在已经去掉了gang并且龙七对情况已经说明,现在找将牌
	int c[27] = { 0 };
	for (i = 0; i < 27; i++)
		c[i] = b[i];
	
	for (int k = 0; k < 27; k++)
	{
		if (c[k] < 2)
			continue;
		c[k] -= 2;
		for (i = 0; i < 27; i++) {//除开三个牌一样的
			if (c[i] == 3)
				c[i] -= 3;
		}
		for (i = 0; i < 27; i++) {
			if ((c[i] >= 1) && (c[i + 1] >= 1) && (c[i + 2] >= 1)) {
				c[i] -= 1;
				c[i + 1] -= 1;
				c[i + 2] -= 1;
			}
		}
		sum = 0;
		for (i = 0; i < 27; i++)
			sum += c[i];
		for (i = 0; i < 27; i++)
			c[i] = b[i];
		if (!sum) {
			printf("GOOD");
			return 0;
		}
	}
	
	printf("BAD");
	return 0;
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值