關於圍住神經貓實現的想法

 看見朋友圈裏面瘋轉這個遊戲,然後就玩了一下,說下自己的想法。。。
首先地圖是一個9*9的矩陣,因爲不是對齊的,所以在後面廣搜的時候會有些麻煩,但是畢竟相對於4個方向,不對齊的6個方向會讓遊戲的可能性有很大變化。
貓貌似都是從地圖中間出現,默認的障礙應該也是隨機生成的,所以沒什麼難度。
感覺這個最麻煩的地方就是貓逃跑的路線。一開始 以爲是6個方向隨即一個跑,但是後來發現是能逃出去的最短路線,因爲本人比較菜,所以就用廣搜來實現的。起點就是貓的位置,終點就是座標超出地圖範圍 。廣搜就是最基本的廣搜,沒有剪枝,沒有雙向(9*9還要這些的只有一斤蔥才能幹出來吧。。。)然後每擴展到一個節點都記錄一下他前一個節點的位置用於作爲逃跑路徑,廣搜裏面的Visit數組我設了兩個,一個是點擊過的,一個是在搜索中臨時的,然後在搜索的時候如果在兩個數組中都沒有訪問過就訪問。探索相鄰節點費了點勁,因爲相對於矩陣,這個的座標實在沒法用兩層for搞定,就想推數學公式,推了半天繁瑣不說,代碼看的叫一難受。。。後來忽然想起一斤蔥的常量數組,輕鬆解決~這樣代碼長度只有原來的1/3,而且比原來好看多了。。。
至於勝負,如果老貓在地圖的邊界那就是輸了,如果上面的廣搜沒有搜到出去的路徑那麼玩家就贏了。PS:其實這種情況在遊戲裏面老貓是在原地晃,還不算結束,不過後面怎麼實現就已經很簡單了,就沒寫。比如沒搜到就返回(-1,-1)動不了就返回(-2,-2)。。。
因爲實在是沒有設計UI的天賦,所以界面就用Label簡單代替了,圓形label百度了一下,貌似可以實現這裏就不贅述了。
然後。。。也沒有什麼然後了? 
最後上代碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TrapTheCat
{
    public partial class Form1 : Form
    {
        private int MapHeight = 9;
        private int MapWidth = 9;
        private bool[,] BoolMap;//不能走的節點
        private int StartNum = 30;
        private GameLabel[,] GameMap;
        private int CatPosX;//貓德位置
        private int CatPosY;
        private int[,] GuideY = { { 0, 1, -1, 1, 0, 1 }, { -1, 0, -1, 1, -1, 0 } };//這兩個數組用於在深搜中探索相鄰節點
        private int[] GuideX = { -1, -1, 0, 0, 1, 1 };
        struct Pos//用於存儲路徑用的
        {
            public Pos(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
            public int X;
            public int Y;
        }
        public Form1()
        {
            InitializeComponent();
            GameStart();
            GameShow();
        }
        private void GameStart()//生成地圖
        {
            int i, j;
            CatPosX = MapHeight / 2;
            CatPosY = MapWidth / 2;
            BoolMap = new bool[MapHeight, MapWidth];
            GameMap = new GameLabel[MapHeight, MapWidth];
            Random rand = new Random();
            for (i = 0; i < MapHeight; i++)
                for (j = 0; j < MapWidth; j++)
                    BoolMap[i, j] = false;
            for (i = 0; i < StartNum; i++)
            {
                int x, y;
                x = rand.Next(MapHeight);
                y = rand.Next(MapWidth);
                while (BoolMap[x, y] || (x == MapHeight / 2 && y == MapWidth / 2))
                {
                    x = rand.Next(MapHeight);
                    y = rand.Next(MapWidth);
                }
                BoolMap[x, y] = true;
            }
            for (i = 0; i < MapHeight; i++)
                for (j = 0; j < MapWidth; j++)
                {
                    GameMap[i, j] = new GameLabel(i, j);
                    if (BoolMap[i, j])
                        GameMap[i, j].BackColor = Color.Orange;
                    else GameMap[i, j].BackColor = Color.White;
                    GameMap[i, j].Width = 20;
                    GameMap[i, j].Height = 20;
                    if (i % 2 == 0)
                    {
                        GameMap[i, j].Left = 30 + j * 25;
                    }
                    else
                    {
                        GameMap[i, j].Left = 20 + j * 25;
                    }
                    GameMap[i, j].Top = 30 + i * 25;
                }
            GameMap[CatPosX, CatPosY].Text = "Cat";
            BoolMap[CatPosX, CatPosY] = false;
        }
        private void GameShow()//顯示界面
        {
            int i, j;
            for (i = 0; i < MapHeight; i++)
                for (j = 0; j < MapWidth; j++)
                {
                    GameMap[i, j].Click += Label_Click;
                    this.Controls.Add(GameMap[i, j]);
                }
        }
        private Pos? CatMove()//貓逃跑的路徑,返回下一步應該向哪個方向跑
        {
            int X = CatPosX;
            int Y = CatPosY;
            int[,] list = new int[400, 2];
            bool[,] Visited = new bool[MapHeight, MapWidth];
            int Top = 0;
            int Tail = 0;
            int i, j;
            for (i = 0; i < MapHeight; i++)
                for (j = 0; j < MapWidth; j++)
                    Visited[i, j] = false;
            Pos[,] Prev = new Pos[MapHeight, MapWidth];
            Prev[X, Y].X = X;
            Prev[X, Y].Y = Y;
            list[Top, 0] = X;
            list[Top, 1] = Y;
            Top++;
            while (Top != Tail || Top == 0)
            {
                X = list[Tail, 0];
                Y = list[Tail, 1];
                Tail++;
                for (i = 0; i < 6; i++)
                {
                    int TempX, TempY;
                    TempY = Y + GuideY[X % 2, i];
                    TempX = X + GuideX[i];
                    if (TempX < 0 || TempX >= MapHeight || TempY < 0 || TempY >= MapWidth)
                    {
                        Pos p;
                        while (Prev[X, Y].X != CatPosX || Prev[X, Y].Y != CatPosY)
                        {
                            p = Prev[X, Y];
                            X = p.X;
                            Y = p.Y;
                        }
                        return new Pos(X, Y);
                    }
                    if (!Visited[TempX, TempY] && !BoolMap[TempX, TempY])
                    {
                        list[Top, 0] = TempX;
                        list[Top, 1] = TempY;
                        Prev[TempX, TempY].X = X;
                        Prev[TempX, TempY].Y = Y;
                        Top++;
                        Visited[TempX, TempY] = true;
                    }
                }

            }
            MessageBox.Show("No!\n" + Tail.ToString());
            return null;
        }
        private void Label_Click(object sender, EventArgs e)//label單擊事件
        {
            GameLabel label = (GameLabel)sender;
            BoolMap[label.X, label.Y] = true;
            label.BackColor = Color.Orange;
            if (CatPosX == 0 || CatPosX == MapHeight - 1 || CatPosY == 0 || CatPosY == MapWidth - 1)
            {
                MessageBox.Show("You Lose!");
                return;
            }
            Pos? p = CatMove();
            if (p.HasValue)
            {
                GameMap[CatPosX, CatPosY].Text = "";
                GameMap[p.Value.X, p.Value.Y].Text = "Cat";
                CatPosX = p.Value.X;
                CatPosY = p.Value.Y;
            }
            else
            {
                MessageBox.Show("You Win!");
            }
        }

    }
    class GameLabel : Label//顯示用標籤
    {
        private int PosX;

        public int X
        {
            get { return PosX; }
        }
        private int PosY;

        public int Y
        {
            get { return PosY; }
        }
        public GameLabel(int PosX, int PosY)
        {
            this.PosX = PosX;
            this.PosY = PosY;
        }
    }

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章