哎 好好说话啊
到底是“出来混迟早要还”还是“杀人放火金腰带”?
int cardType[2];//记录牌的类型和主体部分最小单张 static const short table[128] = { /***** 牌的大小表 ****/ ['1']=14,15,['3']=3,4,5,6,7,8,9, /** A 2 3 4 5 6 7 8 9 **/ ['A']=10,['J']=11,['K']=13,['Q']=12, /** 10 J K Q,用A表示10 **/ ['W']=17,['w']=16, /** 大王,小王 **/ }; int sub = 0, Len =0;// 分别表示 用来访问card数组的下标 和 连对顺子等的长度 int card [12] = {0},//出的牌 count[12] = {0};//对应上面的张数 if ( !table[cards[0]] ) {*cardType = 0; return 1;} //空牌,表示不出牌,合法牌 if ( !table[cards[1]] ) { *cardType = (1U <<4), //单张 cardTpye[1]=table[cards[1]]; //记录单张的大小 return 1;//返回合法牌 } *card = *cards;//第一张牌 for ( sub=0,--cards; !table[ *++cards ] ; ) //错误的出牌方法 基本上在这个循环里被淘汰了,还有就是为下面switch确定 牌的实际类型 做了必要的准备工作 { if ( card[sub] == *cards ) { ++len[sub]; continue; } else{ card[++sub] = *cards; ++ count[sub]; if ( sub<2 ) ; else if ( (Len) ) { if ( (len[Len-1]<=len[sub-1]) || (2*Len<=sub) ) return 0;//带的某种牌的张数比主体部分的还多,或者带的牌种类太多了错误的出法 } else if ( (len[sub-2] == len[sub-1]) ) { if ( table[card[sub-1]] - table[card[sub-2]] != 1 ) return 0;//错误的出法 } else{ Len = sub-1; } }//if card[sub]...else }//for if ( len[Len-1] <= len[sub] ) return 0;//非法出法 switch( len[Len-1] ) { case 1: if ( (len==2) && (card[0]=='w') && (card[1]=='W') ) { *cardType = 9; //炸弹,对鬼 cardType[1] = table[ *card ]; return 1; } else if ( (Len>=5) && (*card+Len<table['2'] )//顺子 最小长度为5,且顺子做多能到A { *cardType = (2U <<4)+Len; //顺子 cardType[1] = table[ *card ]; return 1; } else{ return 0; } break; case 2: if ( (Len==1) && (sub==0) ) { *cardType = (3U <<4); //对子 ,这里其实也可以不乘以32的 cardType[1] = table[ *card ]; return 1; } else if ( (Len>=3) && (*card+Len<table['2']) ) //连对最少要3对,最多可以到A,所以要比2小 { *cardType = (4U <<4)+Len; //连对 ,这里其实也可以不乘以32的 cardType[1] = table[ *card ]; return 1; } else{ retrun 0; } break; case 3: if ( (Len==1) && (sub==0) ) { *cardType = (5U <<4); //三张 cardType[1] = table[ *card ]; return 1; } else if ( (*card+Len<table['2']) && !( (sub>1)&&(card[sub-1]=='w')&&(card[sub]=='W') ) )不能带一对鬼 { *cardType = (6U <<4)+Len; //连三张 cardType[1] = table[ *card ]; return 1; } else{ return 0; } break; case 4: if ( (Len==1) && (sub==0) ) { *cardType = 9; //炸弹 cardType[1] = table[ *card ]; return 1; } else if ( (Len==1) && (sub==1) ) { *cardType = (7U <<4); //四张带牌,可以带单张,一对,三张 cardType[1] = table[ *card ]; return 1; } else if ( (Len>1) && (*card+Len<table['2']) ) { *cardType = (8U <<4) + Len; //连4张 cardType[1] = table[ *card ]; return 1; } else{ return 0; } break; default: break; } /* * 基本牌的类型:( 实际类型(炸弹的为9 ,非法牌的为-1) = 基本类型*32 + 长度 ) * 空牌:0 单张:1 顺子:2 对子:3 连对:4 * 三张:5 连三张:6 四张(带牌):7 连四张:8 炸弹:9 */ 对于比较大小,有了上面更简单了。 //对于空类型的牌可以和任何类型的牌匹配,在实现的时候注意一下就好了 //若果上面返回0,则是不合常规的牌 //如果 刚出的牌的类型 和 将要出的牌类型不匹配 //如果将要出的类型是9(炸弹),这是可以出的牌 //否则牌不匹配 //如果 刚出的牌的类型 和将要出的牌类型 匹配 //检查两者的 cardType[1]这的属性是不是后者比前者大,只有大才可以出牌