使用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

 =================================贼好看的分割线=============

最终效果:

 

posted @ 2019-01-15 15:04  qwert13771  阅读(1548)  评论(0编辑  收藏  举报