标签:
关于《围住神经猫》的逃跑路径算法
《围住神经猫》是去年在微信上挺火的H5游戏,在学习unity3d的过程中我就想把这个游戏用我学习到的unity3d知识重新编写。神经猫的逃跑路径有6个方向,分别是左上,右上,左,右,左下,右下,如图A。当神经猫到达边界点(最左,最右,最上,最下的点)时,则神经猫成功逃脱。
图A
其中橙色圆点为不能到达点。如果在神经猫的逃跑路径上有橙色圆点,则称这条路径为不可通路径,反之为可通路径。逃跑算法的第一步是在6个逃跑方向寻找可通路径,再从可通路径中选择最短的路径(神经猫到达边界点最短距离),在图B中红色的方向为可通路径,白色的方向为不可通路径。
图B
当同时存在多条最短可通路径时,人为的给神经猫设置优先级(我设置的优先级是左上,右上,左,右,左下,右下)。
当神经猫的6个逃跑方向都为不可通路径时。如图C,则在6个逃跑方向中选择神经猫可行走最远距离的为逃跑路径,图D的红色方向。因为这样可在一定程度上避免神经猫被橙色点包围。
图C
图D
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
//using System.Collections.
public class Pot1Click : MonoBehaviour
{
private GameObject cat;
private GameObject manager;
private int[] potNum = new int[6];//保存神经猫最短的可通路径
private bool[] potClick = new bool[6];
private int[] potMax = new int[6];//保存神经猫最远的可移动方向
private int cl1;
private int cl2;
private int cl3;
private int cr1;
private int cr2;
private int cr3;
List<int> lisPot = new List<int>();
// Use this for initialization
void Start()
{
cat = GameObject.Find("cat");
manager = GameObject.Find("GameManager");
}
// Update is called once per frame
void Update()
{
}
public void OnMouseDown()
{
if (manager.GetComponent<StartGame>().F == true || manager.GetComponent<StartGame>().V == true||manager.GetComponent<StartGame>().P==true)
return;
// print("x="+this.transform.position.x+",y="+this.transform.position.y);
this.GetComponent<Pot1>().isClick = true;
this.GetComponent<Pot1>().Changes();
CheckPot();
CatP();
}
public void CheckPot()
{
int max;
int min;
for (int i = 0; i < potClick.Length; i++)
{
potClick[i] = false;
}
//当6个移动方向为不可通路劲时,寻找神经猫可移动的最远的的方向
if (CheckLeft1() != true && CheckRight1() != true && CheckLeft2() != true && CheckRight2() != true && CheckLeft3() != true && CheckRight3() != true)
{
max = 0;
for (int i = 1; i < 6; i++)
{
if (potMax[max] < potMax[i])
max = i;
}
potClick[max] = true;
}
//寻找神经猫的最短可通路径
else if (CheckLeft1() || CheckRight1() || CheckLeft2() || CheckRight2() || CheckLeft3() || CheckRight3())
{
CheckLeft1();
CheckRight1();
CheckLeft2();
CheckRight2();
CheckLeft3();
CheckRight3();
for (int i = 0; i < 6; i++)
{
if (potNum[i] <= 0)
{
print("i=" + i+","+potNum[i]);
potNum[i] = 10;
}
}
min = 0;
for (int i = 1; i < 6; i++)
{
if (potNum[min] > potNum[i])
min = i;
}
potClick[min] = true;
}
}
public void CatP()
{
int row;
if (cat.GetComponent<CatMove>().y % 2 != 0)
{
MoveOdd();
row = 1;//猫在奇数行
print("奇数");
}
else
{
MoveEven();
row = -1;//猫在偶数行
print("偶数");
}
}
/// <summary>
/// 奇数行:左上x轴不变,右上x轴+0.5,左下x轴不变,右下x轴+0.5
/// </summary>
public void MoveOdd()
{
//左上
if (CheckLeft1() == true && potClick[0])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
}
//右上
else if (CheckRight1() && potClick[1])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
cat.GetComponent<CatMove>().x++;
}
//左边
else if (CheckLeft2() && potClick[2])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x--;
}
//右边
else if (CheckRight2() && potClick[3])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x++;
}
//左下
else if (CheckLeft3() && potClick[4])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
}
//右下
else if (CheckRight3() && potClick[5])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
cat.GetComponent<CatMove>().x++;
}
//非通路径检测
//左上
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].GetComponent<Pot1>().isClick == false && potClick[0])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
}
//右上
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y - 1].GetComponent<Pot1>().isClick == false && potClick[1])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
cat.GetComponent<CatMove>().x++;
}
//左边
else if ((manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].GetComponent<Pot1>().isClick == false) && potClick[2])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x--;
}
//右边
else if ((manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].GetComponent<Pot1>().isClick == false) && potClick[3])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x++;
}
//左下
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].GetComponent<Pot1>().isClick == false && potClick[4])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
}
//右下
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y + 1].GetComponent<Pot1>().isClick == false && potClick[5])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
cat.GetComponent<CatMove>().x++;
}
}
/// <summary>
/// 偶数行:左上x轴-0.5,右上x轴不变,左下x轴-0.5,右下x轴不变
/// </summary>
public void MoveEven()
{
//左上
if (CheckLeft1() == true && potClick[0])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
cat.GetComponent<CatMove>().x--;
}
//右上
else if (CheckRight1() && potClick[1])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
}
//左边
else if (CheckLeft2() && potClick[2])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x--;
}
//右边
else if (CheckRight2() && potClick[3])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x++;
}
//左下
else if (CheckLeft3() && potClick[4])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
cat.GetComponent<CatMove>().x--;
}
//右下
else if (CheckRight3() && potClick[5])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
}
//非通路劲检测
//左上
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y - 1].GetComponent<Pot1>().isClick == false && potClick[0])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
cat.GetComponent<CatMove>().x--;
}
//右上
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].GetComponent<Pot1>().isClick == false && potClick[1])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y - 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y--;
}
//左边
else if ((manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].GetComponent<Pot1>().isClick == false) && potClick[2])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x--;
}
//右边
else if ((manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].GetComponent<Pot1>().isClick == false) && potClick[3])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x + 1, cat.GetComponent<CatMove>().y].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().x++;
}
//左下
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y + 1].GetComponent<Pot1>().isClick == false && potClick[4])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x - 1, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
cat.GetComponent<CatMove>().x--;
}
//右下
else if (manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].GetComponent<Pot1>().isClick == false && potClick[5])
{
float x = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.x;
float y = manager.GetComponent<StartGame>().pots[cat.GetComponent<CatMove>().x, cat.GetComponent<CatMove>().y + 1].transform.position.y;
cat.GetComponent<CatMove>().Move(x, y + 0.4f);
cat.GetComponent<CatMove>().y++;
}
}
/// <summary>
/// 左上通路径检测
/// </summary>
/// <returns></returns>
public bool CheckLeft1()
{
int tempx = cat.GetComponent<CatMove>().x;
int tempy = cat.GetComponent<CatMove>().y;
bool checkResult = true;
potNum[0] = 0;
cl1 = 0;
potMax[0] = 0;
while (checkResult)
{
if (tempx == 0 || tempy == 0)
{
potNum[0] = cl1;
return true;
}
if (tempy % 2 != 0)
{
//猫在奇数行
checkResult = oddCheckLeft1(tempx, tempy);
tempy--;
}
else
{
//猫在偶数行
checkResult = evenCheckLeft1(tempx, tempy);
tempx--;
tempy--;
}
}
return false;
}
/// <summary>
/// 奇数行检测
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool oddCheckLeft1(int x, int y)
{
if (manager.GetComponent<StartGame>().pots[x, y - 1].GetComponent<Pot1>().isClick == false)
{
// potNum[0]++;
potMax[0]++;
cl1++;
return true;
}
else
return false;
}
/// <summary>
/// 偶数行检测
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool evenCheckLeft1(int x, int y)
{
if (manager.GetComponent<StartGame>().pots[x - 1, y - 1].GetComponent<Pot1>().isClick == false)
{
//potNum[0]++;
potMax[0]++;
cl1++;
return true;
}
else
return false;
}
/// <summary>
/// 右上通路径检测
/// </summary>
/// <returns></returns>
public bool CheckRight1()
{
int tempx = cat.GetComponent<CatMove>().x;
int tempy = cat.GetComponent<CatMove>().y;
bool checkResult = true;
potNum[1] = 0;
potMax[1] = 0;
cr1 = 0;
while (checkResult == true)
{
if (tempy == 0 || tempx == 8)
{
potNum[1] = cr1;
return true;
}
if (tempy % 2 != 0)
{
checkResult = oddCheckRight1(tempx, tempy);
tempx++;
tempy--;
}
else
{
checkResult = evenCheckRight1(tempx, tempy);
tempy--;
}
}
return false;
}
/// <summary>
/// 奇数行检测
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool oddCheckRight1(int x, int y)
{
if (manager.GetComponent<StartGame>().pots[x + 1, y - 1].GetComponent<Pot1>().isClick == false)
{
// potNum[1]++;
potMax[1]++;
cr1++;
return true;
}
else
return false;
}
/// <summary>
/// 偶数行检测
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public bool evenCheckRight1(int x, int y)
{
if (manager.GetComponent<StartGame>().pots[x, y - 1].GetComponent<Pot1>().isClick == false)
{
// potNum[1]++;
potMax[1]++;
cr1++;
return true;
}
else
return false;
}
/// <summary>
/// 左边通路检测
/// </summary>
/// <returns></returns>
public bool CheckLeft2()
{
int tempx = cat.GetComponent<CatMove>().x;
int tempy = cat.GetComponent<CatMove>().y;
bool checkResult = true;
potNum[2] = 0;
potMax[2] = 0;
cl2 = 0