c#实现2048游戏

2048这个游戏的本质是二位数组,就以4*4的二位数组来分析关键的逻辑以及实现。
我们所有的操作都是对这个二维数组的数据的操作。分为上下左右四个方向。
右三个主要 的类:
Box.class:如果在控制台上实现这个游戏,完全没有必要创建一个Box类,因为它此时只存放一个number值,完全可以有数组中的值来代替。不过考虑到后期游戏可能会在拓展到图形界面,Box可能会有点用(可能会加一些在矩阵中的位置,图片地址、颜色等属性信息)
Grid.class:进行一些游戏初始化和逻辑操作,如判断游戏是否结束、分别对上下左右四个方向操作每个方格等等。
Manager.class:进行游戏开始、结束的控制。


实现效果:
这里写图片描述


代码如下:

Box.class:

using System;
namespace Test
{
    class Box
    {
        //private int row;
        //private int col;
        public int Number { get; set; }
        //public bool IsMerge { get; set; }

        public Box(int num)
        {
            this.Number = num;
            //this.row = row;
            //this.col = col;
            //this.IsMerge = false;
        }
    }
}

Grid.class(实现一):

using System;
using System.Collections.Generic;

namespace Test
{
    class Grid
    {
        private int row;
        private int col;
        private Box[,] grids;
        private bool isFirst;
        private int rdNumber;

        public bool IsGameOver { get; private set; }
        public Grid(int row, int col)
        {
            this.row = row;
            this.col = col;
            this.grids = new Box[row, col];
            InitBoxs();
            IsGameOver = false;
            isFirst = true;
        }
        private void InitBoxs()
        {
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    Box box = new Box(0);
                    grids[i, j] = box;
                }
            }
        }
        public void PrintGrid()
        {
            Console.WriteLine("==============================================");
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    Console.Write(grids[i, j].Number + "\t");
                }
                Console.WriteLine();
            }
            Console.WriteLine("==============================================");
        }
        public void RandomBox()
        {
            int count = 1;

            //首次生成两个数字
            if (isFirst)
            {
                count = 2;
                isFirst = false;
            }

            Random rd = new Random();

            for (int i = 0; i < count; )
            {
                if (rdNumber == 4)
                {
                    rdNumber = 2;
                }
                else
                {
                    int num = rd.Next(1, 11);
                    if (num < 9)
                    {
                        rdNumber = 2;
                    }
                    else
                    {
                        rdNumber = 4;
                    }
                }
                int boxRow = rd.Next(0, row);
                int boxCol = rd.Next(0, col);
                if (grids[boxRow, boxCol].Number == 0)
                {
                    //Console.WriteLine("随机生成点为:[{0},{1}]", boxRow, boxCol);
                    grids[boxRow, boxCol].Number = rdNumber;
                }
                else
                {
                    continue;
                }
                i++;
            }
        }

        public bool MoveDirection(Direction dir)
        {
            bool isMove = false;
            switch (dir)
            {
                case Direction.Up:
                    isMove = MoveUp();
                    break;
                case Direction.Dowm:
                    isMove = MoveDown();
                    break;
                case Direction.Left:
                    isMove = MoveLeft();
                    break;
                case Direction.Right:
                    isMove = MoveRight();
                    break;
            }
            CheckIsGameOver();
            return isMove;
        }

        //当矩阵满了的时候(数字都不为0),上下左右相邻没有数字相同的了,游戏就结束,否则游戏继续
        private void CheckIsGameOver()
        {
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    if (grids[i, j].Number == 0)
                    {
                        IsGameOver = false;
                        return;
                    }
                }
            }

            //矩阵存满了不为0的数
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < col; j++)
                {
                    //上下左右
                    if (i - 1 >= 0 && grids[i, j].Number == grids[i - 1, j].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                    if (i + 1 < row && grids[i, j].Number == grids[i + 1, j].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                    if (j - 1 >= 0 && grids[i, j].Number == grids[i, j - 1].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                    if (j + 1 < col && grids[i, j].Number == grids[i, j + 1].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                }
            }

            IsGameOver = true;
        }
        //向下
        private bool MoveDown()
        {
            bool isMoveBox = false;   //是否移动格子
            for (int j = 0; j < col; j++)
            {
                //将所有的格子往下面移
                for (int i = row - 1; i >= 0; i--)
                {
                    if (grids[i, j].Number == 0)  //如果为0,代表该格子为空,上面的格子往下移
                    {
                        for (int k = i - 1; k >= 0; k--)
                        {
                            if (grids[k, j].Number != 0)
                            {
                                isMoveBox = true;
                                grids[i, j].Number = grids[k, j].Number;
                                grids[k, j].Number = 0;
                                break;
                            }
                        }
                    }
                }

                //合并格子
                for (int i = row - 1; i >= 0; i--)
                {
                    //如果遍历到最后一个格子 或者 当前格子的上面一个格子没有数字,结束循环
                    if (i == 0 || grids[i - 1, j].Number == 0)
                    {
                        break;
                    }
                    //Console.WriteLine("==================");
                    if (grids[i, j].Number == grids[i - 1, j].Number)
                    {
                        isMoveBox = true;
                        grids[i - 1, j].Number = 0;
                        grids[i, j].Number *= 2;

                        //合并完格子,上面的格子(往上数2个)往下面移
                        for (int k = i - 2; k >= 0; k--)
                        {
                            if (grids[k, j].Number == 0)
                            {
                                break;
                            }
                            grids[k + 1, j].Number = grids[k, j].Number;
                            grids[k, j].Number = 0;
                        }
                    }
                }
            }
            return isMoveBox;
        }

        //向上
        private bool MoveUp()
        {
            bool isMoveBox = false;
            for (int j = 0; j < col; j++)
            {
                //将所有的格子往上面移
                for (int i = 0; i < row; i++)
                {
                    if (grids[i, j].Number == 0)  //如果为0,代表该格子为空,下面的格子往上移
                    {
                        for (int k = i + 1; k < row; k++)
                        {
                            if (grids[k, j].Number != 0)
                            {
                                isMoveBox = true;
                                grids[i, j].Number = grids[k, j].Number;
                                grids[k, j].Number = 0;
                                break;
                            }
                        }
                    }
                }

                //合并格子
                for (int i = 0; i < row; i++)
                {
                    //如果遍历到最后一个格子 或者 当前格子的下面一个格子没有数字,结束循环
                    if (i == row - 1 || grids[i + 1, j].Number == 0)
                    {
                        break;
                    }
                    if (grids[i, j].Number == grids[i + 1, j].Number)
                    {
                        isMoveBox = true;
                        grids[i + 1, j].Number = 0;
                        grids[i, j].Number *= 2;

                        //合并完格子,下面的格子(往下数2个)往上面移
                        for (int k = i + 2; k < row; k++)
                        {
                            if (grids[k, j].Number == 0)
                            {
                                break;
                            }
                            grids[k - 1, j].Number = grids[k, j].Number;
                            grids[k, j].Number = 0;
                        }
                    }
                }
            }
            return isMoveBox;
        }
        //向左
        private bool MoveLeft()
        {
            bool isMoveBox = false;   //是否移动格子
            for (int i = 0; i < row; i++)
            {
                //将所有的格子往左边移
                for (int j = 0; j < col; j++)
                {
                    if (grids[i, j].Number == 0)  //如果为0,代表该格子为空,右边的格子往左移
                    {
                        for (int k = j + 1; k < col; k++)
                        {
                            if (grids[i, k].Number != 0)
                            {
                                isMoveBox = true;
                                grids[i, j].Number = grids[i, k].Number;
                                grids[i, k].Number = 0;
                                break;
                            }
                        }
                    }
                }

                //合并格子
                for (int j = 0; j < col; j++)
                {
                    //如果遍历到最后一个格子 或者 当前格子的右边一个格子没有数字,结束循环
                    if (j == col - 1 || grids[i, j + 1].Number == 0)
                    {
                        break;
                    }
                    if (grids[i, j].Number == grids[i, j + 1].Number)
                    {
                        isMoveBox = true;
                        grids[i, j + 1].Number = 0;
                        grids[i, j].Number *= 2;

                        //合并完格子,右边的格子(往右数2个)往左边移
                        for (int k = j + 2; k < col; k++)
                        {
                            if (grids[k, j].Number == 0)
                            {
                                break;
                            }
                            grids[i, k - 1].Number = grids[i, k].Number;
                            grids[i, k].Number = 0;
                        }
                    }
                }
            }
            return isMoveBox;
        }
        //向右
        private bool MoveRight()
        {
            bool isMoveBox = false;   //是否移动格子
            for (int i = 0; i < row; i++)
            {
                //将所有的格子往右边移
                for (int j = col - 1; j >= 0; j--)
                {
                    if (grids[i, j].Number == 0)  //如果为0,代表该格子为空,左边的格子往右移
                    {
                        for (int k = j - 1; k >= 0; k--)
                        {
                            if (grids[i, k].Number != 0)
                            {
                                isMoveBox = true;
                                grids[i, j].Number = grids[i, k].Number;
                                grids[i, k].Number = 0;
                                break;
                            }
                        }
                    }
                }

                //合并格子
                for (int j = col - 1; j >= 0; j--)
                {
                    //如果遍历到最后一个格子 或者 当前格子的左边一个格子没有数字,结束循环
                    if (j == 0 || grids[i, j - 1].Number == 0)
                    {
                        break;
                    }
                    if (grids[i, j].Number == grids[i, j - 1].Number)
                    {
                        isMoveBox = true;
                        grids[i, j - 1].Number = 0;
                        grids[i, j].Number *= 2;

                        //合并完格子,左边的格子(往右数2个)往右边移
                        for (int k = j - 2; k >= 0; k--)
                        {
                            if (grids[k, j].Number == 0)
                            {
                                break;
                            }
                            grids[i, k + 1].Number = grids[i, k].Number;
                            grids[i, k].Number = 0;
                        }
                    }
                }
            }
            return isMoveBox;
        }
    }

    enum Direction
    {
        Up,
        Dowm,
        Left,
        Right
    }
}

