Skip to content

Commit

Permalink
refactored decision engine; made a new model based on random sampling…
Browse files Browse the repository at this point in the history
… of position data
  • Loading branch information
sbrunaugh committed Feb 9, 2024
1 parent 958e192 commit 95133d4
Show file tree
Hide file tree
Showing 19 changed files with 279 additions and 160 deletions.
2 changes: 1 addition & 1 deletion DecisionEngine/src/Enums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static char PieceToChar(Piece p)
Piece.Bishop => 'B',
Piece.Knight => 'N',
Piece.Queen => 'Q',
Piece.King => 'N',
Piece.King => 'K',
_ => ' '
};
}
Expand Down
36 changes: 36 additions & 0 deletions DecisionEngine/src/Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using DecisionEngine.Helpers;

namespace DecisionEngine
{
public static class Extensions
{
public static int[] ToIntArray(this int[,] val)
{
var result = new int[64];

var i = 0;
foreach (var entry in val)
{
result[i] = entry;
i++;
}

return result;
}

public static int[,] ToIntMatrix(this int[] val)
{
var result = BoardHelper.GenerateFreshBoard();

for (var i = 0; i < 8; i++)
{
for (var j = 0; j < 8; j++)
{
result[i, j] = val[(i * 8) + j];
}
}

return result;
}
}
}
12 changes: 9 additions & 3 deletions DecisionEngine/src/Helpers/BishopHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace DecisionEngine.Helpers
{
public static class BishopHelper
{
public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var bishopValue = player == Player.White ? 3 : -3;

Expand All @@ -31,7 +31,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = bishopValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions DecisionEngine/src/Helpers/KingHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public static class KingHelper
[-1, 1]
];

public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var kingValue = player == Player.White ? 9 : -9;

Expand All @@ -41,7 +41,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)square.Row, (int)square.Column] = kingValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray(),
};
result.Add(move);
}
}
}
Expand Down
37 changes: 16 additions & 21 deletions DecisionEngine/src/Helpers/KnightHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ public static class KnightHelper
[-2, 1]
];

public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var knightValue = player == Player.White ? 2 : -2;

Expand All @@ -32,27 +32,22 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)

