2048游戲現(xiàn)在很火啊,很多人應(yīng)該已經(jīng)玩過(guò)了。在博客園上也看見(jiàn)有人模仿做的GDI+版 2048游戲,鄙人暫且不做那么多動(dòng)畫(huà)的東西,畢竟是個(gè)小東東,在此奉上一個(gè)《控制臺(tái)版2048》。
本文程序源碼下載:http://pan.baidu.com/s/1mg8zntu
程序結(jié)構(gòu)相對(duì)簡(jiǎn)單,一共200+行代碼,注釋很少,大家大概也看得懂,我在這解釋下程序中各個(gè)方法的含義:Main 方法程序入口,RePaint 類似Win32程序中的刷新界面,SquareRot90 矩形矩陣順時(shí)針旋轉(zhuǎn)90度角(參數(shù)可以為負(fù),表示逆時(shí)針)。Merge 向左移動(dòng),合并單元格中值相同的元素,并進(jìn)行整理(將所有元素靠左放置)RandomPoint 隨機(jī)生成點(diǎn),從矩陣的空位置(值為0)中隨機(jī)生成一個(gè)點(diǎn),若不存在空位置返回null。CanMove 判斷是否可以繼續(xù)移動(dòng),也是判斷游戲是否結(jié)束的方法。IsEquals 判斷兩矩陣的值是否相同。CopyToB 將矩陣復(fù)制一份。流程圖如下:

上代碼主函數(shù)Mainstatic void Main(string[] args){ int[,] a = new int[4, 4]; a[1, 2] = 2; a[2, 2] = 2; a[2, 1] = 2; RePaint(a); while (true) { ConsoleKeyInfo key = Console.ReadKey(); switch (key.Key) { case ConsoleKey.UpArrow: a = SquareRot90(a, 3); a = Merge(a); a = SquareRot90(a, -3); break; case ConsoleKey.DownArrow: a = SquareRot90(a, 1); a = Merge(a); a = SquareRot90(a, -1); break; case ConsoleKey.LeftArrow: a = Merge(a); break; case ConsoleKey.RightArrow: a = SquareRot90(a, 2); a = Merge(a); a = SquareRot90(a, -2); break; } Point cp = RandomPoint(a); if (cp != null) { a[cp.X, cp.Y] = 2; RePaint(a); } if (cp == null && !CanMove(a)) { RePaint(a, "Game Over"); } }}矩陣旋轉(zhuǎn)方法
/// 矩形順時(shí)針旋轉(zhuǎn)90°/// </summary>/// <param name="rotNum">旋轉(zhuǎn)次數(shù)</param>public static int[,] SquareRot90(int[,] a, int rotNum){ while (rotNum < 0) { rotNum += 4; } for (int rot_i = 0; rot_i < rotNum; rot_i++) { int[,] b = new int[a.GetLength(1), a.GetLength(0)]; for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j < a.GetLength(1); j++) { b[j, a.GetLength(0) - i - 1] = a[i, j]; } } a = b; } return a;}隨機(jī)點(diǎn)方法
public static Point RandomPoint(int[,] a){ List<Point> lstP = new List<Point>(); for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j < a.GetLength(1); j++) { if (a[i, j] == 0) { lstP.Add(new Point(i, j)); } } } if (lstP.Count == 0) { return null; } int rnd = new Random().Next(lstP.Count); return lstP[rnd];}矩陣向左合成方法
public static int[,] Merge(int[,] a){ for (int i = 0; i < a.GetLength(0); i++) { int lastNum = 0; int last_j = 0; for (int j = 0; j < a.GetLength(1); j++)//合并 { if (lastNum != a[i, j] && a[i, j] != 0) { lastNum = a[i, j]; last_j = j; } else if (lastNum == a[i, j]) { a[i, last_j] = 0; a[i, j] = lastNum + a[i, j]; } } last_j = 0; for (int j = 0; j < a.GetLength(1); j++)//整理 { if (a[i, j] != 0) { a[i, last_j] = a[i, j]; if (last_j != j) a[i, j] = 0; last_j++; } } } return a;}是否可以繼續(xù)移動(dòng)CanMove方法
public static bool CanMove(int[,] a){ bool res = false; int[,] b = CopyToB(a); b = Merge(b); if (!IsEquals(a, b)) res = true; b = CopyToB(a); b = SquareRot90(b, 1); b = Merge(b); b = SquareRot90(b, -1); if (!IsEquals(a, b)) res = true; b = CopyToB(a); b = SquareRot90(b, 2); b = Merge(b); b = SquareRot90(b, -2); if (!IsEquals(a, b)) res = true; b = CopyToB(a); b = SquareRot90(b, 3); b = Merge(b); b = SquareRot90(b, -3); if (!IsEquals(a, b)) res = true; return res;}CanMove中用到的IsEquals方法,判斷矩陣相等
public static bool IsEquals(int[,] a, int[,] b){ bool res = true; for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j < a.GetLength(1); j++) { if (b[i, j] != a[i, j]) { res = false; break; } } if (!res) break; } return res;}CanMove中用到的矩陣復(fù)制方法CopyToB
public static int[,] CopyToB(int[,] a){ int[,] b = new int[a.GetLength(0), a.GetLength(1)]; for (int i = 0; i < a.GetLength(0); i++) { for (int j = 0; j < a.GetLength(1); j++) { b[i, j] = a[i, j]; } } return b;}兩個(gè)RePain方法,重新打印,前面的表示GameOver
public static void RePaint(int[,] a, string s){ while (true) { Console.Clear(); RePaint(a); Console.WriteLine("/n/n/n/n/t/t" + s + "/n/n"); Console.ReadKey(); }}public static void RePaint(int[,] a){ Console.Clear(); for (int j = 0; j < a.GetLength(1); j++) { Console.Write("───"); } Console.Write("/n"); for (int i = 0; i < a.GetLength(0); i++) { Console.Write("│"); for (int j = 0; j < a.GetLength(1); j++) { string s = ""; if (a[i, j] == 0) s = " "; else if (a[i, j] < 10) s = " " + a[i, j] + " "; else if (a[i, j] < 100) s = "" + a[i, j] + " "; else s = "" + a[i, j]; Console.Write(s + "│"); } Console.Write("/n"); for (int j = 0; j < a.GetLength(1); j++) { Console.Write("───"); } Console.Write("/n"); }}輔助類Point
class Point{ public Point(int x, int y) { this.X = x; this.Y = y; } public int X { get; set; } public int Y { get; set; }}結(jié)束語(yǔ) 其實(shí)要寫(xiě)一個(gè)游戲并不是像想像中那么容易,要處理算法等問(wèn)題,必須要事先仔細(xì)的設(shè)計(jì),需要一張草紙作為設(shè)計(jì)圖,這樣會(huì)讓工作效率大大提高。之前貼過(guò)畢設(shè)的游戲《保衛(wèi)蘿卜》,由于時(shí)間關(guān)系遲遲沒(méi)有整理,等畢設(shè)答辯完成后,一定好好整理,給大家分享。現(xiàn)在功能基本完成了,在這先貼一個(gè)縮減版的游戲程序,鏈接:http://pan.baidu.com/s/1sjvxO7N。程序有什么問(wèn)題、BUG,希望大家多多留言。源碼整理后再上傳。 過(guò)幾天是藍(lán)橋杯比賽,哈哈,北京我來(lái)了。本文程序源碼下載:http://pan.baidu.com/s/1mg8zntu
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注