Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace DungeonPathfinder {
- #region toolClasses
- class Pos
- {
- public int X { get; set; }
- public int Y { get; set; }
- public int Z { get; set; }
- public Pos(int x, int y, int z)
- {
- X = x;
- Y = y;
- Z = z;
- }
- }
- class Explorer
- {
- public static List<Pos> AllHistory { get; set; } //collection of all positions in maze explored by any Explorer object
- public static bool BeenExplored(Pos p)
- {
- return AllHistory.Any(h => h.X == p.X && h.Y == p.Y && h.Z == p.Z);
- }
- public Pos Position { get; private set; }
- public List<Pos> Path { get; private set; } //the path that this explorer object has traversed
- public Explorer(int x, int y, int z)
- {
- Position = new Pos(x, y, z);
- Path = new List<Pos>();
- Path.Add(Position);
- if (Explorer.AllHistory == null)
- {
- Explorer.AllHistory = new List<Pos>();
- }
- if (!Explorer.BeenExplored(Position)) {
- Explorer.AllHistory.Add(Position);
- }
- }
- public Explorer newPosition(int x, int y, int z)
- {
- Explorer newEx = new Explorer(x, y, z);
- newEx.Path = Path.ToList();
- newEx.Path.Add(Position);
- if (!Explorer.BeenExplored(Position)) {
- Explorer.AllHistory.Add(Position);
- }
- return newEx;
- }
- }
- #endregion toolClasses
- internal class Program
- {
- private static void Main(string[] args) {
- #region setupMap
- string[] file = System.IO.File.ReadAllLines("maze.txt");
- int width = file.Max(l => l.Length);
- int depth = 1;
- int height = 0;
- int checkHeight = 0;
- for (int l = 0; l < file.Length; l++)
- {
- if (file[l].Trim() == ""){
- depth++;
- if (checkHeight > height)
- height = checkHeight;
- checkHeight = 0;
- }
- else
- {
- checkHeight++;
- }
- }
- char[,,] mazeTxt = new char[width, height, depth];
- Pos start = new Pos(-1, -1, -1);
- int floor = 0;
- int lineOffset = 0;
- for (int l = 0; l < file.Length; l++) //convert maze file to a 3-dimensional char array
- {
- if (file[l].Trim() == "")
- {
- floor++;
- l++;
- lineOffset = l;
- }
- char[] line = file[l].ToCharArray();
- for (int c = 0; c < line.Length; c++)
- {
- if (line[c] == 'S') //make sure there is a start position
- {
- start = new Pos(c, l - lineOffset, floor);
- }
- mazeTxt[c, l - lineOffset, floor] = line[c];
- }
- }
- if (start.X == -1 || start.Y == -1 || start.Z == -1)
- {
- throw new Exception("Start not found");
- }
- #endregion setupMap
- int explorerCount = 0;
- if (args.Length == 0)
- {
- #region exploreMap
- List<Explorer> explorerList = new List<Explorer>() {new Explorer(start.X, start.Y, start.Z)};
- //will hold a list of Explorer objects representing one generation of the exploration
- Explorer reachedFinish = null; //will hold the Explorer object that reaches the exit
- while (reachedFinish == null)
- {
- List<Explorer> newExplorerList = new List<Explorer>();
- foreach (Explorer explorer in explorerList) //go through each explorer in the list
- {
- Pos thisRoom = explorer.Position;
- if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'G') //make sure we haven't reached the exit
- {
- reachedFinish = explorer;
- break;
- }
- else
- {
- List<Pos> directionList = new List<Pos>()
- //check the four cardinal directions around the current position
- {
- new Pos(thisRoom.X + 1, thisRoom.Y, thisRoom.Z),
- new Pos(thisRoom.X - 1, thisRoom.Y, thisRoom.Z),
- new Pos(thisRoom.X, thisRoom.Y + 1, thisRoom.Z),
- new Pos(thisRoom.X, thisRoom.Y - 1, thisRoom.Z)
- };
- //add directions for up and down if indicated
- if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'U')
- directionList.Add(new Pos(thisRoom.X, thisRoom.Y, thisRoom.Z - 1));
- if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'D')
- directionList.Add(new Pos(thisRoom.X, thisRoom.Y, thisRoom.Z + 1));
- foreach (Pos direction in directionList)
- {
- if (mazeTxt[direction.X, direction.Y, direction.Z] != '#' &&
- !Explorer.BeenExplored(direction))
- //if the searched direction isn't a wall or a location that has allready been explored...
- {
- newExplorerList.Add(explorer.newPosition(direction.X, direction.Y, direction.Z));
- //...generate a new Explorer object for that position and add it to the list for the next generation.
- }
- }
- }
- }
- explorerList = newExplorerList;
- if (explorerList.Count() > explorerCount)
- explorerCount = explorerList.Count();
- if (!explorerList.Any() && reachedFinish == null)
- {
- throw new Exception("No path to exit");
- }
- }
- #endregion exploreMap
- #region writePath
- for (int x = 0; x < reachedFinish.Path.Count(); x++)
- //once an Explorer has found the exit, go through the path it took and write it to the maze array
- {
- Pos pos = reachedFinish.Path[x];
- Pos lastPos = (x == 0 ? pos : reachedFinish.Path[x - 1]);
- Pos nextPos = (x == reachedFinish.Path.Count() - 1 ? pos : reachedFinish.Path[x + 1]);
- if (!new[] {'S', 'G', 'U', 'D'}.Contains(mazeTxt[pos.X, pos.Y, pos.Z])) //fancy path graphics
- {
- if (lastPos.Z > pos.Z)
- mazeTxt[pos.X, pos.Y, pos.Z] = '↑';
- else if (lastPos.Z < pos.Z)
- mazeTxt[pos.X, pos.Y, pos.Z] = '↓';
- else if ((lastPos.X > nextPos.X && lastPos.Y > nextPos.Y && lastPos.Y == pos.Y) ||
- (lastPos.X < nextPos.X && lastPos.Y < nextPos.Y && lastPos.X == pos.X))
- mazeTxt[pos.X, pos.Y, pos.Z] = '└';
- else if ((lastPos.X > nextPos.X && lastPos.Y > nextPos.Y && lastPos.X == pos.X) ||
- (lastPos.X < nextPos.X && lastPos.Y < nextPos.Y && lastPos.Y == pos.Y))
- mazeTxt[pos.X, pos.Y, pos.Z] = '┐';
- else if ((lastPos.X > nextPos.X && lastPos.Y < nextPos.Y && lastPos.Y == pos.Y) ||
- (lastPos.X < nextPos.X && lastPos.Y > nextPos.Y && lastPos.X == pos.X))
- mazeTxt[pos.X, pos.Y, pos.Z] = '┌';
- else if ((lastPos.X > nextPos.X && lastPos.Y < nextPos.Y && lastPos.X == pos.X) ||
- (lastPos.X < nextPos.X && lastPos.Y > nextPos.Y && lastPos.Y == pos.Y))
- mazeTxt[pos.X, pos.Y, pos.Z] = '┘';
- else if (lastPos.X == pos.X)
- mazeTxt[pos.X, pos.Y, pos.Z] = '│';
- else if (lastPos.Y == pos.Y)
- mazeTxt[pos.X, pos.Y, pos.Z] = '─';
- }
- }
- /*foreach (Pos pos in Explorer.AllHistory)
- //indicate on the maze all the explored paths that didn't lead to the exit
- {
- if (mazeTxt[pos.X, pos.Y, pos.Z] == ' ')
- mazeTxt[pos.X, pos.Y, pos.Z] = '*';
- }*/
- #endregion writePath
- }
- #region displayCompleted
- Console.ForegroundColor = ConsoleColor.Gray;
- for (int z = 0; z < depth; z++)
- {
- for (int y = 0; y < height; y++)
- {
- string line = "";
- for (int x = 0; x < width; x++)
- {
- if (args.Length > 0 && args[0] == "mo")
- {
- Console.Write(mazeTxt[x, y, z]);
- }
- else
- {
- ConsoleColor color;
- if (mazeTxt[x, y, z] == '#')
- color = ConsoleColor.Gray;
- else if (mazeTxt[x, y, z] == '*')
- color = ConsoleColor.Green;
- else if (mazeTxt[x, y, z] == 'S' || mazeTxt[x, y, z] == 'G')
- color = ConsoleColor.Red;
- else if (mazeTxt[x, y, z] == 'U' || mazeTxt[x, y, z] == 'D')
- color = ConsoleColor.DarkYellow;
- else
- color = ConsoleColor.Yellow;
- Console.ForegroundColor = color;
- Console.Write(mazeTxt[x, y, z]);
- Console.ForegroundColor = ConsoleColor.Gray;
- }
- }
- Console.Write(Environment.NewLine);
- }
- Console.Write(Environment.NewLine);
- }
- if (args.Length == 0)
- {
- Console.WriteLine("Maximum explorers: " + explorerCount);
- }
- Console.ReadLine();
- #endregion displayCompleted
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment