导航

打麻将判断天胡算法(c++)

Posted on 2013-07-14 00:54  iphone9  阅读(1012)  评论(1)    收藏  举报
  1 //打麻将天胡测试正式版.cpp
  2 
  3 #include <iostream>
  4 #include <time.h>
  5 #include <conio.h>
  6 #include <math.h>
  7 #include <windows.h>
  8 #include <string>
  9 using namespace std;
 10 
 11 //分解成“刻”“顺”组合
 12 bool Analyze(int aKindPai[])
 13 {
 14     if (0 == aKindPai[0])
 15     {
 16         return true;
 17     }
 18     
 19     //寻找第一张牌
 20     for (int j = 1; j < 10; j++)
 21     {
 22         if (0 != aKindPai[j])
 23         {
 24             break;
 25         }
 26     }
 27     
 28     bool result;
 29     
 30     if (aKindPai[j] >= 3)//作为刻牌
 31     {
 32         //除去这3张刻牌
 33         aKindPai[j] -= 3;
 34         aKindPai[0] -= 3;
 35         
 36         result = Analyze(aKindPai);
 37         
 38         //还原这3张刻牌
 39         aKindPai[j] += 3;
 40         aKindPai[0] += 3;
 41         
 42         return result;
 43     }
 44     
 45     //作为顺牌
 46     if ((j<8)&&(aKindPai[j+1]>0)&&(aKindPai[j+2]>0))
 47     {
 48         //除去这3张顺牌
 49         aKindPai[j]--;
 50         aKindPai[j+1]--;
 51         aKindPai[j+2]--;
 52         aKindPai[0] -= 3;
 53         
 54         result=Analyze(aKindPai);
 55         
 56         //还原这3张顺牌
 57         aKindPai[j]++;
 58         aKindPai[j+1]++;
 59         aKindPai[j+2]++;
 60         aKindPai[0] += 3;
 61         
 62         return result;
 63     }
 64     return false;
 65 }
 66 
 67 bool Hu(int count[3][10])
 68 {
 69     int jiang;//“将”的位置
 70     int mod;//余数
 71     bool jiangExisted = false;
 72     //是否满足3,3,3,3,2模型
 73     
 74     for (int i = 0; i < 3; i++)
 75     {
 76         mod = count[i][0] % 3;
 77         
 78         if (1 == mod)
 79         {
 80             return false;
 81         }
 82         
 83         if (2 == mod)
 84         {
 85             if (jiangExisted)
 86             {
 87                 return false;
 88             }
 89             
 90             jiang = i;
 91             jiangExisted = true;
 92         }
 93     }
 94     for (i = 0; i < 3; i++)
 95     {
 96         if (i != jiang) 
 97         {
 98             if (!Analyze(count[i]))
 99             {
100                 return false;
101             }
102         }
103     }
104     
105     //该类牌中要包含将,因为要对将进行轮询,效率较低,放在最后
106     bool success = false;//指示除掉“将”后能否通过
107     
108     for (int j = 1; j < 10; j++)//对列进行操作,用j表示
109     {
110         if (count[jiang][j] >= 2)
111         {
112             //除去这2张将牌
113             count[jiang][j] -= 2;
114             count[jiang][0] -= 2;
115             
116             if(Analyze(count[jiang]))
117             {
118                 success=true;
119             }
120             
121             //还原这2张将牌
122             count[jiang][j] += 2;
123             count[jiang][0] += 2;
124             
125             if (success) break;
126         }
127     }
128     return success;
129 }
130 
131 void Game(int test)
132 {
133     int a, b, t;
134     int i,j,z[14]= {0},flag = 1;
135     int count[3][10] = {{0},{0},{0}};
136     int num = 1;
137     
138     //建立一个麻将库,从中随机抽取麻将
139     string array[] = {"一条","二条","三条","四条","五条","六条","七条","八条","九条",
140         "一万","贰万","叁万","四万","伍万","六万","七万","八万","九万",
141         "一筒","二筒","三筒","四筒","五筒","六筒","七筒","八筒","九筒"};
142     
143     srand(time(NULL));//随机种子
144     
145     do
146     {
147         while (1 == flag)
148         {
149             flag = 0;
150             //随机数的产生,收集进数组.
151             if (1 == test)
152             {
153                 for (i = 0; i < 14 ; i++)
154                 {
155                     z[i] = rand()%7;
156                 }
157             }
158             else
159             {
160                 for (i = 0; i < 14 ; i++)
161                 {
162                     z[i] = rand()%27;
163                 }
164             }
165             
166             //对产生的数字进行整理(排序)冒泡排序    
167             for (a = 0; a < 13; a++)
168             {
169                 for (b = 0; b < 13 - a; b++)
170                 {
171                     if (z[b+1] < z[b])
172                     {
173                         t = z[b+1];
174                         z[b+1] = z[b];
175                         z[b] = t;
176                     }
177                 }
178             }
179             
180             //判断是否超出4张,超出就重新发牌
181             for (i = 0; i < 10; i++)
182             {
183                 if ((z[i] == z[i+1]) && (z[i+1] == z[i+2]) && (z[i+2] == z[i+3]) && (z[i+3] == z[i+4]))
184                 {
185                     flag = 1; 
186                 }
187             }
188         }
189 
190         flag = 1;
191         
192         cout<<"No."<<num++<<endl;
193         cout<<endl<<"你得到的牌:"<<endl<<endl;
194         for (i = 0; i < 14; i++)
195         {
196             cout<<array[z[i]]<<" ";
197         }
198         cout<<endl;
199         
200         //再次初始化
201         for (i = 0; i < 3; i++)
202         {
203             for (j = 0; j < 10; j++)
204             {
205                 count[i][j] = 0;
206             }
207         }
208     
209         //统计牌数目
210         for (i = 0; i < 14; i++)
211         {
212             switch(z[i])
213             {
214             case 0: count[0][1]++; break;
215             case 1: count[0][2]++; break;
216             case 2: count[0][3]++; break;
217             case 3: count[0][4]++; break;
218             case 4: count[0][5]++; break;
219             case 5: count[0][6]++; break;
220             case 6: count[0][7]++; break;
221             case 7: count[0][8]++; break;
222             case 8: count[0][9]++; break;
223             case 9: count[1][1]++; break;
224             case 10: count[1][2]++; break;
225             case 11: count[1][3]++; break;
226             case 12: count[1][4]++; break;
227             case 13: count[1][5]++; break;
228             case 14: count[1][6]++; break;
229             case 15: count[1][7]++; break;
230             case 16: count[1][8]++; break;
231             case 17: count[1][9]++; break;
232             case 18: count[2][1]++; break;
233             case 19: count[2][2]++; break;
234             case 20: count[2][3]++; break;
235             case 21: count[2][4]++; break;
236             case 22: count[2][5]++; break;
237             case 23: count[2][6]++; break;
238             case 24: count[2][7]++; break;
239             case 25: count[2][8]++; break;
240             case 26: count[2][9]++; break;
241             default:cout<<"不存在!"<<endl; break;
242             }
243         }
244         for (i = 0; i < 3; i++)
245         {
246             for (j = 1; j < 10; j++)
247             {
248                 count[i][0] += count[i][j];
249             }
250         }
251         //发牌情况显示
252     /*    
253         cout<<endl;
254         for (i = 0; i < 3; i++)
255         {
256             for (j = 0; j < 10; j++)
257             {
258                 cout<<count[i][j]<<" ";
259             }
260             cout<<endl;
261         }
262         cout<<endl;
263         */
264         
265         if (Hu(count))
266         {
267             system("color 4a");
268             cout<<endl<<"  恭喜你,天胡!"<<endl;
269             getchar();
270             break;
271         }
272         else
273         {
274             system("color 5a");
275             cout<<endl<<"  很遗憾!没胡牌,按回车再来一次...."<<endl;    
276         }
277     }while('\n' == getchar());
278     system("cls");
279 }
280 
281 int main()
282 {
283     int n;
284     
285     cout<<endl<<"你好!欢迎来到打麻将天胡游戏^@^..."<<endl<<endl;
286 index:
287     system("color 1a");
288     cout<<"                       游戏说明:"<<endl;
289     cout<<"                       1.开始游戏"<<endl;
290     cout<<"                       2.游戏试玩"<<endl;
291     cout<<"                       3.退出游戏"<<endl;
292     cout<<"                       提示:3秒后默认进入游戏."<<endl;
293     
294     cout<<endl<<"                      倒计时:....3";
295     Sleep(1000);
296     cout<<"\b2";
297     Sleep(1000);
298     cout<<"\b1"<<endl;
299     cout<<endl<<"                                     我选择:__\b\b";
300     Sleep(1000);
301     
302     if (kbhit())
303     {
304 loop:
305     cin>>n;
306     getchar();//吸收上面的回车
307     }
308     else
309     {
310         n = 1;
311     }
312     system("cls");
313     cout<<endl<<endl<<"                  游戏加载中.....";
314     Sleep(2000);
315     system("cls");
316     switch(n)
317     {
318     case 1: Game(0); cout<<endl<<endl<<endl; goto index;
319     case 2: Game(1); cout<<endl<<endl<<endl; goto index;
320     case 3: exit(1);
321     default:cout<<"输入有误!请再次输入:__\b\b";
322         goto loop; break;
323     }
324     
325     
326     
327     return 0;
328 }

这是我这次的实验题,我编写出来后就发上来了。

题目要求是这样的:

108张麻将(条、万、筒各36张,1~94张),随机产生14张,判断是否和牌。

没有东,西,南,北 这些单字牌。

by : null

2013年7月14日0:53:16

参考博客:http://lanbolee.com/blog/?p=103