程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 【興趣分享】C#完成回味童年的24點算法游戲

【興趣分享】C#完成回味童年的24點算法游戲

編輯:C#入門知識

【興趣分享】C#完成回味童年的24點算法游戲。本站提示廣大學習愛好者:(【興趣分享】C#完成回味童年的24點算法游戲)文章只能為提供參考,不一定能成為您想要的結果。以下是【興趣分享】C#完成回味童年的24點算法游戲正文


 一、24點游戲玩法規則效果展現

1、初始化界面

2、開端游戲界面

3、游戲超時界面

 

4、檢查答案界面

 

5、答對界面

6、答錯界面

7、計算表達式的驗證界面

 

8、一副牌算完開端新一副牌界面

 到這裡24點算法根本操作圖就完畢了,上面來看看示例代碼吧。

二、完好代碼演示

 關於代碼解釋,為了方便讀者閱讀時更好了解代碼的含義,我把正文都寫在代碼外面了。由於一開端我只思索到功用上的完成並沒有思索代碼的優化所以代碼我就全寫在一個頁面了。至於那些生成撲克牌類、計算類等代碼優化方面的內容就留給想要完成這個24點算法游戲的讀者自己去完善吧。

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.ComponentModel;
  5 using System.Data;
  6 using System.Drawing;
  7 using System.IO;
  8 using System.Linq;
  9 using System.Text;
 10 using System.Threading.Tasks;
 11 using System.Windows.Forms;
 12 
 13 namespace XF_24Point
 14 {
 15     public partial class frnMain : Form
 16     {
 17         private int A, B, C, D;//牌面大小對應的數字大小也用於交流數字的地位
 18         private int NumberA, NumberB, NumberC, NumberD;//牌面大小對應的數字大小
 19         private int topCard;//顯示在窗體四張牌中撲克牌的編號(1-52)
 20         DateTime beginTime;//記載開端時間
 21       
 22         #region 一副牌的生成
 23         //構造: 值得一提的是,在C++中,struct的功用失掉了強化,struct不只可以添加成員變量,還可以添加成員函數,和class相似。
 24         struct card
 25         {
 26             public int face;//牌面大小,數字大小
 27             public int suit;//牌面花樣,如梅花、黑桃、紅心、方塊,只能有四張
 28             public int count;//牌面點數,牌面上的的圖案點數
 29             public bool faceup;//牌面能否向上
 30         }
 31         private card[] PlayingCards;//一副牌
 32 
 33         //生成一副牌
 34         private void GetPlayingCareds()
 35         {
 36             PlayingCards = new card[53];
 37             int i;//牌面大小
 38             int j;//牌面花樣
 39             for (i = 0; i < 13; i++)
 40             {
 41                 for (j = 1; j <= 4; j++)
 42                 {
 43                     PlayingCards[j + i * 4].face = i + 1;//PlayingCards[j + i * 4]:指的是:j + i * 4  =>獲取文件圖片撲克牌的序號
 44                     PlayingCards[j + i * 4].suit = j;//牌面花樣,如梅花、黑桃、紅心、方塊,只能有四張
 45                     if (i < 10)
 46                     {
 47                         PlayingCards[j + i * 4].count = i + 1;//牌面點數,牌面上的的圖案點數
 48                     }
 49                     else
 50                     {
 51                         PlayingCards[j + i * 4].count = 10;
 52                     }
 53                     PlayingCards[j + i * 4].faceup = false;
 54                 }
 55             }
 56         }
 57         //洗牌 :Shuffle
 58         private void Shuffle()
 59         {
 60             Random random = new Random((int)DateTime.Now.Ticks);
 61             card middleCard;//作為暫時交流牌順序的變量
 62             int j, k;
 63             for (int i = 0; i < 1000; i++)
 64             {
 65                 j = (int)random.Next(1, 52);
 66                 k = (int)random.Next(1, 52);
 67                 //打亂牌的順序(隨機交流牌的順序)
 68                 middleCard = PlayingCards[j];
 69                 PlayingCards[j] = PlayingCards[k];
 70                 PlayingCards[k] = middleCard;
 71             }
 72         }
 73         //開端游戲的時分發四張牌
 74         private void btnStart_Click(object sender, EventArgs e)
 75         {
 76             lblInput.Text = "";
 77             GetPlayingCareds();//生成一副牌
 78             Shuffle();//洗牌
 79             topCard = 0;//顯示在窗體四張牌中撲克牌的編號(1-52)
 80             int imageNum;//文件夾中撲克牌圖片的編號(文件名)
 81             string path;
 82             //畫第一張牌
 83             topCard = topCard = 1;
 84             pictureBox1.Visible = true;
 85             //取得文件中某張牌並且知道是什麼花樣對應的編號計算公式:
 86             //牌面花樣(1、2、3、4):要取得某張牌的的花樣
 87             //(牌面數字大小-1)*4:要取得的某張牌的前一個牌面大小如:要取得的牌是10,前一個牌面就是9
 88             //牌面花樣(1、2、3、4)+(牌面數字大小-1)*4
 89             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;//文件圖片編號
 90             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
 91             pictureBox1.Image = Image.FromFile(path);
 92             NumberA = Convert.ToInt32(PlayingCards[topCard].face);//牌面大小對應的數字大小
 93             btnNumber1.Text = NumberA.ToString();
 94             //畫第二張牌
 95             topCard = topCard + 1;
 96             pictureBox2.Visible = true;
 97             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
 98             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
 99             pictureBox2.Image = Image.FromFile(path);
100             NumberB = Convert.ToInt32(PlayingCards[topCard].face);
101             btnNumber2.Text = NumberB.ToString();
102             //畫第三張牌
103             topCard = topCard + 1;
104             pictureBox3.Visible = true;
105             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
106             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
107             pictureBox3.Image = Image.FromFile(path);
108             NumberC = Convert.ToInt32(PlayingCards[topCard].face);
109             btnNumber3.Text = NumberC.ToString();
110             //畫第四張牌
111             topCard = topCard + 1;
112             pictureBox4.Visible = true;
113             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
114             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
115             pictureBox4.Image = Image.FromFile(path);
116             NumberD = Convert.ToInt32(PlayingCards[topCard].face);
117             btnNumber4.Text = NumberD.ToString();
118             //初始化界面控件
119             btnStart.Visible = false;//開端游戲
120             groupBox1.Visible = true;//計算表達式
121             groupBox2.Visible = true;//檢查答案
122             groupBox3.Visible = true;//游戲規則
123             lblShowTime.Visible = true;//顯示時間
124             timer1.Enabled = true;//啟用時鐘
125             beginTime = DateTime.Now;
126         }
127         #endregion
128 
129         public frnMain()
130         {
131             InitializeComponent();
132             Initialize();//初始化窗體上的控件的辦法
133         }
134 
135         //初始化窗體上的控件的辦法,一開端隱藏
136         private void Initialize()
137         {
138             pictureBox1.Visible = false;
139             pictureBox2.Visible = false;
140             pictureBox3.Visible = false;
141             pictureBox4.Visible = false;
142             groupBox1.Visible = false;
143             groupBox2.Visible = false;
144             groupBox3.Visible = false;
145             lblResult.Visible = false;
146             lblShowTime.Visible = false;
147         }
148 
149         #region 計算表達式的輸出
150         //第一張牌
151         private void btnNumber1_Click(object sender, EventArgs e)
152         {
153             lblInput.Text = lblInput.Text + btnNumber1.Text.Trim();
154         }
155         //第二張牌
156         private void btnNumber2_Click(object sender, EventArgs e)
157         {
158             lblInput.Text = lblInput.Text + btnNumber2.Text.Trim();
159         }
160         //第三張牌
161         private void btnNumber3_Click(object sender, EventArgs e)
162         {
163             lblInput.Text = lblInput.Text + btnNumber3.Text.Trim();
164         }
165         //第四章牌
166         private void btnNumber4_Click(object sender, EventArgs e)
167         {
168             lblInput.Text = lblInput.Text + btnNumber4.Text.Trim();
169         }
170         //加號
171         private void btnAdd_Click(object sender, EventArgs e)
172         {
173             lblInput.Text = lblInput.Text + btnAdd.Text.Trim();
174         }
175         //減號
176         private void btnMinus_Click(object sender, EventArgs e)
177         {
178             lblInput.Text = lblInput.Text + btnMinus.Text.Trim();
179         }
180         //乘號
181         private void btnMulti_Click(object sender, EventArgs e)
182         {
183             lblInput.Text = lblInput.Text + btnMulti.Text.Trim();
184         }
185         //除號
186         private void btnDivide_Click(object sender, EventArgs e)
187         {
188             lblInput.Text = lblInput.Text + btnDivide.Text.Trim();
189         }
190         //左括號
191         private void btnLeft_Click(object sender, EventArgs e)
192         {
193             lblInput.Text = lblInput.Text + btnLeft.Text.Trim();
194         }
195         //右括號
196         private void btnRight_Click(object sender, EventArgs e)
197         {
198             lblInput.Text = lblInput.Text + btnRight.Text.Trim();
199         }
200         //刪除最後一個字符
201         private void btnDelete_Click(object sender, EventArgs e)
202         {
203             string input = lblInput.Text.Trim();
204             lblInput.Text = input.Substring(0, input.Length - 1);
205         }
206         //肅清一切字符
207         private void btnClear_Click(object sender, EventArgs e)
208         {
209             lblInput.Text = "";
210         }
211 
212         #endregion
213 
214         //確定按鈕
215         private void btnEnter_Click(object sender, EventArgs e)
216         {
217             if (lblInput.Text.Trim()== "")
218             {
219                 MessageBox.Show("計算表達式不能為空!");
220                 return;
221             }
222             if (CheckForNumber(lblInput.Text.Trim()))//反省輸出表達式中輸出的數字能否婚配
223             {
224                 //計算表達式的後果第一層
225                 int result = Deal(lblInput.Text.Trim());//調用Deal()處置辦法,對用戶輸出的表達式做一系列判別計算,前往最終的後果
226                 lblResult.Visible = true;
227                 if (result == 24)
228                 {
229                     lblResult.Text = "<<---祝賀您,答對了!--->>";
230                     timer1.Enabled = false;//暫停時鐘
231                 }
232                 else
233                 {
234                     lblResult.Text = "<<--抱歉,您的答復有誤!-->>";
235                 }
236             }
237         }
238 
239         #region 驗證確定按鈕包括的一系列辦法:反省計算用戶輸出表達式後果能否正確
240         //處置Deal謂詞表達式中的括號
241         private int Deal(string InputExp)
242         {
243             int result = 0;
244             while (InputExp.IndexOf(')') != -1)//判別能否存在括號 input.IndexOf(')') !=-1,標明存在括號
245             {
246                 //3*8÷(9-8)=24、(10+2)*(3-1)=24
247                 int rightLoc = InputExp.IndexOf(')');//右括號的地位
248                 string temp = InputExp.Substring(0, rightLoc);//從0(開端地位)到右括號的地位,不包括右括號(10+2
249                 int leftLoc = temp.LastIndexOf('(');//左括號的地位0
250                 string first = InputExp.Substring(0, leftLoc);//從0到左括號的地位,空
251                 string middle = InputExp.Substring(leftLoc + 1, rightLoc - leftLoc - 1);//括號兩頭的局部10+2
252                 string last = InputExp.Substring(rightLoc + 1);//右括號前面的局部*(3-1)
253                 //計算表達式的後果第二層
254                 InputExp = first + Formula(middle) + last; //""+10+2+*(3-1)留意:+表示銜接,銜接兩個字符串
255             }
256             //計算表達式的後果第二層
257             result = Formula(InputExp);//調用用戶輸出表達式反省、計算辦法,前往用戶輸出表達式的後果Formula:公式
258             return result;
259         }
260 
261         //最簡式運算 Formula:公式
262         private int Formula(string InputExp)
263         {
264             int length = InputExp.Length;//驗證表達式的長度
265             ArrayList OpeLoc = new ArrayList();//記載運算操作符地位   
266             ArrayList Ope = new ArrayList();//記載運算操作符 
267             ArrayList Value = new ArrayList();//記載數值內容 ,也就是記載輸出表達式的數字的值
268             int i;//全局變量i,運用於辦法體內每個循環
269             for (i = 0; i < length; i++)
270             {
271                 if (IsOperator(InputExp[i]))//反省獲判別一個符號能否是根本算符 
272                 {
273                     OpeLoc.Add(i);//記載並添加運算操作符地位x
274                     Ope.Add(InputExp[i]);//記載並添加運算操作符  
275                 }
276             }
277             if (OpeLoc.Count == 0)
278             {
279                 return int.Parse(InputExp);//處置無運算符的狀況
280             }
281             //計算表達式的後果第三層
282             RebuildOperator(ref OpeLoc, ref Ope);//對運算符停止重新組合,把負號和減號區分開來
283             if (!CheckFunction(OpeLoc, length))
284             {
285                 return 0;//反省功用,判別運算符組能否合法  ,也就是運算符地位能否正確
286             }
287             int j = 0;
288             for (i = 0; i < OpeLoc.Count; i++)
289             {
290                 Value.Add(int.Parse(InputExp.Substring(j, Convert.ToInt32(OpeLoc[i]) - j)));
291                 j = Convert.ToInt32(OpeLoc[i]) + 1;//最後一個數值的索引
292             }
293             //substring(開端索引,字符長度)
294             Value.Add(int.Parse(InputExp.Substring(j, length - j)));//處置最後一個數值的添加
295             //計算表達式的後果第四層
296             return Calculate(Ope, Value);//調用用戶輸出表達式的計算辦法,參數1:運算符,參數2:數值
297         }
298 
299         //處置四則混合運算等根底運算(+-*/)
300         private int Calculate(ArrayList Ope, ArrayList Values)
301         {
302             int i;//全局變量i,運用於辦法體內每個循環
303             for (i = 0; i < Ope.Count; i++)//處置乘法、除法 
304             {
305                 switch (Convert.ToChar(Ope[i]))
306                 {
307                     case '*':
308                         Values[i] = Convert.ToInt32(Values[i]) * Convert.ToInt32(Values[i + 1]);
309                         Values.RemoveAt(i + 1);
310                         Ope.RemoveAt(i);
311                         i--;
312                         break;
313                     case '/':
314                         Values[i] = Convert.ToInt32(Values[i]) * Convert.ToInt32(Values[i + 1]);
315                         Values.RemoveAt(i + 1);
316                         Ope.RemoveAt(i);
317                         i--;
318                         break;
319                 }
320             }
321             for (i = 0; i < Ope.Count; i++)//處置加法和減法 
322             {
323                 switch ((char)Ope[i])
324                 {
325                     case '+':
326                         Values[i] = Convert.ToInt32(Values[i]) + Convert.ToInt32(Values[i + 1]);
327                         Values.RemoveAt(i + 1);
328                         Ope.RemoveAt(i);
329                         i--;
330                         break;
331                     case '-':
332                         Values[i] = Convert.ToInt32(Values[i]) - Convert.ToInt32(Values[i + 1]); ;
333                         Values.RemoveAt(i + 1);
334                         Ope.RemoveAt(i);
335                         i--;
336                         break;
337                 }
338             }
339             return Convert.ToInt32(Values[0].ToString());
340         }
341 
342         //判別運算符組能否合法
343         private bool CheckFunction(ArrayList OpeLoc, int length)
344         {
345             if (Convert.ToInt32(OpeLoc[0]) == 0)//判別第一個運算符的的索引能否為0,也就是運算符排在表達式第一個
346                 return false;
347             int i;
348             for (i = 1; i < OpeLoc.Count; i++)
349             {
350                 if (Convert.ToInt32(OpeLoc[i]) - Convert.ToInt32(OpeLoc[i - 1]) == 1)//反省判別兩個運算符能否延續
351                     return false;
352             }
353             //判別最後一個運算符的的索引能否等於表達式索引的,也就是該運算符排在表達式末尾
354             if (Convert.ToInt32(OpeLoc[OpeLoc.Count - 1]) == length - 1)
355                 return false;
356             return true;
357         }
358         //對負號的處置和重構
359         private void RebuildOperator(ref ArrayList OpeLoc, ref ArrayList Ope)
360         {
361             ArrayList DelItem = new ArrayList();
362             if (Convert.ToInt32(OpeLoc[0].ToString()) == 0 && Convert.ToChar(Ope[0]) == '-')//判別第一個符號能否是負號  ,索引為0的符號
363             {
364                 DelItem.Add(0);
365             }
366             int i;
367             for (i = 1; i < OpeLoc.Count; i++)
368             {
369                 //判別能否有相鄰的算符且後一個是負號,且後一個運算符-前一個運算符==1
370                 if (Convert.ToChar(Ope[i]) == '-' && Convert.ToChar(Ope[i - 1]) != '-' && (Convert.ToInt32(OpeLoc[i]) - Convert.ToInt32(OpeLoc[i - 1])) != 1)
371                 {
372                     DelItem.Add(i);
373                 }
374             }
375             for (i = DelItem.Count - 1; i > 0; i--)//將負號和減號分開處置  
376             {
377                 //移除運算符和所在運算符所在地位
378                 Ope.RemoveAt(Convert.ToInt32(DelItem[i]));
379                 OpeLoc.RemoveAt(Convert.ToInt32(DelItem[i]));
380             }
381         }
382         //判別一個符號能否是根本算符 
383         private bool IsOperator(char c)
384         {
385             if (c == '+' || c == '-' || c == '*' || c == '/')
386                 return true;//判別能否是四則混合運算算符
387             else
388                 return false;
389         }
390         //反省輸出的計算公式能否有錯誤,牌能否有反復或則輸出有誤或輸出的牌超越四張
391         private bool CheckForNumber(string InputExp)//InputExp:用戶輸出的表達式如:(6*2)*(6/3)
392         {
393             bool result = true;
394             //先找出分隔符,再前往用戶輸出以這些分隔符分隔的的string類型數字數組
395             string[] str = InputExp.Split(new char[] { '+', '-', '*', '/', '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
396             if (str.Length != 4)
397             {
398                 MessageBox.Show("抱歉,輸出有誤!請重新輸出");
399                 result = false;
400                 return result;
401             }
402             int[] InputNums = new int[4];//用戶輸出計算表達式的數字
403             int[] CreatNums = { NumberA, NumberB, NumberC, NumberD };//生成的四張牌對應的數字,在生成牌時曾經賦值
404             Array.Sort(CreatNums);//排序:升序
405             for (int i = 0; i < 4; i++)
406             {
407                 InputNums[i] = Convert.ToInt32(str[i]);//用戶輸出的數字
408             }
409             Array.Sort(InputNums);//排序:升序
410             for (int i = 0; i < 4; i++)
411             {
412                 if (InputNums[i] != CreatNums[i])//判別生成的牌對應的數字與用戶輸出的數字能否逐個婚配,假如不婚配則標明牌有反復
413                 {
414                     result = false;
415                     MessageBox.Show("抱歉,每張牌只能運用一次!");
416                     return result;
417                 }
418             }
419             return result;
420         }
421 
422         #endregion
423 
424         //檢查答案按鈕
425         private void btnAnswer_Click(object sender, EventArgs e)
426         {
427 
428             int index = 1;//記載答案個數
429             #region 點擊檢查答案按鈕,輸出按鈕禁用,時鐘中止,清空答案欄
430             btnAdd.Enabled = false;
431             btnMinus.Enabled = false;
432             btnDivide.Enabled = false;
433             btnMulti.Enabled = false;
434             btnNumber1.Enabled = false;
435             btnNumber2.Enabled = false;
436             btnNumber3.Enabled = false;
437             btnNumber4.Enabled = false;
438             btnDelete.Enabled = false;
439             btnClear.Enabled = false;
440             btnLeft.Enabled = false;
441             btnRight.Enabled = false;
442             btnEnter.Enabled = false;
443             timer1.Enabled = false;//中止時鐘
444             txtAnswer.Text = "";//清空答案欄
445             #endregion
446             #region 首先:(ABCD地位)24種狀況的遍歷,然後:計算24點的辦法,接著:把字符表達式轉為數值表達式
447             for (int i = 1; i <= 24; i++)
448             {
449                 ChangeOfPosition24(i);//24種狀況的地位轉換的辦法
450                 ArrayList first = new ArrayList();//數字集合對象
451                 ArrayList firstStr = new ArrayList();//字符集合對象
452                 first.Add(A.ToString());
453                 firstStr.Add("A");
454                 //此辦法的中心思緒:原本一開端是有ABCD四張牌,第一次對A、B停止加減乘除,再把失掉的後果result前往去,第二次調用對result、C反復第一次操作
455                 //第三次也是反復,不過這次前往去的後果就是計算出來的後果
456                 cal(ref first, ref firstStr, B, 'B');
457                 cal(ref first, ref firstStr, C, 'C');
458                 cal(ref first, ref firstStr, D, 'D');
459 
460                 for (int j = 0; j < first.Count; j++)
461                 {
462                     if (Convert.ToInt32(Convert.ToDouble(first[j].ToString())) == 24)
463                     {
464                         //replaceString參數(字符表達式,'字符',數值),此辦法的中心思想是,一個一個字符交換為對應的數值
465                         firstStr[j] = replaceString(firstStr[j].ToString(), 'A', A);
466                         firstStr[j] = replaceString(firstStr[j].ToString(), 'B', B);
467                         firstStr[j] = replaceString(firstStr[j].ToString(), 'C', C);
468                         firstStr[j] = replaceString(firstStr[j].ToString(), 'D', D);
469                         //追加文本答案
470                         txtAnswer.AppendText("答案" + index + ": " + firstStr[j].ToString() + "=24;" + "\r\n");
471                         index++;
472                     }
473                 }
474             }
475             if (txtAnswer.Text.Trim() == "")
476             {
477                 txtAnswer.Text = "此題無解";
478             }
479             #endregion
480         }
481 
482         #region 點擊檢查答案按鈕要做的一系列處置計算
483         //1、(ABCD)24種狀況的地位轉換
484         public void ChangeOfPosition24(int i)
485         {
486             //24種地位轉換 
487             //此辦法的中心思想:要讓A/B/C/D四個數兩兩算一次,如:+加號運算符
488             //(A+B) (A+C) (A+D) (B+C) (B+D) (C+D)一共有6種狀況,以此類推減號也有6種狀況,
489             //加減乘除四種運算符加起來總共就有24種狀況
490             //補充:下面的意思是A在第一個地位有6種狀況,同理
491             //B在第一個地位也有6種狀況,C在第一個地位也有6種狀況,D在第一個地位也有6種狀況
492             switch (i)
493             {
494                 case 1:
495                     A = NumberA; B = NumberB; C = NumberC; D = NumberD;
496                     break;
497                 case 2:
498                     A = NumberA; B = NumberB; D = NumberC; C = NumberD;
499                     break;
500                 case 3:
501                     A = NumberA; C = NumberB; B = NumberC; D = NumberD;
502                     break;
503                 case 4:
504                     A = NumberA; C = NumberB; D = NumberC; B = NumberD;
505                     break;
506                 case 5:
507                     A = NumberA; D = NumberB; B = NumberC; C = NumberD;
508                     break;
509                 case 6:
510                     A = NumberA; D = NumberB; C = NumberC; B = NumberD;
511                     break;
512                 case 7:
513                     B = NumberA; A = NumberB; C = NumberC; D = NumberD;
514                     break;
515                 case 8:
516                     B = NumberA; A = NumberB; D = NumberC; C = NumberD;
517                     break;
518                 case 9:
519                     B = NumberA; C = NumberB; A = NumberC; D = NumberD;
520                     break;
521                 case 10:
522                     B = NumberA; C = NumberB; D = NumberC; A = NumberD;
523                     break;
524                 case 11:
525                     B = NumberA; D = NumberB; A = NumberC; C = NumberD;
526                     break;
527                 case 12:
528                     B = NumberA; D = NumberB; C = NumberC; A = NumberD;
529                     break;
530                 case 13:
531                     C = NumberA; A = NumberB; B = NumberC; D = NumberD;
532                     break;
533                 case 14:
534                     C = NumberA; A = NumberB; D = NumberC; B = NumberD;
535                     break;
536                 case 15:
537                     C = NumberA; B = NumberB; A = NumberC; D = NumberD;
538                     break;
539                 case 16:
540                     C = NumberA; B = NumberB; D = NumberC; A = NumberD;
541                     break;
542                 case 17:
543                     C = NumberA; D = NumberB; A = NumberC; B = NumberD;
544                     break;
545                 case 18:
546                     C = NumberA; D = NumberB; B = NumberC; A = NumberD;
547                     break;
548                 case 19:
549                     D = NumberA; A = NumberB; B = NumberC; C = NumberD;
550                     break;
551                 case 20:
552                     D = NumberA; A = NumberB; C = NumberC; B = NumberD;
553                     break;
554                 case 21:
555                     D = NumberA; B = NumberB; A = NumberC; C = NumberD;
556                     break;
557                 case 22:
558                     D = NumberA; B = NumberB; C = NumberC; A = NumberD;
559                     break;
560                 case 23:
561                     D = NumberA; C = NumberB; A = NumberC; B = NumberD;
562                     break;
563                 case 24:
564                     D = NumberA; C = NumberB; B = NumberC; A = NumberD;
565                     break;
566             }
567         }
568 
569         //2、24點計算辦法(加減乘除)
570         //留意:ref:傳入傳出,out:傳出
571         //此辦法的中心思緒:原本一開端是有ABCD四張牌,第一次對A、B停止加減乘除,再把失掉的後果result前往去,第二次調用對result、C反復第一次操作
572         //第三次也是反復,不過這次前往去的後果就是計算出來的後果
573         private void cal(ref ArrayList num, ref ArrayList numStr, int num2, char num2Str)//傳入參數A=6,"A",B=4,"B"
574         {
575             ArrayList newNum = new ArrayList();//數值集合對象
576             ArrayList newNumStr = new ArrayList();//字符集合對象
577             int temp;
578             for (int i = 0; i < num.Count; i++)
579             {
580                 int num1 = Convert.ToInt32(num[i].ToString());
581 
582                 #region 加法的狀況
583                 temp = num1 + num2;
584                 newNum.Add(temp.ToString());//數字:6+4
585                 newNumStr.Add(numStr[i].ToString() + "+" + num2Str);//字符A+B
586                 #endregion
587 
588                 #region 減法的狀況
589                 if (num1 > num2)
590                 {
591                     temp = num1 - num2;
592                     newNum.Add(temp.ToString());//數字:6-4
593                     newNumStr.Add(numStr[i].ToString() + "-" + num2Str);//字符A-B
594                 }
595                 else
596                 {
597                     temp = num2 - num1;
598                     newNum.Add(temp.ToString());
599                     //反省能否存在+-運算符,若查找前往索引的後果不等於-1,表示存在+-運算符
600                     if (numStr[i].ToString().IndexOf('+') != -1 || numStr[i].ToString().IndexOf('-') != -1)
601                     {
602                         newNumStr.Add(num2Str + "-" + "(" + numStr[i].ToString() + ")");//B-(A)
603                     }
604                     else
605                     {
606                         newNumStr.Add(num2Str + "-" + numStr[i].ToString());//B-A
607                     }
608                 }
609                 #endregion
610 
611                 #region 乘法的狀況
612                 temp = num1 * num2;
613                 newNum.Add(temp.ToString());
614                 //應用IndexOf()反省能否有+-運算符-1:指的是沒有
615                 if (numStr[i].ToString().IndexOf("+") == -1 && numStr[i].ToString().IndexOf("-") == -1)
616                 {
617                     newNumStr.Add(numStr[i].ToString() + "*" + num2Str);//A*B
618                 }
619                 else
620                 {
621                     newNumStr.Add("(" + numStr[i].ToString() + ")" + "*" + num2Str);//(A+B)*C
622                 }
623                 #endregion
624 
625                 #region 除法的狀況
626                 if (num1 > num2)
627                 {
628                     if (num2 != 0 && num1 % num2 == 0)//除數不為0,而且兩數相除余數要為0,也就是要能整除
629                     {
630                         temp = num1 / num2;
631                         newNum.Add(temp.ToString());
632                         if (numStr[i].ToString().IndexOf("+") == -1 && numStr[i].ToString().IndexOf("-") == -1)
633                         {
634                             newNumStr.Add(numStr[i].ToString() + "/" + num2Str);//A/B
635                         }
636                         else
637                         {
638                             newNumStr.Add("(" + numStr[i].ToString() + ")" + "/" + num2Str);//(A+B)/C
639                         }
640                     }
641                 }
642                 else
643                 {
644                     if (num1 != 0 && num2 % num1 == 0)
645                     {
646                         temp = num2 / num1;
647                         newNum.Add(temp.ToString());
648                         if (numStr[i].ToString().IndexOf("+") == -1 && numStr[i].ToString().IndexOf("-") == -1)
649                         {
650                             newNumStr.Add(num2Str + "/" + numStr[i].ToString());
651                         }
652                         else
653                         {
654                             newNumStr.Add(num2Str + "/" + "(" + numStr[i].ToString() + ")");
655                         }
656                     }
657                 }
658                 #endregion
659             }
660             //要前往的集合後果
661             num = newNum;
662             numStr = newNumStr;
663         }
664 
665         //3、用數值表達式交換字符串表達式的辦法,此辦法的中心思想是,一個一個字符交換為對應的數值
666         private object replaceString(string ExpressionStr, char NumStr, int Num)
667         {
668             //參數(字符表達式=(A-B)*C+D,'字符'=A,數值=5)=>數值表達式=(13-12)*8+3
669             int loc = ExpressionStr.IndexOf(NumStr);
670             string first = ExpressionStr.Substring(0, loc);
671             ExpressionStr = first + Convert.ToInt16(Num) + ExpressionStr.Substring(loc + 1);
672             return ExpressionStr;
673         }
674 
675         #endregion
676 
677         //點擊下一輪按鈕
678         private void btnNext_Click(object sender, EventArgs e)
679         {
680             #region 點擊下一輪按鈕更新初始化數據
681             btnAdd.Enabled = true;
682             btnMinus.Enabled = true;
683             btnDivide.Enabled = true;
684             btnMulti.Enabled = true;
685             btnNumber1.Enabled = true;
686             btnNumber2.Enabled = true;
687             btnNumber3.Enabled = true;
688             btnNumber4.Enabled = true;
689             btnDelete.Enabled = true;
690             btnClear.Enabled = true;
691             btnLeft.Enabled = true;
692             btnRight.Enabled = true;
693             btnEnter.Enabled = true;
694             lblInput.Text = "";
695             txtAnswer.Text = "";
696             lblResult.Visible = false;
697             lblShowTime.Text = "";
698             timer1.Enabled = true;
699             beginTime = DateTime.Now;
700             #endregion
701 
702             int imageNum;
703             string path;
704             //畫第一張牌
705             if (topCard >= 52)
706             {
707                 MessageBox.Show("祝賀你已算完好副牌,開端新的一副牌。");
708                 topCard = 0;
709                 Shuffle();//洗牌
710             }
711             topCard = topCard + 1;
712             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
713             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
714             pictureBox1.Image = Image.FromFile(path);
715             NumberA = Convert.ToInt32(PlayingCards[topCard].face);
716             btnNumber1.Text = NumberA.ToString();
717             //畫第二張牌
718             if (topCard >= 52)
719             {
720                 MessageBox.Show("祝賀你已算完好副牌,開端新的一副牌。");
721                 topCard = 0;
722                 Shuffle();
723             }
724             topCard = topCard + 1;
725             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
726             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
727             pictureBox2.Image = Image.FromFile(path);
728             NumberB = Convert.ToInt32(PlayingCards[topCard].face);
729             btnNumber2.Text = NumberB.ToString();
730             //畫第三張牌
731             if (topCard >= 52)
732             {
733                 MessageBox.Show("祝賀你已算完好副牌,開端新的一副牌。");
734                 topCard = 0;
735                 Shuffle();
736             }
737             topCard = topCard + 1;
738             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
739             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
740             pictureBox3.Image = Image.FromFile(path);
741             NumberC = Convert.ToInt32(PlayingCards[topCard].face);
742             btnNumber3.Text = NumberC.ToString();
743             //畫第四張牌
744             if (topCard >= 52)
745             {
746                 MessageBox.Show("祝賀你已算完好副牌,開端新的一副牌。");
747                 topCard = 0;
748                 Shuffle();
749             }
750             topCard = topCard + 1;
751             imageNum = PlayingCards[topCard].suit + (PlayingCards[topCard].face - 1) * 4;
752             path = Directory.GetCurrentDirectory() + @"\images\" + imageNum.ToString() + ".bmp";
753             pictureBox4.Image = Image.FromFile(path);
754             NumberD = Convert.ToInt32(PlayingCards[topCard].face);
755             btnNumber4.Text = NumberD.ToString();
756         }
757 
758         //計時器
759         private void timer1_Tick(object sender, EventArgs e)
760         {
761             TimeSpan ts = DateTime.Now - beginTime;
762             lblShowTime.Text = "用時:" + ts.Minutes + "分" + ts.Seconds.ToString() + "秒";
763             if (ts.Seconds == 30|ts.Seconds==59)
764             {
765                 MessageBox.Show("我等到花兒都謝了,怎樣還沒算出來呀,需求協助的話就點擊檢查答案哦!!!", "時間正告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
766                 lblShowTime.ForeColor = Color.Red;
767             }
768         }
769     }
770 }
View Code 三、示例下載

GitHub:https://github.com/SeeYouBug2/twenty-four-Algorithm-Game.git

總結:前段時間由於閒著無聊,於是乎,就想了一下,必需找點事情來做。於是在上網閱讀網頁時不經意間看到了這個24點算法小游戲,然後就玩了一下,忽然發現有種找回童年的覺得,由於自己童年的時分很喜歡玩24點算法游戲,對它十分感興味,在家的時分就喜歡跟我大嫂和我表弟一同玩24點算法游戲,在學校就和同窗一同玩,玩的還很happy,所以我玩24點算法游戲還是玩的挺多的,於是腦子裡就蹦出來這樣一個想法,這個24點算法游戲它是如何完成的呢?自己能否也做一個出來呢?順著這個想法我就上網查找了一些材料,然後就開端著手做了起來,整了半天,終於把它給整完了。總結一下這個24點游戲的中心內容就是運用到了遞歸算法和驗證表達式等相關知識。啰嗦了那麼多最後我總結分享一句話給大家:“興味是你的最好教師,不論做任何事情,你都要尋覓自己的興味點,跟著自己的興味走,你會學的更好,學的更深,學編程也不例外”。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved