程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 2048 控制台版(C#)

2048 控制台版(C#)

編輯: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   

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved