使用C#控制台應用程序完成一個2048小游戲


曾經使用C#控制台應用程序寫的一個2048,現在翻出來回顧一下

  • Box類是2048中每一個小格子的相關信息,包括格子的橫縱坐標、格子的值和格子是否剛合並這些信息。
  • Grid類是網格的相關信息,包括網格的長寬(默認是4X4,也可以改成其他形式的),分數等。
  • Manager2048類是個大雜燴的類,寫的很亂,什么亂七八糟的方法都丟在了里面。

 =================================賊好看的分割線=============

Program.CS

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _031_test
 8 {
 9     /// <summary>
10     /// 2048
11     /// </summary>
12     class Program
13     {
14         static void Main(string[] args)
15         {
16             Manager2048 m2048 = new Manager2048();
17             m2048.Strat();
18             m2048.Control();
19 
20 
21             Console.ReadLine();
22         }
23     }
24 }
Program.CS

Box.CS

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 
 7 namespace _031_test
 8 {
 9     /// <summary>
10     /// 格子
11     /// </summary>
12     class Box
13     {
14         //格子的坐標
15         int row;
16         int col;
17         public int Row { get { return row; } }
18         public int Col { get { return col; } }
19         //格子的值
20         public int Value { get; set; }
21         //是否已經合並
22         public bool IsMerge { get; set; }
23 
24         public Box(int row,int col)
25         {
26             this.row = row;
27             this.col = col;
28             //初始化默認值為0
29             this.Value = 0;
30             this.IsMerge = false;
31         }
32 
33 
34     }
35 }
Box.CS

Grid.CS

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.IO;
  7 
  8 namespace _031_test
  9 {
 10     /// <summary>
 11     /// 網格
 12     /// </summary>
 13     class Grid
 14     {
 15         //網格的長寬
 16         int rows;
 17         int cols;
 18         public int Rows { get { return rows; } }
 19         public int Cols { get { return cols; } }
 20 
 21         public int score;
 22 
 23         public int randomTimes = 0;//判斷游戲是否結束的標識位16結束
 24         Random random;
 25         //存放格子對象
 26         public Box[,] bList;
 27         //是否是第一次,第一次則出現兩個數,否則只出現一個數
 28         bool isFirst = true;
 29 
 30         public Grid(int rows, int cols)
 31         {
 32             this.random = new Random();
 33             this.rows = rows < 4 ? 4 : rows;
 34             this.cols = cols < 4 ? 4 : cols;
 35             bList = new Box[rows, cols];
 36         }
 37 
 38         //初始化
 39         public void InitGrid()
 40         {
 41             //對網格中的每一個格子進行初始化,並將每一個格子對象存入bList中
 42             for (int i = 0; i < bList.GetLength(0); i++)
 43             {
 44                 for (int j = 0; j < bList.GetLength(1); j++)
 45                 {
 46                     Box box = new Box(i, j);
 47                     bList[i, j] = box;
 48                 }
 49             }
 50             RandomNum();
 51         }
 52         ///////////////////////////////////
 53         //隨機---包括生成的數字和位置
 54         public void RandomNum()
 55         {
 56             //count表示要生成的數字的個數,進行判斷,初始化時候生成兩個,否則就一個
 57             int count;
 58             if (isFirst) { count = 2; isFirst = false; }
 59             else count = 1;
 60 
 61             int i = 0;
 62             while (i < count)
 63             {
 64                 //隨機出現數字的下標
 65                 int r = random.Next(0, rows);
 66                 int c = random.Next(0, cols);
 67                 //若隨機到的位置已經有值了,則返回重新隨機
 68                 if (bList[r, c].Value != 0) continue;
 69                 //隨機2和4   出現幾率  80%   20%
 70                 int valuePercent = random.Next(1, 11);
 71                 //將出現的值
 72                 int value;
 73                 if (valuePercent < 9) value = 2;
 74                 else value = 4;
 75                 bList[r, c].Value = value;
 76                 i++;
 77                 //當randomTimes到16時說明所有格子都滿了
 78                 randomTimes++;
 79             }
 80         }
 81 
 82         //顯示游戲界
 83         public void DisPlay()
 84         {
 85             Console.WriteLine("===============================");
 86             for (var i = 0; i < bList.GetLength(0); i++)
 87             {
 88                 for (var j = 0; j < bList.GetLength(1); j++)
 89                 {
 90                     Console.Write(bList[i, j].Value + "\t");
 91                 }
 92                 Console.WriteLine("\n");
 93             }
 94             Console.WriteLine("===============================");
 95             Console.WriteLine("當前分數:" + score + "歷史最高:" + Int32.Parse(File.ReadAllText("score.txt")));
 96         }
 97 
 98 
 99 
100     }
101 }
Grid.CS

