2048游戏的简单实现(C#实现)

游戏规则

游戏规则,玩家需要控制所有方块向同一个方向运动,两个相同数字方块撞在一起后会合并成为它们的和,每次操作后会随机生成一个2或者4,最终得到一个“2048”的方块就算胜利。

C#代码实现

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

namespace _2019年8月16日
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] arr = new int[4, 4]
            {
                //{8,8,2,0 },
                //{8,4,0,4 },
                //{2,0,2,0 },
                //{0,0,0,0 },

                //{0,8,2,0 },
                //{0,4,0,4 },
                //{2,0,2,0 },
                //{0,0,0,0 },

                {0,0,2,0 },
                {0,0,0,0 },
                {2,0,0,0 },
                {0,0,0,0 },
            };

            _2048 a2048 = new _2048(arr);
            Console.WriteLine("原数组:");
            a2048.PrintArr(arr);
            while (true)
            {
                ConsoleKeyInfo info = Console.ReadKey();//获取按键信息
                switch (info.Key)
                {
                    case ConsoleKey.LeftArrow://如果是向左键
                        Console.WriteLine("←");
                        a2048.Print_Left();
                        break;
                    case ConsoleKey.UpArrow://如果是向上键
                        Console.WriteLine("↑");
                        a2048.Print_Up();
                        break;
                    case ConsoleKey.RightArrow://如果是向右键
                        Console.WriteLine("→");
                        a2048.Print_Right();
                        break;
                    case ConsoleKey.DownArrow://如果是向下键
                        Console.WriteLine("↓");
                        a2048.Print_Down();
                        break;
                    default:
                        break;
                }
            }
        }
    }

    //2048小游戏类
    class _2048
    {
        private int[,] arr;

        public _2048(int[,] arr)
        {
            this.arr = arr;
        }

        //打印数组
        public void PrintArr(int[,] newArr)
        {
            for (int i = 0; i < newArr.GetLength(0); i++)
            {
                for (int j = 0; j < newArr.GetLength(1); j++)
                {
                    Console.Write(newArr[i, j] + "\t");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }

        //打印向右合并数组
        public void Print_Right()
        {
            int[,] rightArr = ToRigth(arr);
            //arr = rightArr;//更新arr数组
            arr = Rand2048(rightArr);//更新能随机生成数字的arr数组
            PrintArr(rightArr);
        }

        //打印向上合并数组
        public void Print_Up()
        {
            int[,] upArr = ToUp(arr);
            //arr = upArr;
            arr = Rand2048(upArr);
            PrintArr(upArr);
        }

        //打印向下合并数组
        public void Print_Down()
        {
            int[,] downArr = ToDown(arr);
            //arr = downArr;
            arr = Rand2048(downArr);
            PrintArr(downArr);
        }

        //打印向左合并数组
        public void Print_Left()
        {
            int[,] leftArr = ToLeft(arr);
            //arr = leftArr;
            arr = Rand2048(leftArr);
            PrintArr(leftArr);
        }

        //顺时针旋转90°
        private int[,] CW90(int[,] arr)
        {
            int[,] newArr = new int[arr.GetLength(1), arr.GetLength(0)];//定义新数组

            for (int r = 0, c_newArr = newArr.GetLength(1) - 1; r < arr.GetLength(0); r++)
            {
                for (int c = 0, r_newArr = 0; c < arr.GetLength(1); c++)
                {
                    newArr[r_newArr, c_newArr] = arr[r, c];
                    r_newArr++;
                }
                c_newArr--;
            }

            return newArr;
        }

        //逆时针旋转90°
        private int[,] ACW90(int[,] arr)
        {
            int[,] newArr = new int[arr.GetLength(1), arr.GetLength(0)];//定义新数组

            for (int r = 0, c_newArr = 0; r < arr.GetLength(0); r++)
            {
                for (int c = 0, r_newArr = newArr.GetLength(0) - 1; c < arr.GetLength(1); c++)
                {
                    newArr[r_newArr, c_newArr] = arr[r, c];
                    r_newArr--;
                }
                c_newArr++;
            }

            return newArr;
        }

        //垂直翻转
        private int[,] FZ(int[,] arr)
        {
            int[,] newArr = new int[arr.GetLength(0), arr.GetLength(1)];//定义新数组

            for (int r = 0; r < arr.GetLength(0); r++)
            {
                for (int c = 0, c_n = newArr.GetLength(1) - 1; c < arr.GetLength(1); c++, c_n--)
                {
                    newArr[r, c_n] = arr[r, c];
                }
            }

            return newArr;
        }

        //向右合并
        private int[,] ToRigth(int[,] arr)
        {
            //向右
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                for (int k = 0; k < arr.GetLength(1) - 1; k++)//逐行将0左对齐
                {
                    for (int j = arr.GetLength(1) - 1; j > k; j--)
                    {
                        if (arr[i, j] == 0)
                        {
                            int temp = arr[i, j];
                            arr[i, j] = arr[i, j - 1];
                            arr[i, j - 1] = temp;
                        }
                    }
                }

            }

            //合并
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                for (int j = arr.GetLength(1) - 1; j > 0; j--)
                {
                    if (arr[i, j] == arr[i, j - 1] && arr[i, j] != 0)//相邻数字相同且不等于0时
                    {
                        arr[i, j] *= 2;
                        arr[i, j - 1] = 0;
                    }
                }
            }

            //再次向右
            for (int i = 0; i < arr.GetLength(0); i++)
            {
                for (int k = 0; k < arr.GetLength(1) - 1; k++)//逐行将0左对齐
                {
                    for (int j = arr.GetLength(1) - 1; j > k; j--)
                    {
                        if (arr[i, j] == 0)
                        {
                            int temp = arr[i, j];
                            arr[i, j] = arr[i, j - 1];
                            arr[i, j - 1] = temp;
                        }
                    }
                }

            }

            return arr;
        }

        //向上合并
        private int[,] ToUp(int[,] arr)
        {
            //先使数组顺时针旋转90°
            int[,] newArr = CW90(arr);

            //再向右合并
            newArr = ToRigth(newArr);

            //最后使数组逆时针旋转90°(转回来)
            newArr = ACW90(newArr);

            return newArr;
        }

        //向下合并
        private int[,] ToDown(int[,] arr)
        {
            //先使数组逆时针旋转90°
            int[,] newArr = ACW90(arr);

            //再向右合并
            newArr = ToRigth(newArr);

            //最后使数组顺时针旋转90°
            newArr = CW90(newArr);

            return newArr;
        }

        //向左合并
        private int[,] ToLeft(int[,] arr)
        {
            //先使数组垂直翻转一次
            int[,] newArr = FZ(arr);

            //再向右合并
            newArr = ToRigth(newArr);

            //最后再使数组翻转回来
            newArr = FZ(newArr);

            return newArr;
        }

        //在数字为0的地方随机生成2或者4
        private int[,] Rand2048(int[,] arr)
        {
            Random rand = new Random();

            int r_ran = rand.Next(arr.GetLength(0));//获取随机行索引
            int c_ran = rand.Next(arr.GetLength(1));//获取随机列索引

            if (arr[r_ran, c_ran] == 0)//如果该随机数原来等于0
            {
                int num = rand.Next(10);
                if (num == 0)//随机生成4的概率为10%
                {
                    arr[r_ran, c_ran] = 4;
                }
                else//随机生成2的概率为90%
                {
                    arr[r_ran, c_ran] = 2;
                }
            }
            return arr;
        }
    }
}

小结

本次游戏实现通过写一个2048游戏类,声明一个二维数组字段,并且在类构造函数中通过传参实现二维数组的初始化。

在2048游戏类中有打印数组方法,打印向左、向右、向上、向下合并数组方法,这些方法主要作用是显示合并的最终结果。

接下来首先写出向右合并方法,接着向上、向下和向左合并方法可以分别通过将原数组旋转和翻转后调用向右合并方法实现

根据上面的思路,类中还应该有顺逆时针旋转、垂直翻转二维数组的方法,以便于在除向右合并方法的其他合并方法中使用。

最后是实现操作一次,随机生成一个2或者4在二维数组里,这个利用C#类库中的Random类就可以了,据说生成2的概率和生成4的概率是不同的,前者概率是90%,后者是10%。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

斗乐八神

你的鼓励将是我最大的支持~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值