From 1e70b4c1f14ebba9f04217d4ae5a17cd0024a6ff Mon Sep 17 00:00:00 2001 From: Dan Cojocaru Date: Wed, 1 Dec 2021 22:55:49 +0200 Subject: [PATCH] Added IDA* control step Added flow control to find start+destination points, and increase the threshold if a search doesn't reach the destination. Next step: implement search. --- IDAstar.cs | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 6 deletions(-) diff --git a/IDAstar.cs b/IDAstar.cs index b52aeca..2222969 100644 --- a/IDAstar.cs +++ b/IDAstar.cs @@ -1,9 +1,9 @@ using System.Collections.ObjectModel; -using System.Threading.Channels; -namespace IdaStar { +namespace IdaStar +{ - public enum CellState { + public enum CellState { EMPTY, OBSTACLE, START, @@ -41,7 +41,13 @@ namespace IdaStar { } } - public class WorkingBoard { + public record struct Point(int Row, int Column) { + public int ManhattanDistance(Point otherPoint) { + return Math.Abs(Row - otherPoint.Row) + Math.Abs(Column - otherPoint.Column); + } + } + + public class WorkingBoard { readonly List> _board; public WorkingBoard(List> board) { @@ -65,11 +71,74 @@ namespace IdaStar { public event Action? AlgorithmStep; - public void RunIdaStar() { - throw new NotImplementedException(); + /// + /// Clean board, making it ready for a new run. + /// + /// This is achieved by setting all PATH states to EMPTY states. + /// + public void Reset() { + foreach (var row in _board) { + for (var i = 0; i < row.Count; i++) { + if (row[i] == CellState.PATH) { + row[i] = CellState.EMPTY; + } + } + } + } + + public void RunIdaStar() => RunIdaStar(0, 1, (p1, p2) => p1.ManhattanDistance(p2)); + public void RunIdaStar(Comp zero, Comp increment, Func heuristic) where Comp: IComparable { + // Don't run algorithm on a "dirty" board + // "dirty" = the algorithm was already ran before + if (_board.Select((row) => row.Where((state) => state == CellState.PATH).Count()).Any((cnt) => cnt > 0)) { + throw new DirtyBoardException(); + } + + Point findPoint(CellState neededState) { + for (var i = 0; i < _board.Count; i++) { + for (var j = 0; j < _board[i].Count; j++) { + if (_board[i][j] == CellState.START) { + return new(i, j); + } + } + } + throw new NoPoint(neededState); + } + + Point startPoint = findPoint(CellState.START); + + Point destinationPoint = findPoint(CellState.DESTINATION); + + Comp search(Point current, Comp cost, Comp threshold) { + throw new NotImplementedException(); + } + + var threshold = heuristic(startPoint, destinationPoint); + while (threshold.CompareTo(zero) == 0) { + threshold = search(startPoint, zero, threshold); + } } } + [System.Serializable] + public class DirtyBoardException : System.Exception + { + public DirtyBoardException() : base("The board is dirty (contains path cells)") { } + public DirtyBoardException(System.Exception inner) : base("The board is dirty (contains path cells)", inner) { } + protected DirtyBoardException( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } + + [System.Serializable] + public class NoPoint : System.Exception + { + public NoPoint(CellState neededState) : base($"The board doesn't contain any {neededState} point") { } + public NoPoint(CellState neededState, System.Exception inner) : base($"The board doesn't contain any {neededState} point", inner) { } + protected NoPoint( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) : base(info, context) { } + } } /*