看见朋友圈里面疯转这个游戏,然后就玩了一下,说下自己的想法。。。
首先地图是一个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; } } }
关于围住神经猫实现的想法
时间: 2024-11-05 17:33:09