From c31c5a9c3902e2c9608c03fd9ef45c054ade4f28 Mon Sep 17 00:00:00 2001 From: Kai Date: Sun, 1 Mar 2020 09:56:40 +0100 Subject: [PATCH] Add Debug Maze Generation to Prims --- Projects/Maze/Prims/Graph.cs | 48 ++++++++++ Projects/Maze/Prims/PrimsAlgorithm.cs | 49 ---------- Projects/Maze/Prims/PrimsMazeGenerator.cs | 104 +++++++++++++++------- 3 files changed, 119 insertions(+), 82 deletions(-) diff --git a/Projects/Maze/Prims/Graph.cs b/Projects/Maze/Prims/Graph.cs index 324b3fb9..edb3aa33 100644 --- a/Projects/Maze/Prims/Graph.cs +++ b/Projects/Maze/Prims/Graph.cs @@ -31,5 +31,53 @@ public Graph(Node[] nodes) { Nodes = nodes ?? throw new ArgumentNullException(nameof(nodes)); } + + public static Maze.Tile[,] ConvertToGrid(Graph graph, int rows, int columns, Func index, int start_row, int start_column, int end_row, int end_column) + { + var tiles = new Maze.Tile[rows, columns]; + + foreach (var node in graph.Nodes) + { + if (node == null) + continue; + + (int, int) Unpack(int i) => (i % rows, i / rows); + + var (row, col) = Unpack(node.OwnIndex); + + // directional + if (node.Connections.Contains(index(row - 1, col))) + { + tiles[row, col] |= Maze.Tile.Up; + tiles[row - 1, col] |= Maze.Tile.Down; + } + if (node.Connections.Contains(index(row + 1, col))) + { + tiles[row, col] |= Maze.Tile.Down; + tiles[row + 1, col] |= Maze.Tile.Up; + } + if (node.Connections.Contains(index(row, col - 1))) + { + tiles[row, col] |= Maze.Tile.Left; + tiles[row, col - 1] |= Maze.Tile.Right; + } + if (node.Connections.Contains(index(row, col + 1))) + { + tiles[row, col] |= Maze.Tile.Right; + tiles[row, col + 1] |= Maze.Tile.Left; + } + + // start/end + if (row == start_row && col == start_column) + { + tiles[row, col] |= Maze.Tile.Start; + } + if (row == end_row && col == end_column) + { + tiles[row, col] |= Maze.Tile.End; + } + } + return tiles; + } } } diff --git a/Projects/Maze/Prims/PrimsAlgorithm.cs b/Projects/Maze/Prims/PrimsAlgorithm.cs index 42b2609c..111c6b50 100644 --- a/Projects/Maze/Prims/PrimsAlgorithm.cs +++ b/Projects/Maze/Prims/PrimsAlgorithm.cs @@ -5,55 +5,6 @@ namespace Prims { public static class PrimsAlgorithm { - private readonly struct TwoWayConnection : IComparable - { - public readonly int IndexA; - public readonly int IndexB; - public readonly double Cost; - public TwoWayConnection(int indexA, int indexB, double cost) - { - IndexA = indexA; - IndexB = indexB; - Cost = cost; - } - - public int CompareTo(TwoWayConnection other) => other.Cost.CompareTo(Cost); // inversed because of how the heap works - } - - public static Graph SimplePrims(Graph graph) - { - var newGraph = new Graph(new Graph.Node[graph.Nodes.Length]); - var nodes = graph.Nodes; - var current = nodes[0]; - newGraph.Nodes[0] = new Graph.Node(0); - - var heap = new HeapArray(); - - while (true) - { - for (int i = 0; i < current.Connections.Count; i++) - { - heap.Enqueue(new TwoWayConnection(current.OwnIndex, current.Connections[i], current.Costs[i])); - } - - TwoWayConnection c; - do - { - if (heap.Count == 0) - { - return newGraph; - } - c = heap.Dequeue(); - } - while (newGraph.Nodes[c.IndexB] != null); - - newGraph.Nodes[c.IndexA].Add(c.IndexB, c.Cost); - - newGraph.Nodes[c.IndexB] = new Graph.Node(c.IndexB); - current = graph.Nodes[c.IndexB]; - newGraph.Nodes[c.IndexB].Add(c.IndexA, c.Cost); - } - } } } \ No newline at end of file diff --git a/Projects/Maze/Prims/PrimsMazeGenerator.cs b/Projects/Maze/Prims/PrimsMazeGenerator.cs index 3db0c1fd..236b9f6d 100644 --- a/Projects/Maze/Prims/PrimsMazeGenerator.cs +++ b/Projects/Maze/Prims/PrimsMazeGenerator.cs @@ -1,4 +1,6 @@ -using System; +// #define DebugMazeGeneration +using System; +using Towel.DataStructures; namespace Prims { @@ -45,49 +47,85 @@ public class PrimsMazeGenerator } } - var res = PrimsAlgorithm.SimplePrims(new Graph(grid)); + var graph = new Graph(grid); + + #if DebugMazeGeneration + + Console.Clear(); + Console.WriteLine(Maze.Render(Graph.ConvertToGrid(graph, rows, columns, Index, start_row.Value, start_column.Value, end_row.Value, end_column.Value))); + Console.WriteLine("Press Enter To Continue..."); + Console.ReadLine(); + var res = SimplePrims(graph, rows, columns, Index, start_row.Value, start_column.Value, end_row.Value, end_column.Value); + #else + var res = SimplePrims(graph); + #endif - var tiles = new Maze.Tile[rows, columns]; + return Graph.ConvertToGrid(res, rows, columns, Index, start_row.Value, start_column.Value, end_row.Value, end_column.Value); + } + + private readonly struct TwoWayConnection : IComparable + { + public readonly int IndexA; + public readonly int IndexB; + public readonly double Cost; - foreach (var node in res.Nodes) + public TwoWayConnection(int indexA, int indexB, double cost) { - (int, int) Unpack(int i) => (i % rows, i / rows); + IndexA = indexA; + IndexB = indexB; + Cost = cost; + } - var (row, col) = Unpack(node.OwnIndex); + public int CompareTo(TwoWayConnection other) => other.Cost.CompareTo(Cost); // inversed because of how the heap works + } - // directional - if (node.Connections.Contains(Index(row - 1, col))) - { - tiles[row, col] |= Maze.Tile.Up; - tiles[row - 1, col] |= Maze.Tile.Down; - } - if (node.Connections.Contains(Index(row + 1, col))) - { - tiles[row, col] |= Maze.Tile.Down; - tiles[row + 1, col] |= Maze.Tile.Up; - } - if (node.Connections.Contains(Index(row, col - 1))) - { - tiles[row, col] |= Maze.Tile.Left; - tiles[row, col - 1] |= Maze.Tile.Right; - } - if (node.Connections.Contains(Index(row, col + 1))) - { - tiles[row, col] |= Maze.Tile.Right; - tiles[row, col + 1] |= Maze.Tile.Left; - } + public static Graph SimplePrims(Graph graph +#if DebugMazeGeneration + , int rows, int columns, Func index, int start_row, int start_column, int end_row, int end_column +#endif + + ) + { + var newGraph = new Graph(new Graph.Node[graph.Nodes.Length]); + var nodes = graph.Nodes; + var current = nodes[0]; + newGraph.Nodes[0] = new Graph.Node(0); - // start/end - if (row == start_row.Value && col == start_column.Value) + var heap = new HeapArray(); + + while (true) + { + for (int i = 0; i < current.Connections.Count; i++) { - tiles[row, col] |= Maze.Tile.Start; + heap.Enqueue(new TwoWayConnection(current.OwnIndex, current.Connections[i], current.Costs[i])); } - if (row == end_row.Value && col == end_column.Value) + + TwoWayConnection c; + do { - tiles[row, col] |= Maze.Tile.End; + if (heap.Count == 0) + { + return newGraph; + } + c = heap.Dequeue(); } + while (newGraph.Nodes[c.IndexB] != null); + + newGraph.Nodes[c.IndexA].Add(c.IndexB, c.Cost); + + newGraph.Nodes[c.IndexB] = new Graph.Node(c.IndexB); + current = graph.Nodes[c.IndexB]; + newGraph.Nodes[c.IndexB].Add(c.IndexA, c.Cost); + +#if DebugMazeGeneration + + Console.Clear(); + Console.WriteLine(Maze.Render(Graph.ConvertToGrid(newGraph, rows, columns, index, start_row, start_column, end_row, end_column))); + Console.WriteLine("Press Enter To Continue..."); + Console.ReadLine(); + +#endif } - return tiles; } } } \ No newline at end of file