private IPlayerMove CreateNewMove(bool checkOpenings, int?overrideSearchDepth = null) { var isMaximizing = IsPlayerWhite; Diagnostics.StartMoveCalculations(); // Common start measures if (Settings.UseTranspositionTables) { // Delete old entries from tables var transpositions = Board.Shared.Transpositions.Tables; if (transpositions.Any()) { var toBeDeleted = new List <ulong>(); var currentTurnCount = Board.Shared.GameTurnCount; foreach (var transposition in transpositions) { // If transposition.turn 20 < current 25 - 4 if (transposition.Value.GameTurnCount < currentTurnCount - Settings.ClearSavedTranspositionsAfterTurnsPassed) { toBeDeleted.Add(transposition.Key); } } foreach (var hash in toBeDeleted) { transpositions.Remove(hash); } if (Settings.UseFullDiagnostics) { if (toBeDeleted.Any()) { Diagnostics.AddMessage($"Deleted {toBeDeleted.Count} old transposition entries."); } Diagnostics.AddMessage($"Total transpositions: {transpositions.Count}."); } } } // Opening if (GameHistory.Count < 10 && checkOpenings) { var previousMoves = GetPreviousMoves(); var openingMove = Openings.NextMove(previousMoves); if (openingMove != null) { var openingMoveWithData = Board.CollectMoveProperties(openingMove); Board.ExecuteMove(openingMoveWithData); Board.Shared.GameTurnCount++; PreviousData = Diagnostics.CollectAndClear(); var result = new PlayerMoveImplementation( openingMove.ToInterfaceMove(), PreviousData.ToString()); GameHistory.Add(result.Move); return(result); } } // Get all available moves and do necessary filtering List <SingleMove> allMoves = Board.Moves(isMaximizing, true, true).ToList(); if (allMoves.Count == 0) { // Game ended to stalemate throw new ArgumentException( $"No possible moves for player [isWhite={IsPlayerWhite}]. Game should have ended to draw (stalemate)."); } if (MoveHistory.IsLeaningToDraw(GameHistory)) { // Take 4th from the end of list var repetionMove = GameHistory[^ 4];
public override IPlayerMove CreateMove() { if (_connectionTestOverride) { var diagnostics = Diagnostics.CollectAndClear(); // Dummy moves for connection testing var move = new PlayerMoveImplementation() { Move = new MoveImplementation() { StartPosition = $"a{_connectionTestIndex--}", EndPosition = $"a{_connectionTestIndex}", PromotionResult = PromotionPieceType.NoPromotion }, Diagnostics = diagnostics.ToString() }; return(move); } else { var isMaximizing = IsPlayerWhite; Diagnostics.StartMoveCalculations(); // Get all available moves and do necessary filtering List <SingleMove> allMoves = Board.Moves(isMaximizing, true, true).ToList(); if (allMoves.Count == 0) { throw new ArgumentException($"No possible moves for player [isWhite={IsPlayerWhite}]. Game should have ended to draw (stalemate)."); } // Reorder moves to improve alpha-beta cutoffs // allMoves = MoveResearch.OrderMoves(allMoves, Board, isMaximizing); if (MoveHistory.IsLeaningToDraw(GameHistory)) { var repetionMove = GameHistory[GameHistory.Count - 4]; allMoves.RemoveAll(m => m.PrevPos.ToAlgebraic() == repetionMove.StartPosition && m.NewPos.ToAlgebraic() == repetionMove.EndPosition); } Diagnostics.AddMessage($"Available moves found: {allMoves.Count}. "); Strategy.Update(PreviousData, TurnCount); var strategyResult = Strategy.DecideSearchDepth(PreviousData, allMoves, Board); SearchDepth = strategyResult.searchDepth; Phase = strategyResult.gamePhase; var bestMove = AnalyzeBestMove(allMoves); if (bestMove == null) { throw new ArgumentException($"Board didn't contain any possible move for player [isWhite={IsPlayerWhite}]."); } // Update local Board.ExecuteMove(bestMove); TurnCount++; // Endgame checks // TODO should be now read from singlemove var castling = false; var check = Board.IsCheck(IsPlayerWhite); //var checkMate = false; //if(check) checkMate = Board.IsCheckMate(IsPlayerWhite, true); if (bestMove.Promotion) { Diagnostics.AddMessage($"Promotion occured at {bestMove.NewPos.ToAlgebraic()}. "); } PreviousData = Diagnostics.CollectAndClear(); var move = new PlayerMoveImplementation() { Move = bestMove.ToInterfaceMove(castling, check), Diagnostics = PreviousData.ToString() }; GameHistory.Add(move.Move); return(move); } }