Guest User

Dungeon Explorer

a guest
Dec 3rd, 2015
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.19 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace DungeonPathfinder {
  6.     #region toolClasses
  7.     class Pos
  8.     {
  9.         public int X { get; set; }
  10.         public int Y { get; set; }
  11.         public int Z { get; set; }
  12.  
  13.         public Pos(int x, int y, int z)
  14.         {
  15.             X = x;
  16.             Y = y;
  17.             Z = z;
  18.         }
  19.     }
  20.  
  21.     class Explorer
  22.     {
  23.         public static List<Pos> AllHistory { get; set; } //collection of all positions in maze explored by any Explorer object
  24.  
  25.         public static bool BeenExplored(Pos p)
  26.         {
  27.             return AllHistory.Any(h => h.X == p.X && h.Y == p.Y && h.Z == p.Z);
  28.         }
  29.  
  30.         public Pos Position { get; private set; }
  31.         public List<Pos> Path { get; private set; } //the path that this explorer object has traversed
  32.  
  33.         public Explorer(int x, int y, int z)
  34.         {
  35.             Position = new Pos(x, y, z);
  36.             Path = new List<Pos>();
  37.             Path.Add(Position);
  38.  
  39.             if (Explorer.AllHistory == null)
  40.             {
  41.                 Explorer.AllHistory = new List<Pos>();
  42.             }
  43.  
  44.             if (!Explorer.BeenExplored(Position)) {
  45.                 Explorer.AllHistory.Add(Position);
  46.             }
  47.         }
  48.  
  49.         public Explorer newPosition(int x, int y, int z)
  50.         {
  51.             Explorer newEx = new Explorer(x, y, z);
  52.             newEx.Path = Path.ToList();
  53.             newEx.Path.Add(Position);
  54.  
  55.  
  56.             if (!Explorer.BeenExplored(Position)) {
  57.                 Explorer.AllHistory.Add(Position);
  58.             }
  59.  
  60.             return newEx;
  61.         }
  62.     }
  63.     #endregion toolClasses
  64.  
  65.     internal class Program
  66.     {
  67.         private static void Main(string[] args) {
  68.             #region setupMap
  69.  
  70.             string[] file = System.IO.File.ReadAllLines("maze.txt");
  71.  
  72.             int width = file.Max(l => l.Length);
  73.             int depth = 1;
  74.             int height = 0;
  75.  
  76.             int checkHeight = 0;
  77.  
  78.             for (int l = 0; l < file.Length; l++)
  79.             {
  80.                 if (file[l].Trim() == ""){
  81.                     depth++;
  82.                     if (checkHeight > height)
  83.                         height = checkHeight;
  84.                     checkHeight = 0;
  85.                 }
  86.                 else
  87.                 {
  88.                     checkHeight++;
  89.                 }
  90.             }
  91.  
  92.             char[,,] mazeTxt = new char[width, height, depth];
  93.  
  94.             Pos start = new Pos(-1, -1, -1);
  95.  
  96.             int floor = 0;
  97.             int lineOffset = 0;
  98.  
  99.             for (int l = 0; l < file.Length; l++) //convert maze file to a 3-dimensional char array
  100.             {
  101.  
  102.                 if (file[l].Trim() == "")
  103.                 {
  104.                     floor++;
  105.                     l++;
  106.                     lineOffset = l;
  107.                 }
  108.  
  109.                 char[] line = file[l].ToCharArray();
  110.                 for (int c = 0; c < line.Length; c++)
  111.                 {
  112.                     if (line[c] == 'S') //make sure there is a start position
  113.                     {
  114.                         start = new Pos(c, l - lineOffset, floor);
  115.                     }
  116.  
  117.                     mazeTxt[c, l - lineOffset, floor] = line[c];
  118.                 }
  119.         }
  120.  
  121.             if (start.X == -1 || start.Y == -1 || start.Z == -1)
  122.             {
  123.                 throw new Exception("Start not found");
  124.             }
  125.  
  126.            
  127.             #endregion setupMap
  128.  
  129.             int explorerCount = 0;
  130.  
  131.             if (args.Length == 0)
  132.             {
  133.                 #region exploreMap
  134.  
  135.                 List<Explorer> explorerList = new List<Explorer>() {new Explorer(start.X, start.Y, start.Z)};
  136.                 //will hold a list of Explorer objects representing one generation of the exploration
  137.  
  138.                 Explorer reachedFinish = null; //will hold the Explorer object that reaches the exit
  139.  
  140.                
  141.  
  142.                 while (reachedFinish == null)
  143.                 {
  144.                     List<Explorer> newExplorerList = new List<Explorer>();
  145.  
  146.                     foreach (Explorer explorer in explorerList) //go through each explorer in the list
  147.                     {
  148.                         Pos thisRoom = explorer.Position;
  149.  
  150.                         if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'G') //make sure we haven't reached the exit
  151.                         {
  152.                             reachedFinish = explorer;
  153.                             break;
  154.                         }
  155.                         else
  156.                         {
  157.                             List<Pos> directionList = new List<Pos>()
  158.                                 //check the four cardinal directions around the current position
  159.                             {
  160.                                 new Pos(thisRoom.X + 1, thisRoom.Y, thisRoom.Z),
  161.                                 new Pos(thisRoom.X - 1, thisRoom.Y, thisRoom.Z),
  162.                                 new Pos(thisRoom.X, thisRoom.Y + 1, thisRoom.Z),
  163.                                 new Pos(thisRoom.X, thisRoom.Y - 1, thisRoom.Z)
  164.                             };
  165.  
  166.                             //add directions for up and down if indicated
  167.                             if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'U')
  168.                                 directionList.Add(new Pos(thisRoom.X, thisRoom.Y, thisRoom.Z - 1));
  169.  
  170.                             if (mazeTxt[thisRoom.X, thisRoom.Y, thisRoom.Z] == 'D')
  171.                                 directionList.Add(new Pos(thisRoom.X, thisRoom.Y, thisRoom.Z + 1));
  172.  
  173.                             foreach (Pos direction in directionList)
  174.                             {
  175.                                 if (mazeTxt[direction.X, direction.Y, direction.Z] != '#' &&
  176.                                     !Explorer.BeenExplored(direction))
  177.                                     //if the searched direction isn't a wall or a location that has allready been explored...
  178.                                 {
  179.                                     newExplorerList.Add(explorer.newPosition(direction.X, direction.Y, direction.Z));
  180.                                     //...generate a new Explorer object for that position and add it to the list for the next generation.
  181.                                 }
  182.                             }
  183.                         }
  184.                     }
  185.  
  186.                     explorerList = newExplorerList;
  187.  
  188.                     if (explorerList.Count() > explorerCount)
  189.                         explorerCount = explorerList.Count();
  190.  
  191.                     if (!explorerList.Any() && reachedFinish == null)
  192.                     {
  193.                         throw new Exception("No path to exit");
  194.                     }
  195.                 }
  196.  
  197.                 #endregion exploreMap
  198.  
  199.  
  200.                 #region writePath
  201.  
  202.                 for (int x = 0; x < reachedFinish.Path.Count(); x++)
  203.                     //once an Explorer has found the exit, go through the path it took and write it to the maze array
  204.                 {
  205.                     Pos pos = reachedFinish.Path[x];
  206.                     Pos lastPos = (x == 0 ? pos : reachedFinish.Path[x - 1]);
  207.                     Pos nextPos = (x == reachedFinish.Path.Count() - 1 ? pos : reachedFinish.Path[x + 1]);
  208.  
  209.                     if (!new[] {'S', 'G', 'U', 'D'}.Contains(mazeTxt[pos.X, pos.Y, pos.Z])) //fancy path graphics
  210.                     {
  211.                         if (lastPos.Z > pos.Z)
  212.                             mazeTxt[pos.X, pos.Y, pos.Z] = '↑';
  213.                         else if (lastPos.Z < pos.Z)
  214.                             mazeTxt[pos.X, pos.Y, pos.Z] = '↓';
  215.                         else if ((lastPos.X > nextPos.X && lastPos.Y > nextPos.Y && lastPos.Y == pos.Y) ||
  216.                             (lastPos.X < nextPos.X && lastPos.Y < nextPos.Y && lastPos.X == pos.X))
  217.                             mazeTxt[pos.X, pos.Y, pos.Z] = '└';
  218.                         else if ((lastPos.X > nextPos.X && lastPos.Y > nextPos.Y && lastPos.X == pos.X) ||
  219.                                  (lastPos.X < nextPos.X && lastPos.Y < nextPos.Y && lastPos.Y == pos.Y))
  220.                             mazeTxt[pos.X, pos.Y, pos.Z] = '┐';
  221.                         else if ((lastPos.X > nextPos.X && lastPos.Y < nextPos.Y && lastPos.Y == pos.Y) ||
  222.                                  (lastPos.X < nextPos.X && lastPos.Y > nextPos.Y && lastPos.X == pos.X))
  223.                             mazeTxt[pos.X, pos.Y, pos.Z] = '┌';
  224.                         else if ((lastPos.X > nextPos.X && lastPos.Y < nextPos.Y && lastPos.X == pos.X) ||
  225.                                  (lastPos.X < nextPos.X && lastPos.Y > nextPos.Y && lastPos.Y == pos.Y))
  226.                             mazeTxt[pos.X, pos.Y, pos.Z] = '┘';
  227.                         else if (lastPos.X == pos.X)
  228.                             mazeTxt[pos.X, pos.Y, pos.Z] = '│';
  229.                         else if (lastPos.Y == pos.Y)
  230.                             mazeTxt[pos.X, pos.Y, pos.Z] = '─';
  231.                     }
  232.                 }
  233.  
  234.                 /*foreach (Pos pos in Explorer.AllHistory)
  235.                     //indicate on the maze all the explored paths that didn't lead to the exit
  236.                 {
  237.                     if (mazeTxt[pos.X, pos.Y, pos.Z] == ' ')
  238.                         mazeTxt[pos.X, pos.Y, pos.Z] = '*';
  239.  
  240.                 }*/
  241.  
  242.                 #endregion writePath
  243.             }
  244.  
  245.             #region displayCompleted
  246.  
  247.             Console.ForegroundColor = ConsoleColor.Gray;
  248.             for (int z = 0; z < depth; z++)
  249.             {
  250.  
  251.                 for (int y = 0; y < height; y++)
  252.  
  253.                 {
  254.                     string line = "";
  255.                     for (int x = 0; x < width; x++)
  256.                     {
  257.                         if (args.Length > 0 && args[0] == "mo")
  258.                         {
  259.                             Console.Write(mazeTxt[x, y, z]);
  260.                         }
  261.                         else
  262.                         {
  263.                             ConsoleColor color;
  264.  
  265.                             if (mazeTxt[x, y, z] == '#')
  266.                                 color = ConsoleColor.Gray;
  267.                             else if (mazeTxt[x, y, z] == '*')
  268.                                 color = ConsoleColor.Green;
  269.                             else if (mazeTxt[x, y, z] == 'S' || mazeTxt[x, y, z] == 'G')
  270.                                 color = ConsoleColor.Red;
  271.                             else if (mazeTxt[x, y, z] == 'U' || mazeTxt[x, y, z] == 'D')
  272.                                 color = ConsoleColor.DarkYellow;
  273.                             else
  274.                                 color = ConsoleColor.Yellow;
  275.  
  276.                             Console.ForegroundColor = color;
  277.                             Console.Write(mazeTxt[x, y, z]);
  278.                             Console.ForegroundColor = ConsoleColor.Gray;
  279.                         }
  280.  
  281.                     }
  282.                     Console.Write(Environment.NewLine);
  283.                 }
  284.                 Console.Write(Environment.NewLine);
  285.             }
  286.  
  287.             if (args.Length == 0)
  288.             {
  289.                 Console.WriteLine("Maximum explorers: " + explorerCount);
  290.             }
  291.  
  292.             Console.ReadLine();
  293.  
  294.             #endregion displayCompleted
  295.  
  296.         }
  297.     }
  298. }
Advertisement
Add Comment
Please, Sign In to add comment