mirror of
https://github.com/dancojocaru2000/ai-project-idastar.git
synced 2025-02-23 00:49:34 +02:00
Implement the rest of IDA*
This commit is contained in:
parent
1e70b4c1f1
commit
778ffca169
2 changed files with 87 additions and 4 deletions
86
IDAstar.cs
86
IDAstar.cs
|
@ -1,4 +1,9 @@
|
|||
using System.Runtime.Versioning;
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections;
|
||||
|
||||
[assembly: RequiresPreviewFeatures()]
|
||||
|
||||
namespace IdaStar
|
||||
{
|
||||
|
@ -45,6 +50,56 @@ namespace IdaStar
|
|||
public int ManhattanDistance(Point otherPoint) {
|
||||
return Math.Abs(Row - otherPoint.Row) + Math.Abs(Column - otherPoint.Column);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum NDirections : byte {
|
||||
N = 0b0000_0001,
|
||||
E = 0b0000_0010,
|
||||
S = 0b0000_0100,
|
||||
W = 0b0000_1000,
|
||||
NE = 0b0001_0000,
|
||||
SE = 0b0010_0000,
|
||||
SW = 0b0100_0000,
|
||||
NW = 0b1000_0000,
|
||||
}
|
||||
|
||||
public List<Point> GetNeighbours(byte directions = 0b1111) {
|
||||
List<Point> result = new();
|
||||
|
||||
if ((directions & ((byte)NDirections.N)) > 0) {
|
||||
result.Add(new(Row - 1, Column));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.E)) > 0) {
|
||||
result.Add(new(Row, Column + 1));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.S)) > 0) {
|
||||
result.Add(new(Row + 1, Column));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.W)) > 0) {
|
||||
result.Add(new(Row, Column - 1));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.NE)) > 0) {
|
||||
result.Add(new(Row - 1, Column + 1));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.SE)) > 0) {
|
||||
result.Add(new(Row + 1, Column + 1));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.SW)) > 0) {
|
||||
result.Add(new(Row + 1, Column - 1));
|
||||
}
|
||||
if ((directions & ((byte)NDirections.NW)) > 0) {
|
||||
result.Add(new(Row - 1, Column - 1));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsInsideBox(int Height, int Width) => IsInsideBox(new(Height - 1, Width - 1));
|
||||
public bool IsInsideBox(Point bottomRight) => IsInsideBox(new(0, 0), bottomRight);
|
||||
public bool IsInsideBox(Point topLeft, Point bottomRight) {
|
||||
return topLeft.Row <= Row && topLeft.Column <= Column &&
|
||||
Row <= bottomRight.Row && Column <= bottomRight.Column;
|
||||
}
|
||||
}
|
||||
|
||||
public class WorkingBoard {
|
||||
|
@ -87,7 +142,7 @@ namespace IdaStar
|
|||
}
|
||||
|
||||
public void RunIdaStar() => RunIdaStar(0, 1, (p1, p2) => p1.ManhattanDistance(p2));
|
||||
public void RunIdaStar<Comp>(Comp zero, Comp increment, Func<Point, Point, Comp> heuristic) where Comp: IComparable<Comp> {
|
||||
public void RunIdaStar<Num>(Num zero, Num increment, Func<Point, Point, Num> heuristic) where Num: INumber<Num> {
|
||||
// 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)) {
|
||||
|
@ -109,12 +164,35 @@ namespace IdaStar
|
|||
|
||||
Point destinationPoint = findPoint(CellState.DESTINATION);
|
||||
|
||||
Comp search(Point current, Comp cost, Comp threshold) {
|
||||
throw new NotImplementedException();
|
||||
Num search(Point current, Num cost, Num threshold) {
|
||||
var h = heuristic(current, destinationPoint);
|
||||
if (h == zero) {
|
||||
return h;
|
||||
}
|
||||
var f = cost + h;
|
||||
if (f > threshold) {
|
||||
return f;
|
||||
}
|
||||
var min = f;
|
||||
|
||||
foreach(var neighbour in current.GetNeighbours()) {
|
||||
if (!neighbour.IsInsideBox(_board.Count, _board[0].Count)) {
|
||||
continue;
|
||||
}
|
||||
var neighbourF = search(neighbour, cost + increment, threshold);
|
||||
if (neighbourF < min) {
|
||||
min = neighbourF;
|
||||
}
|
||||
if (min == zero) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
var threshold = heuristic(startPoint, destinationPoint);
|
||||
while (threshold.CompareTo(zero) == 0) {
|
||||
while (threshold == zero) {
|
||||
threshold = search(startPoint, zero, threshold);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Runtime.Experimental" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
Loading…
Add table
Reference in a new issue