foreach (var x in potentialTargets)
{
if(player == Player.White)
{
// If target square is empty or has a black piece
if (BoardHelper.IntValueAt(board, (int)x.Row, (int)x.Column) <= 0)
{
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = knightValue;
result.Add(newBoard);
}
}
else
var condition = player == Player.White
? BoardHelper.IntValueAt(board, (int)x.Row, (int)x.Column) <= 0
: BoardHelper.IntValueAt(board, (int)x.Row, (int)x.Column) >= 0;

if(condition)
{
// If target square is empty or has a white piece
if (BoardHelper.IntValueAt(board, (int)x.Row, (int)x.Column) >= 0)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = knightValue;
var move = new Move()
{
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = knightValue;
result.Add(newBoard);
}
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}
}
Expand Down
70 changes: 21 additions & 49 deletions DecisionEngine/src/Helpers/MoveHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ namespace DecisionEngine.Helpers
{
public static class MoveHelper
{
public static List<int[,]> FindAllLegalCastles(int[,] board, Player player)
public static List<Move> FindAllLegalCastles(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();
var backRank = player == Player.White ? 0 : 7;
var rookVal = player == Player.White ? 5 : -5;
var kingVal = player == Player.White ? 9 : -9;
Expand All @@ -30,7 +30,13 @@ public static List<int[,]> FindAllLegalCastles(int[,] board, Player player)
newBoard[backRank, 2] = kingVal;
newBoard[backRank, 3] = rookVal;
newBoard[backRank, 4] = 0;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}

// King side - a side
Expand All @@ -49,7 +55,13 @@ public static List<int[,]> FindAllLegalCastles(int[,] board, Player player)
newBoard[backRank, 5] = rookVal;
newBoard[backRank, 6] = kingVal;
newBoard[backRank, 7] = 0;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}

return result;
Expand All @@ -70,57 +82,17 @@ internal static int PickRandomBestEvaluationIndex(List<float> evaluations, Playe
return indices[randomIndex];
}

internal static string GenerateMoveName(int[,] originalPosition, int[,] newPosition, Player player)
{
var diffs = new List<BoardDifference>();

if (diffs.Count == 4)
{
if (diffs.Any(d => d.j == (int)Column.a))
return "O-O-O";
else
return "O-O";
}

for (var i = 0; i < 8; i++)
{
for (var j = 0; j < 8; j++)
{
if (originalPosition[i, j] != newPosition[i, j])
{
diffs.Add(new BoardDifference(i, j, originalPosition[i, j], newPosition[i, j]));
}
}
}

if (player == Player.White)
diffs.OrderByDescending(d => d.newValue);
else
diffs.OrderBy(d => d.newValue);

var sb = new StringBuilder();
sb.Append(EnumHelper.PieceToChar((Piece)Math.Abs(diffs[0].newValue)));

if (diffs[0].originalValue != 0)
sb.Append('x');

sb.Append(EnumHelper.ColumnToChar((Column)diffs[0].j));
sb.Append(diffs[0].i + 1);

return sb.ToString();
}

public static void FilterOutMovesResultingInCheck(List<int[,]> positions, Player player)
public static void FilterOutMovesResultingInCheck(List<Move> moves, Player player)
{
var enemy = player == Player.White ? Player.Black : Player.White;
var kingValue = player == Player.White ? 9 : -9;
var indecesToRemove = new List<int>();

// Loop through all positions passed in
for (var i = 0; i < positions.Count; i++)
for (var i = 0; i < moves.Count; i++)
{
// Find every potential move enemy can make (not filtering out checks)
var enemeyMoves = Program.FindAllLegalMoves(positions[i], enemy, false);
var enemeyMoves = Program.FindAllLegalMoves(moves[i].NewPosition.ToIntMatrix(), enemy, false);
var containsCheck = false;

// Loop through all potential positions after next move
Expand All @@ -130,7 +102,7 @@ public static void FilterOutMovesResultingInCheck(List<int[,]> positions, Player
var isKingPresent = false;

// Loop through every piece on the board
foreach (int pieceValue in position)
foreach (int pieceValue in position.NewPosition)
{
if (pieceValue == kingValue)
isKingPresent = true; // King was found
Expand All @@ -148,7 +120,7 @@ public static void FilterOutMovesResultingInCheck(List<int[,]> positions, Player

foreach(var index in indecesToRemove)
{
positions.RemoveAt(index);
moves.RemoveAt(index);
}
}
}
Expand Down
27 changes: 20 additions & 7 deletions DecisionEngine/src/Helpers/PawnHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace DecisionEngine.Helpers
{
public static class PawnHelper
{
public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var pawnValue = player == Player.White ? 1 : -1;
var startingRow = player == Player.White ? 1 : 6;
Expand All @@ -18,7 +18,7 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
if (board[i, j] != pawnValue)
continue;

var targets = GetPotentialMoveSquares(new Square(i,j), player, i == startingRow);
var targets = GetPotentialMoveSquares(board, new Square(i,j), player, i == startingRow);
var captureTargets = GetPotentialCaptureSquares(new Square(i, j), player);

foreach (var x in targets)
Expand All @@ -28,7 +28,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = pawnValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}

Expand All @@ -43,7 +49,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = pawnValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}
}
Expand All @@ -52,13 +64,14 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
return result;
}

private static List<Square> GetPotentialMoveSquares(Square square, Player player, bool isStartingRow = false)
private static List<Square> GetPotentialMoveSquares(int[,] board, Square square, Player player, bool isStartingRow = false)
{
var result = new List<Square>();
var oneUpSquare = new Square(OneRowFoward((int)square.Row, player), (int)square.Column);
result.Add(oneUpSquare);

if(isStartingRow)
// Can't jump over other pieces
if(isStartingRow && !BoardHelper.IsSquareOccupied(board, oneUpSquare))
{
var twoUpSquare = new Square(TwoRowsFoward((int)square.Row, player), (int)square.Column);
result.Add(twoUpSquare);
Expand Down
12 changes: 9 additions & 3 deletions DecisionEngine/src/Helpers/QueenHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace DecisionEngine.Helpers
{
public static class QueenHelper
{
public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var queenValue = player == Player.White ? 8 : -8;

Expand All @@ -32,7 +32,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = queenValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions DecisionEngine/src/Helpers/RookHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ namespace DecisionEngine.Helpers
{
public static class RookHelper
{
public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
public static List<Move> FindAllLegalMoves(int[,] board, Player player)
{
var result = new List<int[,]>();
var result = new List<Move>();

var rookValue = player == Player.White ? 5 : -5;

Expand All @@ -31,7 +31,13 @@ public static List<int[,]> FindAllLegalMoves(int[,] board, Player player)
var newBoard = BoardHelper.DeepCopy(board);
newBoard[i, j] = 0;
newBoard[(int)x.Row, (int)x.Column] = rookValue;
result.Add(newBoard);
var move = new Move()
{
Player = player,
PriorPosition = board.ToIntArray(),
NewPosition = newBoard.ToIntArray()
};
result.Add(move);
}
}
}
Expand Down
Loading

0 comments on commit 95133d4

Please sign in to comment.