首页 > 学院 > 开发设计 > 正文

2048 控制台版(C#)

2019-11-17 03:08:10
字体:
来源:转载
供稿:网友

2048 控制台版(C#)

开篇

2048游戏现在很火啊,很多人应该已经玩过了。在博客园上也看见有人模仿做的GDI+版 2048游戏,鄙人暂且不做那么多动画的东西,毕竟是个小东东,在此奉上一个《控制台版2048》。

本文程序源码下载:http://pan.baidu.com/s/1mg8zntu

程序结构相对简单,一共200+行代码,注释很少,大家大概也看得懂,我在这解释下程序中各个方法的含义:
Main 方法程序入口,RePaint 类似Win32程序中的刷新界面,SquareRot90 矩形矩阵顺时针旋转90度角(参数可以为负,表示逆时针)。Merge 向左移动,合并单元格中值相同的元素,并进行整理(将所有元素靠左放置)RandomPoint 随机生成点,从矩阵的空位置(值为0)中随机生成一个点,若不存在空位置返回null。CanMove 判断是否可以继续移动,也是判断游戏是否结束的方法。IsEquals 判断两矩阵的值是否相同。CopyToB 将矩阵复制一份。
流程图如下:上代码主函数Main
static 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");        }    }}

  

矩阵旋转方法
/// 矩形顺时针旋转90°/// </summary>/// <param name="rotNum">旋转次数</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;}

  

随机点方法
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;}

  

是否可以继续移动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中用到的矩阵复制方法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;}

  

两个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;    }}

  

结束语 其实要写一个游戏并不是像想像中那么容易,要处理算法等问题,必须要事先仔细的设计,需要一张草纸作为设计图,这样会让工作效率大大提高。之前贴过毕设的游戏《保卫萝卜》,由于时间关系迟迟没有整理,等毕设答辩完成后,一定好好整理,给大家分享。现在功能基本完成了,在这先贴一个缩减版的游戏程序,链接:http://pan.baidu.com/s/1sjvxO7N。程序有什么问题、BUG,希望大家多多留言。源码整理后再上传。 过几天是蓝桥杯比赛,哈哈,北京我来了。本文程序源码下载:http://pan.baidu.com/s/1mg8zntu
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表