Manager2048.CS

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.IO;
  7 
  8 namespace _031_test
  9 {
 10     /// <summary>
 11     /// 控制器
 12     /// </summary>
 13     class Manager2048
 14     {
 15         Grid g;
 16 
 17         public Manager2048()
 18         {
 19             g = new Grid(4, 4);
 20         }
 21 
 22         //開始游戲
 23 
 24         public void Strat()
 25         {
 26             g.InitGrid();
 27             g.DisPlay();
 28             Console.WriteLine("游戲開始,請直接使用方向鍵進行操作");
 29         }
 30 
 31         public void Control()
 32         {
 33             while (true)
 34             {
 35                 //ConsoleKeyInfo可以直接接受一個字符不需要再按下回車鍵確認
 36                 ConsoleKeyInfo keyInfo = Console.ReadKey();
 37                 switch (keyInfo.Key)
 38                 {
 39                     case ConsoleKey.UpArrow: Up(); break;
 40                     case ConsoleKey.DownArrow: Down(); break;
 41                     case ConsoleKey.LeftArrow: Left(); break;
 42                     case ConsoleKey.RightArrow: Right(); break;
 43                     default: Console.WriteLine("按錯了"); break;
 44                 }
 45                 if (g.randomTimes==g.Rows*g.Cols&&!CanWeMergeInFull())
 46                 {
 47                     Console.WriteLine("游戲結束");
 48                     break;
 49                 }
 50             }
 51         }
 52 
 53         public void Up()
 54         {
 55             bool ismove=false;
 56             //遍歷每一個box,檢測該box是否要移動
 57             for (int i = 1; i < g.bList.GetLength(0); i++)//向上移動不需要考慮第一行的上移,所以直接i=1
 58             {
 59                 for (int j = 0; j < g.bList.GetLength(1); j++)
 60                 {
 61                     //如果該box值不是0,說明該box需要移動,否則繼續遍歷下一個box
 62                     if (g.bList[i, j].Value != 0)
 63                     {
 64                         int temp = g.bList[i, j].Value;
 65                         //從該box的上一行開始一直遍歷到最頂上
 66                         int k = i - 1;
 67                         while (k >= 0)
 68                         {
 69                             if (g.bList[k, j].Value != 0 || k == 0) break;
 70                             else k--;
 71                         }
 72                         //如果碰到了和要移動的box值一樣的box,就要把他們合並(IsMerge:當這個box是這一輪合並來的box時,則不能合並)
 73                         if (temp == g.bList[k, j].Value && g.bList[k, j].IsMerge==false)
 74                         {
 75                             g.bList[i, j].Value = 0;
 76                             g.bList[k, j].Value = temp * 2;
 77                             g.score += temp * 2;
 78                             if (g.score > Int32.Parse(File.ReadAllText("score.txt")))
 79                             {
 80                                 File.WriteAllText("score.txt", g.score.ToString());
 81                             }
 82                             g.bList[k, j].IsMerge = true;
 83                             g.randomTimes--;
 84                             ismove = true;
 85                         }
 86                         else if (temp == g.bList[k, j].Value && g.bList[k, j].IsMerge==true)
 87                         {
 88                             g.bList[i, j].Value = 0;
 89                             g.bList[k + 1, j].Value = temp;
 90                             //i=k+1表示該box並沒有移動
 91                             if (i == k + 1) ismove = false;
 92                             else ismove = true;
 93                         }
 94                         //值不一樣的時候,就把要移動的box放到這個box下面去
 95                         else if (g.bList[k, j].Value != 0)
 96                         {
 97                             g.bList[i, j].Value = 0;
 98                             g.bList[k + 1, j].Value = temp;
 99                             if (i == k + 1) ismove = false;
100                             else ismove = true;
101                         }
102                         //這種情況是遍歷到最頂行的box且該box為0時,直接把要動的box移到這
103                         else
104                         {
105                             g.bList[i, j].Value = 0;
106                             g.bList[k, j].Value = temp;
107                             if (i == k) ismove = false;
108                             else ismove = true;
109                         }
110                     }
111                 }
112             }
113             if (ismove && !IsFull()) g.RandomNum();//當所有格子都滿了時就不隨機生成數字
114             else Console.WriteLine("該方向無法移動");
115             ResetIsMerge();//重置所有box的合並狀態為false
116             g.DisPlay();
117         }
118 
119         public void Down()
120         {
121             bool ismove = false;
122             //錯誤寫法:for (int i = 0; i < g.bList.GetLength(0) - 1; i++)
123             //以上寫法會導致上層的數先被遍歷從而導致先移動完畢,所以要從最后一個數開始遍歷
124             for (int i = g.bList.GetLength(0) - 2; i >= 0; i--)
125             {
126                 for (int j = g.bList.GetLength(1) - 1; j >= 0; j--)
127                 {
128                     if (g.bList[i, j].Value != 0)
129                     {
130                         int temp = g.bList[i, j].Value;
131                         int k = i + 1;
132                         while (k <= g.bList.GetLength(0) - 1)
133                         {
134                             if (g.bList[k, j].Value != 0 || k == g.bList.GetLength(0) - 1) break;
135                             else k++;
136                         }
137                         if (temp == g.bList[k, j].Value && g.bList[k, j].IsMerge == false)
138                         {
139                             g.bList[i, j].Value = 0;
140                             g.bList[k, j].Value = temp * 2;
141                             g.bList[k, j].IsMerge = true;
142                             g.score += temp * 2;
143                             if (g.score > Int32.Parse(File.ReadAllText("score.txt")))
144                             {
145                                 File.WriteAllText("score.txt", g.score.ToString());
146                             }
147                             g.randomTimes--;
148                             ismove = true;
149                         }
150                         else if (temp == g.bList[k, j].Value && g.bList[k, j].IsMerge == true)
151                         {
152                             g.bList[i, j].Value = 0;
153                             g.bList[k - 1, j].Value = temp;
154                             if (i == k - 1) ismove = false;
155                             else ismove = true;
156                         }
157                         else if (g.bList[k, j].Value != 0)
158                         {
159                             g.bList[i, j].Value = 0;
160                             g.bList[k - 1, j].Value = temp;
161                             if (i == k - 1) ismove = false;
162                             else ismove = true;
163                         }
164                         else
165                         {
166                             g.bList[i, j].Value = 0;
167                             g.bList[k, j].Value = temp;
168                             if (i == k) ismove = false;
169                             else ismove = true;
170                         }
171                     }
172                 }
173             }
174             if (ismove && !IsFull()) g.RandomNum();
175             else Console.WriteLine("該方向無法移動");
176             ResetIsMerge();
177             g.DisPlay();
178         }
179 
180         public void Left()
181         {
182             bool ismove = false;
183             for (int i = 0; i < g.bList.GetLength(0); i++)
184             {
185                 for (int j = 1; j < g.bList.GetLength(1); j++)
186                 {
187                     if (g.bList[i, j].Value != 0)
188                     {
189                         int temp = g.bList[i, j].Value;
190                         int k = j - 1;
191                         while (k >= 0)
192                         {
193                             if (g.bList[i, k].Value != 0 || k == 0) break;
194                             else k--;
195                         }
196                         if (temp == g.bList[i, k].Value && g.bList[i, k].IsMerge == false)
197                         {
198                             g.bList[i, j].Value = 0;
199                             g.bList[i, k].Value = temp * 2;
200                             g.score += temp * 2;
201                             if (g.score > Int32.Parse(File.ReadAllText("score.txt")))
202                             {
203                                 File.WriteAllText("score.txt", g.score.ToString());
204                             }
205                             g.bList[k, j].IsMerge = true;
206                             g.randomTimes--;
207                             ismove = true;
208                         }
209                         else if (temp == g.bList[i, k].Value && g.bList[i, k].IsMerge == true)
210                         {
211                             g.bList[i, j].Value = 0;
212                             g.bList[i, k + 1].Value = temp;
213                             if (j == k + 1) ismove = false;
214                             else ismove = true;
215                         }
216                         else if (g.bList[i, k].Value != 0)
217                         {
218                             g.bList[i, j].Value = 0;
219                             g.bList[i, k + 1].Value = temp;
220                             if (j == k + 1) ismove = false;
221                             else ismove = true;
222                         }
223                         else
224                         {
225                             g.bList[i, j].Value = 0;
226                             g.bList[i, k].Value = temp;
227                             if (j == k) ismove = false;
228                             else ismove = true;
229                         }
230                     }
231                 }
232             }
233             if (ismove && !IsFull()) g.RandomNum();
234             else Console.WriteLine("該方向無法移動");
235             ResetIsMerge();
236             g.DisPlay();
237         }
238 
239         public void Right()
240         {
241             bool ismove = false;
242             //錯誤寫法:for (int i = 0; i < g.bList.GetLength(0) - 1; i++)
243             //以上寫法會導致上層的數先被遍歷從而導致先移動完畢,所以要從最后一個數開始遍歷
244             for (int i = g.bList.GetLength(0) - 1; i >= 0; i--)
245             {
246                 for (int j = g.bList.GetLength(1) - 2; j >= 0; j--)
247                 {
248                     if (g.bList[i, j].Value != 0)
249                     {
250                         int temp = g.bList[i, j].Value;
251                         int k = j + 1;
252                         while (k <= g.bList.GetLength(1) - 1)
253                         {
254                             if (g.bList[i, k].Value != 0 || k == g.bList.GetLength(1) - 1) break;
255                             else k++;
256                         }
257                         if (temp == g.bList[i, k].Value && g.bList[i, k].IsMerge == false)
258                         {
259                             g.bList[i, j].Value = 0;
260                             g.bList[i, k].Value = temp * 2;
261                             g.score += temp * 2;
262                             if (g.score > Int32.Parse(File.ReadAllText("score.txt")))
263                             {
264                                 File.WriteAllText("score.txt", g.score.ToString());
265                             }
266                             g.bList[k, j].IsMerge = true;
267                             g.randomTimes--;
268                             ismove = true;
269                         }
270                         else if (temp == g.bList[i, k].Value && g.bList[i, k].IsMerge == true)
271                         {
272                             g.bList[i, j].Value = 0;
273                             g.bList[i, k - 1].Value = temp;
274                             if (j == k - 1) ismove = false;
275                             else ismove = true;
276                         }
277                         else if (g.bList[i, k].Value != 0)
278                         {
279                             g.bList[i, j].Value = 0;
280                             g.bList[i, k - 1].Value = temp;
281                             if (j == k - 1) ismove = false;
282                             else ismove = true;
283                         }
284                         else
285                         {
286                             g.bList[i, j].Value = 0;
287                             g.bList[i, k].Value = temp;
288                             if (j == k) ismove = false;
289                             else ismove = true;
290                         }
291                     }
292                 }
293             }
294             if (ismove && !IsFull()) g.RandomNum();
295             else Console.WriteLine("該方向無法移動");
296             ResetIsMerge();
297             g.DisPlay();
298         }
299 
300         //判斷網格是否已滿
301         public bool IsFull()
302         {
303             for (int i = 0; i < g.Rows; i++)
304             {
305                 for (int j = 0; j < g.Cols; j++)
306                 {
307                     if (g.bList[i, j].Value == 0)
308                     {
309                         return false;
310                     }
311                 }
312             }
313             return true;
314         }
315 
316         //重置所有box合並狀態
317         public void ResetIsMerge()
318         {
319             for (int i = 0; i < g.Rows; i++)
320             {
321                 for (int j = 0; j < g.Cols; j++)
322                 {
323                     g.bList[i, j].IsMerge = false;
324                 }
325             }
326         }
327 
328         //網格滿時是否還可以繼續合並 true表示還有能合並的
329         public bool CanWeMergeInFull()
330         {
331             for (int i = 0; i < g.Rows; i++)
332             {
333                 for (int j = 0; j < g.Cols; j++)
334                 {
335                     //檢測上方向
336                     if (i - 1 >= 0 && g.bList[i, j].Value == g.bList[i - 1, j].Value)
337                     {
338                         return true;
339                     }
340                     //檢測下方向
341                     if (i + 1 < g.Rows && g.bList[i, j].Value == g.bList[i + 1, j].Value)
342                     {
343                         return true; 
344                     }
345                     //檢測左方向
346                     if (j - 1 >= 0 && g.bList[i, j].Value == g.bList[i, j - 1].Value)
347                     {
348                         return true;
349                     }
350                     //檢測右方向
351                     if (j + 1 < g.Cols && g.bList[i, j].Value == g.bList[i, j + 1].Value)
352                     {
353                         return true;
354                     }
355                 }
356             }
357             return false;
358         }
359 
360     }
361 }
Manager2048.CS

 =================================賊好看的分割線=============

最終效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM