public virtual List <Tile> GetAlgorithmSteps(Labyrinths.ILabyrinth labyrinth) { var state = new AlgorithmExecutionState(); ResetProgressState(state, labyrinth); while (GetNextStep(state, labyrinth, out Tile tile)) { } return(state.algorithmSteps); }
// Up, right down, left public override Direction[] GetPrioritizedDirections( AlgorithmExecutionState state, Labyrinths.ILabyrinth labyrinth) { Direction[] prioritizedDirections = new Direction[4]; if (state.direction == (int)Direction.Up) { return(new Direction[] { Direction.Right, Direction.Up, Direction.Left, Direction.Down }); } else if (state.direction == (int)Direction.Down) { return(new Direction[] { Direction.Left, Direction.Down, Direction.Right, Direction.Up }); } else if (state.direction == (int)Direction.Left) { return(new Direction[] { Direction.Up, Direction.Left, Direction.Down, Direction.Right }); } else if (state.direction == (int)Direction.Right) { return(new Direction[] { Direction.Down, Direction.Right, Direction.Up, Direction.Left }); } return(prioritizedDirections); }
public virtual Tile ResetProgressState(AlgorithmExecutionState state, Labyrinths.ILabyrinth labyrinth) { state.algorithmSteps = new List <Tile>(); state.isTileAlreadyVisited = new bool[labyrinth.GetLabyrithXLenght(), labyrinth.GetLabyrithYLenght()]; state.hasReachedTheEnd = false; state.lastRemoved = null; state.direction = labyrinth.StartDirection; state.position = labyrinth.StartPos; state.endPosition = labyrinth.EndPos; state.isTileAlreadyVisited[state.position.x, state.position.y] = true; state.stack.Add(new Action { pos = state.position, dir = (Direction)state.direction }); return(new Tile(state.position.x, state.position.y, TileColor.Yellow)); }
// Up, right down, left // Originally base on: // https://github.com/ferenc-nemeth/maze-generation-algorithms/blob/757c6289286387ad661813e6ecc0ec04edea30c0/solver/solver.cpp // void maze::solver::wall_follower public virtual bool GetNextStep( AlgorithmExecutionState state, Labyrinths.ILabyrinth labyrinth, out Tile tile) { tile = new Tile(); Direction[] prioritizedDirections = GetPrioritizedDirections(state, labyrinth); Vector2Int dest = state.position; bool found = false; for (int i = 0; i < 4; i++) { if (prioritizedDirections[i] == Direction.Up) { if (labyrinth.GetIsTileWalkable( dest = Promoscience.Utils.GetMoveDestination(state.position, Direction.Up)) && !state.IsAlreadyVisisted(dest)) { state.direction = (int)Direction.Up; found = true; break; } } else if (prioritizedDirections[i] == Direction.Down) { if (labyrinth.GetIsTileWalkable( dest = Promoscience.Utils.GetMoveDestination(state.position, Direction.Down)) && !state.IsAlreadyVisisted(dest)) { state.direction = (int)Direction.Down; found = true; break; } } else if (prioritizedDirections[i] == Direction.Left) { if (labyrinth.GetIsTileWalkable( dest = Promoscience.Utils.GetMoveDestination(state.position, Direction.Left)) && !state.IsAlreadyVisisted(dest)) { state.direction = (int)Direction.Left; found = true; break; } } else if (prioritizedDirections[i] == Direction.Right) { if (labyrinth.GetIsTileWalkable( dest = Promoscience.Utils.GetMoveDestination(state.position, Direction.Right)) && !state.IsAlreadyVisisted(dest)) { state.direction = (int)Direction.Right; found = true; break; } } } if (found) { // FIX: Return to last if (state.lastRemoved != null) { state.stack.Add(state.lastRemoved); state.lastRemoved = null; } state.stack.Add(new Action { pos = dest, dir = (Direction)state.direction, }); state.SetVisited(dest); tile = new Tile { Position = state.position, Color = TileColor.Yellow }; // FIX: If in dead end, use end of the stack instead (backtracking) if ( state.algorithmSteps.Count > 0 && tile.Position == state.algorithmSteps[state.algorithmSteps.Count - 1].Position) { state.algorithmSteps.RemoveAt(state.algorithmSteps.Count - 1); } state.position = dest; state.hasReachedTheEnd = state.position == labyrinth.EndPos; } else if (state.stack.Count != 0) { int last = state.stack.Count - 1; tile = new Tile { // FIX: if we have pushed a yellow tile, red when popped, otherwise yellow when popped Position = state.position, Color = TileColor.Red }; // FIX: If in dead end, use end of the stack instead (backtracking) if ( state.algorithmSteps.Count > 0 && tile.Position == state.algorithmSteps[state.algorithmSteps.Count - 1].Position) { state.algorithmSteps.RemoveAt(state.algorithmSteps.Count - 1); } state.position = state.stack[last].pos; state.direction = (int)Promoscience.Utils.GetOppositeDirection(state.stack[last].dir); state.lastRemoved = state.stack[last]; state.stack.RemoveAt(last); } // Do add tile state.algorithmSteps.Add(tile); return(!state.hasReachedTheEnd); }
public abstract Direction[] GetPrioritizedDirections(AlgorithmExecutionState state, Labyrinths.ILabyrinth labyrinth);
public AlgorithmExecution( Algorithm algorithm, Labyrinths.ILabyrinth labyrinth) { steps = algorithm.GetAlgorithmSteps(labyrinth); }