Grid.class(实现二):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo2048
{
    /// <summary>
    /// 网格类
    /// </summary>
    class Grid
    {
        int row = 0;//保存行数
        int cols = 0;//列数
        Box[,] gridList;
        bool isFirst = true;//第一次
        Random rdObj;
        int rdNum = 2;//存储上一次的随机数字
        private int boxCount = 0;
        public bool IsGameOver { get; private set; }
        public Grid(int row, int cols)
        {
            this.row = row < 4 ? 4 : row;
            this.cols = cols < 4 ? 4 : cols;
            gridList = new Box[row, cols];
            rdObj = new Random();
            //  InitGrid();
        }
        public void InitGrid()
        {
            for (var i = 0; i < gridList.GetLength(0); i++)
            {
                for (var j = 0; j < gridList.GetLength(1); j++)
                {
                    Box box = new Box(i, j);
                    gridList[i, j] = box;
                }
            }
            this.RandomNum();
        }

        public void RandomNum()
        {
            int count = 0;
            //第一次随机两个数
            if (isFirst)
            {
                count = 2;
                isFirst = false;
            }
            else
            {//后面只随机一个数字
                count = 1;
            }

            for (var i = 0; i < count; )
            {
                //随机下标,出现数字的位置
                int r = rdObj.Next(0, row);
                int c = rdObj.Next(0, cols);
                if (gridList[r, c].Number != 0) continue;
                //避免两次随机都是4
                if (rdNum == 4)
                {
                    rdNum = 2;
                }
                else
                { //随机数字,80%2,20%4
                    int a = rdObj.Next(1, 11);
                    if (a < 9) rdNum = 2;
                    else rdNum = 4;
                }
                //进行赋值
                gridList[r, c].Number = rdNum;
                boxCount++;
                i++;
            }

        }

        private void CheckIsGameOver()
        {

            //矩阵存满了不为0的数
            for (int i = 0; i < row; i++)
            {
                for (int j = 0; j < cols; j++)
                {
                    //下右
                    //if (i - 1 >= 0 && gridList[i, j].Number == gridList[i - 1, j].Number)
                    //{
                    //    IsGameOver = false;
                    //    return;
                    //}
                    if (i + 1 < row && gridList[i, j].Number == gridList[i + 1, j].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                    //if (j - 1 >= 0 && gridList[i, j].Number == gridList[i, j - 1].Number)
                    //{
                    //    IsGameOver = false;
                    //    return;
                    //}
                    if (j + 1 < cols && gridList[i, j].Number == gridList[i, j + 1].Number)
                    {
                        IsGameOver = false;
                        return;
                    }
                }
            }

            IsGameOver = true;
        }
        public bool MoveDir(Direction dir)
        {
            bool isMove = false;
            switch (dir)
            {
                case Direction.Up:
                    isMove = MoveUp();
                    break;
                case Direction.Down:
                    isMove = MoveDown();
                    break;
                case Direction.Left:
                    isMove = MoveLeft();
                    break;
                case Direction.Right:
                    isMove = MoveRight();
                    break;
            }
            if (boxCount == 16)
            {
                CheckIsGameOver();
            }
            return isMove;
        }

        private bool MoveDown()
        {
            bool isMove = false;
            //循环列的下标
            int mergeIndex = -1;
            for (var c = 0; c < gridList.GetLength(1); c++)
            {
                for (var r = gridList.GetLength(0) - 2; r >= 0; r--)
                {
                    Box box = gridList[r, c];//当前进行检测判断是否可以往下移动或者合并的格子
                    if (box.Number == 0) continue;

                    for (var k = r + 1; k < gridList.GetLength(0); k++)
                    {
                        Box nextBox = gridList[k, c];
                        //进行空白格子判断
                        if (nextBox.Number == 0)
                        {
                            isMove = true;
                            //找到一个就往下移一个
                            nextBox.Number = box.Number;
                            box.Number = 0;
                            box = nextBox;
                            continue;
                        }
                        //进行格子合并的判断
                        if (nextBox.Number == box.Number)
                        {
                            if (mergeIndex == k)
                            {
                                break;
                            }
                            mergeIndex = k;
                            isMove = true;
                            nextBox.Number *= 2;
                            box.Number = 0;
                            boxCount--;
                            //nextBox.IsMerge = true;//表示已经被合并过了
                            // megreList.Enqueue(nextBox);
                        }
                        break;
                    }

                }
            }
            //当次合并过的所有格子对象,重置IsMerge=false
            // this.ResetMegreList();
            return isMove;
        }

        private bool MoveUp()
        {
            bool isMove = false;
            //循环列的下标
            for (var c = 0; c < cols; c++)
            {
                int mergeIndex = -1;
                for (int r = 1; r < row; r++)
                {
                    Box currentBox = gridList[r, c];
                    if (currentBox.Number == 0)
                    {
                        continue;
                    }
                    for (int k = r - 1; k >= 0; k--)
                    {
                        Box nextBox = gridList[k, c];
                        if (nextBox.Number == 0)
                        {
                            isMove = true;
                            nextBox.Number = currentBox.Number;
                            currentBox.Number = 0;
                            currentBox = nextBox;
                            continue;
                        }

                        if (currentBox.Number == nextBox.Number)
                        {
                            if (mergeIndex == k)
                            {
                                break;
                            }
                            mergeIndex = k;
                            isMove = true;
                            nextBox.Number *= 2;
                            currentBox.Number = 0;
                            boxCount--;
                        }

                        break;
                    }
                }
            }

            return isMove;
        }

        private bool MoveRight()
        {
            bool isMove = false;
            //循环列的下标
            for (var r = 0; r < row; r++)
            {
                int mergeIndex = -1;
                for (var c = cols - 2; c >= 0; c--)
                {
                    Box box = gridList[r, c];//当前进行检测判断是否可以往下移动或者合并的格子
                    if (box.Number == 0) continue;
                    for (var k = c + 1; k < cols; k++)
                    {
                        Box nextBox = gridList[r, k];
                        //进行空白格子判断
                        if (nextBox.Number == 0)
                        {
                            isMove = true;
                            //找到一个就往下移一个
                            nextBox.Number = box.Number;
                            box.Number = 0;
                            box = nextBox;
                            continue;
                        }
                        //进行格子合并的判断
                        if (nextBox.Number == box.Number)
                        {
                            if (mergeIndex == k)
                            {
                                break;
                            }
                            mergeIndex = k;
                            isMove = true;
                            nextBox.Number *= 2;
                            box.Number = 0;
                            boxCount--;
                        }
                        break;
                    }

                }
            }
            return isMove;
        }

        private bool MoveLeft()
        {
            bool isMove = false;
            //循环行的下标
            for (var r = 0; r < row; r++)
            {
                int mergeIndex = -1;
                for (int c = 1; c < cols; c++)
                {
                    Box currentBox = gridList[r, c];
                    if (currentBox.Number == 0)
                    {
                        continue;
                    }
                    for (int k = c - 1; k >= 0; k--)
                    {
                        Box nextBox = gridList[r, k];
                        if (nextBox.Number == 0)
                        {
                            isMove = true;
                            nextBox.Number = currentBox.Number;
                            currentBox.Number = 0;
                            currentBox = nextBox;
                            continue;
                        }

                        if (currentBox.Number == nextBox.Number)
                        {
                            if (mergeIndex == k)
                            {
                                break;
                            }
                            mergeIndex = k;
                            isMove = true;
                            nextBox.Number *= 2;
                            currentBox.Number = 0;
                            boxCount--;
                        }

                        break;
                    }
                }
            }

            return isMove;
        }
        public void Test()
        {
            Console.WriteLine("================================");
            for (var i = 0; i < gridList.GetLength(0); i++)
            {
                for (var j = 0; j < gridList.GetLength(1); j++)
                {
                    Console.Write(gridList[i, j].Number + "\t");
                }
                Console.Write("\n");
            }
            Console.WriteLine("================================");
        }
    }
}

Manager.cs:

using System;

namespace Test
{
    class Manager
    {

        private static Grid grid = new Grid(4, 4);
        static void Main()
        {
            StartGame();
        }

        public static void StartGame()
        {
            grid.RandomBox();
            grid.PrintGrid();
            Console.WriteLine("请按上下左右键");

            while (grid.IsGameOver == false)
            {
                if (PlayController() == false)
                {
                    if (grid.IsGameOver)
                    {
                        Console.WriteLine("------------------------------------------");
                        Console.WriteLine("------------------------------------------");
                        Console.WriteLine("------------------游戏结束----------------");
                        Console.WriteLine("------------------------------------------");
                        Console.WriteLine("------------------------------------------");
                        Console.WriteLine("------------------------------------------");
                        break;
                    }
                    continue;
                }

                //随机生成box
                grid.RandomBox();
                Console.Clear();

                grid.PrintGrid();
            }
        }

        public static bool PlayController()
        {
            bool isCanMove = false;


            while (true)
            {
                bool isRightKey = false;
                ConsoleKeyInfo info = Console.ReadKey();

                switch (info.Key)
                {
                    case ConsoleKey.UpArrow:
                        isRightKey = true;
                        isCanMove = grid.MoveDirection(Direction.Up);
                        //if (isCanMove == false)
                        //{
                        //    Console.WriteLine("不能往上移动了!");
                        //}
                        break;
                    case ConsoleKey.DownArrow:
                        isRightKey = true;
                        isCanMove = grid.MoveDirection(Direction.Dowm);
                        //if (isCanMove == false)
                        //{
                        //    Console.WriteLine("不能往下移动了!");
                        //}
                        break;
                    case ConsoleKey.LeftArrow:
                        isRightKey = true;
                        isCanMove = grid.MoveDirection(Direction.Left);
                        //if (isCanMove == false)
                        //{
                        //    Console.WriteLine("不能往左移动了!");
                        //}
                        break;
                    case ConsoleKey.RightArrow:
                        isRightKey = true;
                        isCanMove = grid.MoveDirection(Direction.Right);
                        //if (isCanMove == false)
                        //{
                        //    Console.WriteLine("不能往右移动了!");
                        //}
                        break;
                }
                if (isRightKey)
                {
                    break;
                }
            }
            return isCanMove;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34937637/article/details/81098762