Fix wrong piecetype in GameMoveHistory
This commit is contained in:
parent
c9242fd749
commit
c318cb4ca0
5 changed files with 138 additions and 100 deletions
|
@ -25,9 +25,23 @@ namespace ChessChallenge.API
|
|||
/// Create a new board. Note: this should not be used in the challenge,
|
||||
/// use the board provided in the Think method instead.
|
||||
/// </summary>
|
||||
public Board(Chess.Board board)
|
||||
public Board(Chess.Board boardSource)
|
||||
{
|
||||
this.board = board;
|
||||
// Clone board and create game move history
|
||||
board = new Chess.Board();
|
||||
board.LoadPosition(boardSource.StartPositionInfo);
|
||||
GameMoveHistory = new Move[boardSource.AllGameMoves.Count];
|
||||
|
||||
for (int i = 0; i < boardSource.AllGameMoves.Count; i ++)
|
||||
{
|
||||
Chess.Move move = boardSource.AllGameMoves[i];
|
||||
int movePieceType = PieceHelper.PieceType(board.Square[move.StartSquareIndex]);
|
||||
int capturePieceType = PieceHelper.PieceType(board.Square[move.TargetSquareIndex]);
|
||||
GameMoveHistory[i] = new Move(move, movePieceType, capturePieceType);
|
||||
board.MakeMove(move, false);
|
||||
}
|
||||
|
||||
// Init move gen
|
||||
moveGen = new APIMoveGen();
|
||||
cachedLegalMoves = Array.Empty<Move>();
|
||||
cachedLegalCaptureMoves = Array.Empty<Move>();
|
||||
|
@ -49,11 +63,7 @@ namespace ChessChallenge.API
|
|||
// Init rep history
|
||||
repetitionHistory = new HashSet<ulong>(board.RepetitionPositionHistory);
|
||||
GameRepetitionHistory = repetitionHistory.ToArray();
|
||||
GameRepetitionHistory.Reverse();
|
||||
repetitionHistory.Remove(board.ZobristKey);
|
||||
|
||||
// Init game moves history
|
||||
GameMoveHistory = board.AllGameMoves.Select(m => new Move(MoveUtility.GetMoveNameUCI(m), this)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -142,9 +142,7 @@ namespace ChessChallenge.Application
|
|||
|
||||
Move GetBotMove()
|
||||
{
|
||||
// Board b = new Board();
|
||||
// b.LoadPosition(FenUtility.CurrentFen(board));
|
||||
API.Board botBoard = new(new(board));
|
||||
API.Board botBoard = new(board);
|
||||
try
|
||||
{
|
||||
API.Timer timer = new(PlayerToMove.TimeRemainingMs);
|
||||
|
|
|
@ -268,12 +268,13 @@ namespace ChessChallenge.Application
|
|||
static void MiscTest()
|
||||
{
|
||||
Console.WriteLine("Running Misc Tests");
|
||||
|
||||
// Captures
|
||||
var board = new Chess.Board();
|
||||
board.LoadPosition("1q3rk1/P5p1/4p2p/2ppP1N1/5Qb1/1PP5/7P/2R2RK1 w - - 0 28");
|
||||
boardAPI = new(board);
|
||||
Assert(boardAPI.IsWhiteToMove, "Colour to move wrong");
|
||||
|
||||
//var moves = boardAPI.GetLegalMoves();
|
||||
var captures = boardAPI.GetLegalMoves(true);
|
||||
Assert(captures.Length == 4, "Captures wrong");
|
||||
int numTested = 0;
|
||||
|
@ -308,6 +309,20 @@ namespace ChessChallenge.Application
|
|||
}
|
||||
}
|
||||
Assert(numTested == 4, "Target square wrong");
|
||||
|
||||
// Game moves
|
||||
string startPos = "r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 1 2";
|
||||
board.LoadPosition(startPos);
|
||||
board.MakeMove(MoveUtility.GetMoveFromUCIName("e4e5", board), false);
|
||||
board.MakeMove(MoveUtility.GetMoveFromUCIName("c6e5", board), false);
|
||||
var b = new Chess.Board(board);
|
||||
boardAPI = new(b);
|
||||
Assert(boardAPI.GameMoveHistory[0].MovePieceType is PieceType.Pawn, "Wrong game move history");
|
||||
Assert(boardAPI.GameMoveHistory[0].CapturePieceType is PieceType.None, "Wrong game move history");
|
||||
Assert(boardAPI.GameMoveHistory[1].MovePieceType is PieceType.Knight, "Wrong game move history");
|
||||
Assert(boardAPI.GameMoveHistory[1].CapturePieceType is PieceType.Pawn, "Wrong game move history");
|
||||
Assert(boardAPI.GameStartFenString == startPos, "Wrong game start fen");
|
||||
Assert(boardAPI.GetFenString() == "r1bqkbnr/pppppppp/8/4n3/8/8/PPPP1PPP/RNBQKBNR w KQkq - 0 3", "Wrong game fen");
|
||||
}
|
||||
|
||||
static void MoveGenTest()
|
||||
|
|
|
@ -59,7 +59,8 @@ namespace ChessChallenge.Chess
|
|||
public GameState currentGameState;
|
||||
|
||||
public List<Move> AllGameMoves;
|
||||
public string GameStartFen { get; private set; }
|
||||
public string GameStartFen => StartPositionInfo.fen;
|
||||
public FenUtility.PositionInfo StartPositionInfo;
|
||||
|
||||
// piece count excluding pawns and kings
|
||||
public int totalPieceCountWithoutPawnsAndKings;
|
||||
|
@ -72,16 +73,13 @@ namespace ChessChallenge.Chess
|
|||
{
|
||||
if (source != null)
|
||||
{
|
||||
string fen = FenUtility.CurrentFen(source);
|
||||
LoadPosition(fen);
|
||||
|
||||
RepetitionPositionHistory = new(source.RepetitionPositionHistory);
|
||||
AllGameMoves = new(source.AllGameMoves);
|
||||
|
||||
currentGameState = source.currentGameState;
|
||||
LoadPosition(source.StartPositionInfo);
|
||||
|
||||
for (int i = 0; i < source.AllGameMoves.Count; i++)
|
||||
{
|
||||
MakeMove(source.AllGameMoves[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -470,9 +468,13 @@ namespace ChessChallenge.Chess
|
|||
// Load custom position from fen string
|
||||
public void LoadPosition(string fen)
|
||||
{
|
||||
LoadPosition(FenUtility.PositionFromFen(fen));
|
||||
}
|
||||
|
||||
public void LoadPosition(FenUtility.PositionInfo posInfo)
|
||||
{
|
||||
StartPositionInfo = posInfo;
|
||||
Initialize();
|
||||
GameStartFen = fen;
|
||||
FenUtility.PositionInfo posInfo = FenUtility.PositionFromFen(fen);
|
||||
|
||||
// Load pieces into board array and piece lists
|
||||
for (int squareIndex = 0; squareIndex < 64; squareIndex++)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace ChessChallenge.Chess
|
||||
{
|
||||
|
@ -11,72 +13,7 @@ namespace ChessChallenge.Chess
|
|||
public static PositionInfo PositionFromFen(string fen)
|
||||
{
|
||||
|
||||
PositionInfo loadedPositionInfo = new PositionInfo();
|
||||
string[] sections = fen.Split(' ');
|
||||
|
||||
int file = 0;
|
||||
int rank = 7;
|
||||
|
||||
foreach (char symbol in sections[0])
|
||||
{
|
||||
if (symbol == '/')
|
||||
{
|
||||
file = 0;
|
||||
rank--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (char.IsDigit(symbol))
|
||||
{
|
||||
file += (int)char.GetNumericValue(symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pieceColour = (char.IsUpper(symbol)) ? PieceHelper.White : PieceHelper.Black;
|
||||
int pieceType = char.ToLower(symbol) switch
|
||||
{
|
||||
'k' => PieceHelper.King,
|
||||
'p' => PieceHelper.Pawn,
|
||||
'n' => PieceHelper.Knight,
|
||||
'b' => PieceHelper.Bishop,
|
||||
'r' => PieceHelper.Rook,
|
||||
'q' => PieceHelper.Queen,
|
||||
_ => PieceHelper.None
|
||||
};
|
||||
|
||||
loadedPositionInfo.squares[rank * 8 + file] = pieceType | pieceColour;
|
||||
file++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loadedPositionInfo.whiteToMove = (sections[1] == "w");
|
||||
|
||||
string castlingRights = sections[2];
|
||||
loadedPositionInfo.whiteCastleKingside = castlingRights.Contains("K");
|
||||
loadedPositionInfo.whiteCastleQueenside = castlingRights.Contains("Q");
|
||||
loadedPositionInfo.blackCastleKingside = castlingRights.Contains("k");
|
||||
loadedPositionInfo.blackCastleQueenside = castlingRights.Contains("q");
|
||||
|
||||
if (sections.Length > 3)
|
||||
{
|
||||
string enPassantFileName = sections[3][0].ToString();
|
||||
if (BoardHelper.fileNames.Contains(enPassantFileName))
|
||||
{
|
||||
loadedPositionInfo.epFile = BoardHelper.fileNames.IndexOf(enPassantFileName) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Half-move clock
|
||||
if (sections.Length > 4)
|
||||
{
|
||||
int.TryParse(sections[4], out loadedPositionInfo.fiftyMovePlyCount);
|
||||
}
|
||||
// Full move number
|
||||
if (sections.Length > 5)
|
||||
{
|
||||
int.TryParse(sections[5], out loadedPositionInfo.moveCount);
|
||||
}
|
||||
PositionInfo loadedPositionInfo = new(fen);
|
||||
return loadedPositionInfo;
|
||||
}
|
||||
|
||||
|
@ -273,27 +210,103 @@ namespace ChessChallenge.Chess
|
|||
}
|
||||
}
|
||||
|
||||
public class PositionInfo
|
||||
public readonly struct PositionInfo
|
||||
{
|
||||
public int[] squares;
|
||||
public readonly string fen;
|
||||
public readonly ReadOnlyCollection<int> squares;
|
||||
|
||||
// Castling rights
|
||||
public bool whiteCastleKingside;
|
||||
public bool whiteCastleQueenside;
|
||||
public bool blackCastleKingside;
|
||||
public bool blackCastleQueenside;
|
||||
public readonly bool whiteCastleKingside;
|
||||
public readonly bool whiteCastleQueenside;
|
||||
public readonly bool blackCastleKingside;
|
||||
public readonly bool blackCastleQueenside;
|
||||
// En passant file (1 is a-file, 8 is h-file, 0 means none)
|
||||
public int epFile;
|
||||
public bool whiteToMove;
|
||||
public readonly int epFile;
|
||||
public readonly bool whiteToMove;
|
||||
// Number of half-moves since last capture or pawn advance
|
||||
// (starts at 0 and increments after each player's move)
|
||||
public int fiftyMovePlyCount;
|
||||
public readonly int fiftyMovePlyCount;
|
||||
// Total number of moves played in the game
|
||||
// (starts at 1 and increments after black's move)
|
||||
public int moveCount;
|
||||
public readonly int moveCount;
|
||||
|
||||
public PositionInfo()
|
||||
public PositionInfo(string fen)
|
||||
{
|
||||
squares = new int[64];
|
||||
this.fen = fen;
|
||||
int[] squarePieces = new int[64];
|
||||
|
||||
string[] sections = fen.Split(' ');
|
||||
|
||||
int file = 0;
|
||||
int rank = 7;
|
||||
|
||||
foreach (char symbol in sections[0])
|
||||
{
|
||||
if (symbol == '/')
|
||||
{
|
||||
file = 0;
|
||||
rank--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (char.IsDigit(symbol))
|
||||
{
|
||||
file += (int)char.GetNumericValue(symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
int pieceColour = (char.IsUpper(symbol)) ? PieceHelper.White : PieceHelper.Black;
|
||||
int pieceType = char.ToLower(symbol) switch
|
||||
{
|
||||
'k' => PieceHelper.King,
|
||||
'p' => PieceHelper.Pawn,
|
||||
'n' => PieceHelper.Knight,
|
||||
'b' => PieceHelper.Bishop,
|
||||
'r' => PieceHelper.Rook,
|
||||
'q' => PieceHelper.Queen,
|
||||
_ => PieceHelper.None
|
||||
};
|
||||
|
||||
squarePieces[rank * 8 + file] = pieceType | pieceColour;
|
||||
file++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
squares = new(squarePieces);
|
||||
|
||||
whiteToMove = (sections[1] == "w");
|
||||
|
||||
string castlingRights = sections[2];
|
||||
whiteCastleKingside = castlingRights.Contains('K');
|
||||
whiteCastleQueenside = castlingRights.Contains('Q');
|
||||
blackCastleKingside = castlingRights.Contains('k');
|
||||
blackCastleQueenside = castlingRights.Contains('q');
|
||||
|
||||
// Default values
|
||||
epFile = 0;
|
||||
fiftyMovePlyCount = 0;
|
||||
moveCount = 0;
|
||||
|
||||
if (sections.Length > 3)
|
||||
{
|
||||
string enPassantFileName = sections[3][0].ToString();
|
||||
if (BoardHelper.fileNames.Contains(enPassantFileName))
|
||||
{
|
||||
epFile = BoardHelper.fileNames.IndexOf(enPassantFileName) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Half-move clock
|
||||
if (sections.Length > 4)
|
||||
{
|
||||
int.TryParse(sections[4], out fiftyMovePlyCount);
|
||||
}
|
||||
// Full move number
|
||||
if (sections.Length > 5)
|
||||
{
|
||||
int.TryParse(sections[5], out moveCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue