mirror of
https://github.com/Stone-Red-Code/Maze.git
synced 2026-09-05 23:41:09 +02:00
Initial commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
using Maze.Nodes;
|
||||
|
||||
namespace Maze.Utlis;
|
||||
|
||||
internal class MazeParser
|
||||
{
|
||||
public T[,] FromFile<T>(string filePath, out T startNode) where T : BaseMazeNode<T>, new()
|
||||
{
|
||||
return FromString(File.ReadAllText(filePath), out startNode);
|
||||
}
|
||||
|
||||
public T[,] FromString<T>(string input, out T startNode) where T : BaseMazeNode<T>, new()
|
||||
{
|
||||
string[] lines = input.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
|
||||
|
||||
startNode = null!;
|
||||
T? goalNode = null;
|
||||
T[,] nodes = new T[lines.Length, lines[0].Length];
|
||||
|
||||
// Create nodes from input
|
||||
for (int y = 0; y < lines.Length; y++)
|
||||
{
|
||||
for (int x = 0; x < lines[0].Length; x++)
|
||||
{
|
||||
char c = lines[y][x];
|
||||
|
||||
T node = new T
|
||||
{
|
||||
Wall = c == '+',
|
||||
Start = c == 'S',
|
||||
Goal = c == 'G'
|
||||
};
|
||||
|
||||
if (node.Start)
|
||||
{
|
||||
if (startNode is not null)
|
||||
{
|
||||
throw new MazeException("Multiple start nodes found.");
|
||||
}
|
||||
|
||||
startNode = node;
|
||||
}
|
||||
|
||||
if (node.Goal)
|
||||
{
|
||||
if (goalNode is not null)
|
||||
{
|
||||
throw new MazeException("Multiple goal nodes found.");
|
||||
}
|
||||
goalNode = node;
|
||||
}
|
||||
|
||||
nodes[y, x] = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (startNode is null)
|
||||
{
|
||||
throw new MazeException("No start node found.");
|
||||
}
|
||||
|
||||
if (goalNode is null)
|
||||
{
|
||||
throw new MazeException("No goal node found.");
|
||||
}
|
||||
|
||||
// Add neighbors to nodes based on their position in the maze
|
||||
for (int y = 0; y < lines.Length; y++)
|
||||
{
|
||||
for (int x = 0; x < lines[0].Length; x++)
|
||||
{
|
||||
T node = nodes[y, x];
|
||||
|
||||
if (x < lines[0].Length - 1)
|
||||
{
|
||||
node.Neighbors.Add(nodes[y, x + 1]);
|
||||
}
|
||||
if (x > 0)
|
||||
{
|
||||
node.Neighbors.Add(nodes[y, x - 1]);
|
||||
}
|
||||
if (y < lines.Length - 1)
|
||||
{
|
||||
node.Neighbors.Add(nodes[y + 1, x]);
|
||||
}
|
||||
if (y > 0)
|
||||
{
|
||||
node.Neighbors.Add(nodes[y - 1, x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using Maze.Nodes;
|
||||
|
||||
using Stone_Red_Utilities.ConsoleExtentions;
|
||||
|
||||
namespace Maze.Utlis;
|
||||
|
||||
internal class MazePrinter
|
||||
{
|
||||
public void Print<T>(T[,] nodes, List<T>? solution = null, bool redrawAll = false) where T : BaseMazeNode<T>
|
||||
{
|
||||
for (int y = 0; y < nodes.GetLength(0); y++)
|
||||
{
|
||||
for (int x = 0; x < nodes.GetLength(1); x++)
|
||||
{
|
||||
T node = nodes[y, x];
|
||||
|
||||
if (!node.Updated && !redrawAll)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
node.Updated = false;
|
||||
|
||||
Console.SetCursorPosition(x, y);
|
||||
|
||||
if (node.Wall)
|
||||
{
|
||||
Console.Write('+');
|
||||
}
|
||||
else if (node.Start)
|
||||
{
|
||||
Console.Write('S');
|
||||
}
|
||||
else if (node.Goal)
|
||||
{
|
||||
Console.Write('G');
|
||||
}
|
||||
else if (solution?.Contains(node) == true)
|
||||
{
|
||||
Console.Write(GetDirection(x, y, node, nodes, solution));
|
||||
}
|
||||
else if (node.Visited)
|
||||
{
|
||||
Console.Write('-');
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PrintColored<T>(T[,] nodes, List<T>? solution = null, bool redrawAll = false) where T : BaseMazeNode<T>
|
||||
{
|
||||
Console.BackgroundColor = ConsoleColor.Black;
|
||||
Console.CursorVisible = false;
|
||||
|
||||
for (int y = 0; y < nodes.GetLength(0); y++)
|
||||
{
|
||||
for (int x = 0; x < nodes.GetLength(1); x++)
|
||||
{
|
||||
T node = nodes[y, x];
|
||||
|
||||
if (!node.Updated && !redrawAll)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
node.Updated = false;
|
||||
|
||||
Console.SetCursorPosition(x, y);
|
||||
|
||||
if (node.Wall)
|
||||
{
|
||||
ConsoleExt.Write('+', ConsoleColor.White);
|
||||
}
|
||||
else if (node.Start)
|
||||
{
|
||||
ConsoleExt.Write('S', ConsoleColor.Magenta);
|
||||
}
|
||||
else if (node.Goal)
|
||||
{
|
||||
ConsoleExt.Write('G', ConsoleColor.Red);
|
||||
}
|
||||
else if (solution?.Contains(node) == true)
|
||||
{
|
||||
ConsoleExt.Write(GetDirection(x, y, node, nodes, solution), ConsoleColor.Green);
|
||||
}
|
||||
else if (node.Visited)
|
||||
{
|
||||
ConsoleExt.Write('-', ConsoleColor.DarkGray);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.ResetColor();
|
||||
Console.CursorVisible = false;
|
||||
}
|
||||
|
||||
// Get the direction of the next node in the solution list
|
||||
private static char GetDirection<T>(int x, int y, T node, T[,] nodes, List<T> solution)
|
||||
{
|
||||
int index = solution.IndexOf(node);
|
||||
T? nextNode = solution.ElementAtOrDefault(index - 1);
|
||||
|
||||
if (y > 0 && nextNode?.Equals(nodes[y - 1, x]) == true)
|
||||
{
|
||||
return '^';
|
||||
}
|
||||
else if (y < nodes.GetLength(0) - 1 && nextNode?.Equals(nodes[y + 1, x]) == true)
|
||||
{
|
||||
return 'v';
|
||||
}
|
||||
else if (x > 0 && nextNode?.Equals(nodes[y, x - 1]) == true)
|
||||
{
|
||||
return '<';
|
||||
}
|
||||
else if (x < nodes.GetLength(1) - 1 && nextNode?.Equals(nodes[y, x + 1]) == true)
|
||||
{
|
||||
return '>';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'O';
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user