使用了 unity 完成,因为 unity 非常方便图形显示
Maze.cs
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
public class Maze : MonoBehaviour
{
public int StartIndex;
public int EndIndex;
private int[,] MazeArray;
private const int row = 7;
private const int col = 7;
private GameObject Player;
private bool success = false;
private Stack<int> Path = new Stack<int>();
void Awake()
{
// 创建迷宫
MazeArray = new int[row, col]
{
{1, 1, 1, 1, 1, 1, 1},
{1, 1, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 1, 0, 1},
{1, 0, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1},
};
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
if(MazeArray[i, j] == 1)
{
CreateCube(i, j, CubeType.Wall);
}
else
{
CreateCube(i, j, CubeType.Path);
}
}
}
// 设置迷宫的起始位置和终点位置
Vector2 pos = GetPositionByIndex(StartIndex);
Player = CreateCube((int)pos.x, (int)pos.y, CubeType.Player);
pos = GetPositionByIndex(EndIndex);
CreateCube((int)pos.x, (int)pos.y, CubeType.Exit);
}
void Start ()
{
// 激活玩家,开始探索
MazePlayer player = new MazePlayer();
player.LoadMaze(MazeArray, StartIndex, EndIndex);
success = player.Search(ref Path);
if(success)
{
// 开始移动。。。。
StartCoroutine(Move());
}
}
IEnumerator Move()
{
if(Path.Count <= 0)
yield break;
Vector2 pos = GetPositionByIndex(Path.Pop());
Player.transform.position = new Vector3(pos.x, pos.y, -0.2f);
yield return new WaitForSeconds(0.4f);
StartCoroutine(Move());
}
private GameObject CreateCube(int i, int j, CubeType type)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.parent = transform;
cube.gameObject.transform.position = new Vector3(i, j, 0);
cube.transform.rotation = Quaternion.identity;
switch(type)
{
case CubeType.Wall:
cube.name = "Wall";
cube.renderer.material.color = Color.cyan;
break;
case CubeType.Player:
cube.name = "Player";
cube.renderer.material.color = Color.green;
cube.gameObject.transform.position = new Vector3(i, j, -0.2f);
break;
case CubeType.Exit:
cube.name = "Exit";
cube.renderer.material.color = Color.red;
cube.gameObject.transform.position = new Vector3(i, j, -0.1f);
break;
}
return cube;
}
private Vector2 GetPositionByIndex(int index)
{
int tempRow = index/ col;
int tempCol = index - tempRow * col;
return new Vector2(tempRow, tempCol);
}
private enum CubeType
{
Wall,
Path,
Player,
Exit,
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MazePlayer
{
private int _StartPos;
private int _EndPos;
private int[,] _MazeArray;
private int _RowSize;
private int _ColSize;
public class Node
{
public int Index;
public bool CanPass;
public int Direction;
public bool FootPrint;
public Node(int index, bool canPass)
{
this.Index = index;
this.CanPass = canPass;
this.Direction = 0;
this.FootPrint = false;
}
}
private List<Node> _NodeList = new List<Node>();
public Stack<Node> PathStack{get; private set;}
public void LoadMaze(int[,] maze, int startPos, int endPos)
{
_MazeArray = maze;
_RowSize = _MazeArray.GetLength(0);
_ColSize = _MazeArray.GetLength(1);
for(int i = 0; i < _RowSize; i++)
{
for(int j = 0; j < _ColSize; j++)
{
Node node = new Node(i * _RowSize + j, _MazeArray[i, j] == 0);
_NodeList.Add(node);
}
}
this._StartPos = startPos;
this._EndPos = endPos;
}
public bool Search(ref Stack<int> Path)
{
PathStack = new Stack<Node>();
PathStack.Push(_NodeList[_StartPos]);
do{
// 查看当前块是否可通过
Node node = PathStack.Peek();
if(node.CanPass)
{
if(node.Index == _EndPos)
{
break;
}
MarkPrint(node);
// 顺时针方向加入节点四个方向的块
if(node.Direction < 4)
{
node.Direction++;
int index = GetNextNodeIndex(node.Index, node.Direction);
Node nextNode = _NodeList[index];
if(nextNode.FootPrint == false)
{
PathStack.Push(nextNode);
}
}
else
{
node = PathStack.Pop();
node.CanPass = false;
}
}
else
{
node = PathStack.Pop();
node.CanPass = false;
}
}while(PathStack.Count > 0);
if(PathStack.Count > 0)
{
while(PathStack.Count > 0)
{
Node node = PathStack.Pop();
Path.Push(node.Index);
}
return true;
}
return false;
}
private void MarkPrint(Node node)
{
node.FootPrint = true;
}
private int GetNextNodeIndex(int crtIndex, int direction)
{
int crtRow = crtIndex / _ColSize;
int crtCol = crtIndex - crtRow * _ColSize;
int nextRow = crtRow;
int nextCol = crtCol;
if(direction == 1)
{
nextRow--;
}
else if(direction == 2)
{
nextCol++;
}
else if(direction == 3)
{
nextRow++;
}
else
{
nextCol--;
}
return nextRow * _ColSize + nextCol;
}
}