C#實現2048小遊戲
阿新 • • 發佈:2019-02-11
要實現這個簡單的小遊戲主要在於實現一個方向移動
數字的移動及合併該如何處理
然後其它方向的邏輯是相同的
我做的這個基本功能實現了
主要分為三個類
Box.cs格子類(一些格子裡儲存的資料,行下標,列下標,是否合併過的開關。。)
Grid.cs網格類(主要演算法在裡面)
Manage2048.cs控制遊戲類(控制遊戲流程)
經過幾次簡單的右移,這是控制檯實現的數字變化效果(左上角的4是隨機產生的所以沒向右靠)
程式碼供參考
Box.cs格子類
/// <summary> /// 格子類 /// </summary> class Box { //行下標 private int rowIndex; //列下標 private int colsIndex; public int RowIndex { get { return rowIndex; } set { rowIndex = value; } } //是否第一次合併 public bool isMerge = false; public int ColsIndex { get { return colsIndex; } set { colsIndex = value; } } //格子上的數字 public int Number { get; set; } public Box(int row, int cols) { this.RowIndex = row; this.ColsIndex = cols; Number = 0; } }
Grid.cs網格類
/// <summary> /// 網格類 /// </summary> class Grid { int row = 0;//行 int clos = 0;//列 Box[,] boxes; bool isEnableRandom = false;//是否還會產生隨機數(預設不能) int gridNum = 2;//格子上的隨機數 bool isFirst = true; //是否是第一個 Queue<Box> boxisMerge;//佇列儲存合併過的數 Random ran; public bool isGameover = false;//遊戲是否結束 int total = 0;//計算格子的數 public Grid(int row, int clos) { this.row = row < 4 ? 4 : row; this.clos = clos < 4 ? 4 : clos; boxes = new Box[row, clos]; ran = new Random(); boxisMerge = new Queue<Box>(); } /// <summary> /// 初始化網格 /// </summary> public void InitGrid() { for (int i = 0; i < boxes.GetLength(0); i++) { for (int j = 0; j < boxes.GetLength(1); j++) { boxes[i, j] = new Box(i, j); } } this.RandomNum(); } /// <summary> /// 產生隨機數 /// </summary> public void RandomNum() { int count = 0; //如果是第一個數 將隨機出現兩個數字 if (isFirst) { count = 2; isFirst = false; } else { count = 1; } for (int i = 0; i < count;) { int r = ran.Next(0, row); int c = ran.Next(0, clos); //判斷該格子上是否有數字了 if (boxes[r, c].Number != 0) continue; //隨機到4 那麼下次必然出現2 if (gridNum == 4) { gridNum = 2; } else if (gridNum == 2) { //如果隨機數是2 那麼下次隨機到2的概率為80%,隨機到4的概率為20% int num = ran.Next(0, 10); if (num < 8) { gridNum = 2; } else { gridNum = 4; } } boxes[r, c].Number = gridNum;//將隨機數放在隨機格子上 i++; } total += count; } /// <summary> /// 控制向右移動 /// </summary> public void MoveRight() { for (var i = 0; i < boxes.GetLength(0); i++) { for (var j = 0; j < boxes.GetLength(1); j++) { //一旦發現不為0的數 if (boxes[i, j].Number != 0) { //從右往左遍歷到該數前一個 for (var k = boxes.GetLength(1) - 1; k > j; k--) { //如果最右邊的數不等於0 && 最右邊的數和最右邊-1的數相等 說明可以合併 if (boxes[i, k].Number != 0 && boxes[i, k].Number == boxes[i, k - 1].Number && !boxes[i, k].isMerge && !boxes[i, k - 1].isMerge) { boxes[i, k].Number *= 2; boxes[i, k - 1].Number = 0; boxes[i, k].isMerge = true; isEnableRandom = true;//如果產生合併就能產生隨機數 boxisMerge.Enqueue(boxes[i, k]);//把合併過數的存入佇列 total--; } //如果最右邊的數等於0 && 最右邊-1的數不為0 (向右移動) if (boxes[i, k].Number == 0 && boxes[i, k - 1].Number != 0) { int temp = boxes[i, k - 1].Number; boxes[i, k - 1].Number = boxes[i, k].Number; boxes[i, k].Number = temp; isEnableRandom = true;//如果移動就能產生隨機數 } } } } } this.ResetMegreList();//把所有數isMerge開關重置 EnableRandom(); } /// <summary> /// 控制向左移動 /// </summary> public void MoveLeft() { for (var i = boxes.GetLength(0) - 1; i >= 0; i--) { for (var j = boxes.GetLength(1) - 1; j >= 0; j--) { if (boxes[i, j].Number != 0) { for (var k = 0; k < j; k++) { if (boxes[i, k].Number != 0 && boxes[i, k].Number == boxes[i, k + 1].Number && !boxes[i, k].isMerge && !boxes[i, k + 1].isMerge) { boxes[i, k].Number *= 2; boxes[i, k + 1].Number = 0; boxes[i, k].isMerge = true; isEnableRandom = true; boxisMerge.Enqueue(boxes[i, k]);//把合併過數的存入佇列 total--; } if (boxes[i, k].Number == 0 && boxes[i, k + 1].Number != 0) { int temp = boxes[i, k + 1].Number; boxes[i, k + 1].Number = boxes[i, k].Number; boxes[i, k].Number = temp; isEnableRandom = true; } } } } } this.ResetMegreList();//把所有數isMerge開關重置 EnableRandom(); } /// <summary> /// 控制向上移動 /// </summary> public void MoveTop() { for (var j = boxes.GetLength(0) - 1; j >= 0; j--) { for (var i = boxes.GetLength(1) - 1; i >= 0; i--) { if (boxes[i, j].Number != 0) { for (var k = 0; k < i; k++) { if (boxes[k, j].Number != 0 && boxes[k, j].Number == boxes[k + 1, j].Number && !boxes[k, j].isMerge && !boxes[k + 1, j].isMerge) { boxes[k, j].Number *= 2; boxes[k + 1, j].Number = 0; boxes[k, j].isMerge = true; isEnableRandom = true; boxisMerge.Enqueue(boxes[k, j]);//把合併過數的存入佇列 total--; } if (boxes[k, j].Number == 0 && boxes[k + 1, j].Number != 0) { int temp = boxes[k + 1, j].Number; boxes[k + 1, j].Number = boxes[k, j].Number; boxes[k, j].Number = temp; isEnableRandom = true; } } } } } this.ResetMegreList();//把所有數isMerge開關重置 EnableRandom(); } /// <summary> /// 控制向下移動 /// </summary> public void MoveDown() { for (var j = 0; j < boxes.GetLength(1); j++) { for (var i = 0; i < boxes.GetLength(0); i++) { if (boxes[i, j].Number != 0) { for (var k = boxes.GetLength(0) - 1; k > i; k--) { if (boxes[k, j].Number != 0 && boxes[k, j].Number == boxes[k - 1, j].Number && !boxes[k, j].isMerge && !boxes[k - 1, j].isMerge) { boxes[k, j].Number *= 2; boxes[k - 1, j].Number = 0; boxes[k, j].isMerge = true; isEnableRandom = true; boxisMerge.Enqueue(boxes[k, j]);//把合併過數的存入佇列 total--; } if (boxes[k, j].Number == 0 && boxes[k - 1, j].Number != 0) { int temp = boxes[k - 1, j].Number; boxes[k - 1, j].Number = boxes[k, j].Number; boxes[k, j].Number = temp; isEnableRandom = true; } } } } } this.ResetMegreList();//把所有數isMerge開關重置 EnableRandom(); } /// <summary> /// /把所有格子裡的數isMerge開關重置 /// </summary> public void ResetMegreList() { while (boxisMerge.Count > 0) { boxisMerge.Dequeue().isMerge = false; } } /// <summary> /// 判斷是否還能移動 /// </summary> public void EnableRandom() { //如果能移動和合並就產生隨機數 if (isEnableRandom) { this.RandomNum(); } else { Console.WriteLine("不能再向這個方向移動了"); } //重置開關 isEnableRandom = false; } /// <summary> /// 檢查遊戲是否結束 /// </summary> public void CheckGanmeisOver() { if (total < row * clos) { isGameover = false; return; } for (int i = 0; i < boxes.GetLength(0); i++) { for (int j = 0; j < boxes.GetLength(1); j++) { //上下左右判斷 if (i >= 1&&boxes[i, j].Number == boxes[i - 1, j].Number ) { isGameover = false; return; } if (i < boxes.GetLength(0)-1 && boxes[i, j].Number == boxes[i + 1, j].Number) { isGameover = false; return; } if (j >= 1 && boxes[i, j].Number == boxes[i, j-1].Number) { isGameover = false; return; } if (j < boxes.GetLength(1)-1 && boxes[i, j].Number == boxes[i, j+1].Number) { isGameover = false; return; } } } isGameover = true; } public void Test() { Console.WriteLine("-----------"); for (int i = 0; i < boxes.GetLength(0); i++) { for (int j = 0; j < boxes.GetLength(1); j++) { Console.Write(boxes[i, j].Number + " "); } Console.WriteLine(); } Console.WriteLine("-----------"); } }
Manage2048.cs控制遊戲類
/// <summary> /// 管理類控制遊戲 /// </summary> class Manage2048 { Grid g; public Manage2048() { g = new Grid(4, 4); } public void StartGame() { g.InitGrid(); g.Test(); } public void PlayGame() { while (!g.isGameover) { string op = Console.ReadLine(); switch (op) { case "w": g.MoveTop(); break; case "s": g.MoveDown(); break; case "a": g.MoveLeft(); break; case "d": g.MoveRight(); break; default: Console.WriteLine("輸入錯誤"); break; } Console.Clear(); g.Test(); g.CheckGanmeisOver(); } Console.WriteLine("Game Over!"); } }