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 将矩阵复制一份。
流程图如下:
2048 控制台版(C#)
上代码
 
主函数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 
 

你可能感兴趣的:(控制台)