1. 程式人生 > >C#實現2048小遊戲

C#實現2048小遊戲

要實現這個簡單的小遊戲主要在於實現一個方向移動

數字的移動及合併該如何處理

然後其它方向的邏輯是相同的

我做的這個基本功能實現了

主要分為三個類

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!");
        }

    }