/// <summary> /// Does an AI move. /// </summary> private void MoveAI() { Task.Run(() => { var openingBookMove = _openingBook.GetMoveFromBook(_history); var enemyColor = ColorOperations.Invert(_currentColor); Move moveToApply = null; if (openingBookMove != null) { moveToApply = Bitboard.Moves.First(p => p.From == openingBookMove.From && p.To == openingBookMove.To); } else { var aiResult = _ai.Calculate(_currentColor, Bitboard, _preferredTime, _helperTasksCount); moveToApply = aiResult.PVNodes[0]; ConsoleManager.WriteLine(); ConsoleManager.WriteLine($"$w{_currentColor}:"); ConsoleManager.WriteLine($"$wBest move: $g{aiResult.PVNodes} $w(Score: $m{aiResult.Score}$w)"); ConsoleManager.WriteLine($"$wTotal nodes: $g{aiResult.Stats.TotalNodes} N $w(Depth: $m{aiResult.Depth}$w)"); ConsoleManager.WriteLine($"$wTime: $m{aiResult.Time} s"); ConsoleManager.WriteLine(); } CalculateBitboard(moveToApply, false); CheckIfGameHasEnded(Bitboard); _currentColor = enemyColor; _history.Add(moveToApply); }); }
/// <summary> /// Checks if king with the specified color is in stalemate. /// </summary> /// <param name="color">The king color.</param> /// <returns>True if king with specified color is in stalemate, otherwise false.</returns> public bool IsStalemate(Color color) { if (!_calculated) { throw new BitboardNotCalculatedException(); } var bitboardWithoutEnPassant = new Bitboard(this); bitboardWithoutEnPassant.EnPassant[(int)color] = 0; var ai = new AICore(); var aiResult = ai.Calculate(color, bitboardWithoutEnPassant, 0, 0); return(!IsCheck(color) && Math.Abs(aiResult.Score) == AIConstants.MateValue); }
/// <summary> /// Runs AI and does best found move. /// </summary> /// <param name="color">The engine color.</param> /// <returns>The AI result.</returns> public AIResult MoveAI(Color color) { Bitboard.Calculate(GeneratorMode.CalculateMoves | GeneratorMode.CalculateAttacks, false); CheckBitboardIntegrity(); UpdateMovesCount(color); if (CheckIfGameHasEnded()) { return(null); } var openingBookMove = _openingBook.GetMoveFromBook(_history); if (openingBookMove != null) { var moveToApply = Bitboard.Moves.First(p => p.From == openingBookMove.From && p.To == openingBookMove.To); Bitboard = Bitboard.Move(moveToApply); _history.Add(moveToApply); return(new AIResult() { PVNodes = new PVNodesList() { moveToApply } }); } else { var preferredTime = _preferredTimeCalculator.Calculate(MovesCount, _remainingTime[(int)color]); var aiResult = _aiCore.Calculate(color, Bitboard, preferredTime); // Temporary if (aiResult.PVNodes.Count < 1) { Console.WriteLine($"Move not found"); return(null); } Bitboard = Bitboard.Move(aiResult.PVNodes[0]); _history.Add(aiResult.PVNodes[0]); return(aiResult); } }
/// <summary> /// Runs AI calculating. /// </summary> /// <param name="command">The AI command</param> private void CalculateBestMove(Command command) { var colorArgument = command.GetArgument <string>(0); var preferredTimeArgument = command.GetArgument <float>(1); var helperTasksCount = command.GetArgument <int>(2); var colorParseResult = Enum.TryParse(colorArgument, true, out Color color); if (!colorParseResult) { ConsoleManager.WriteLine($"$rInvalid color type ($R{color}$r)"); return; } var ai = new AICore(); var aiResult = ai.Calculate(color, Bitboard, preferredTimeArgument, helperTasksCount); ConsoleManager.WriteLine(); if (aiResult.PVNodes.Count == 0) { ConsoleManager.WriteLine("$gMate"); } else { ConsoleManager.WriteLine($"$wDepth: $g{aiResult.Depth}"); ConsoleManager.WriteLine($"$wTotal nodes: $g{aiResult.Stats.TotalNodes} N"); ConsoleManager.WriteLine($"$wEnd nodes: $g{aiResult.Stats.EndNodes} N"); ConsoleManager.WriteLine($"$wα-β cutoffs: $y{aiResult.Stats.AlphaBetaCutoffs} N"); ConsoleManager.WriteLine($"$wTT hits: $y{aiResult.Stats.TranspositionTableHits} N"); ConsoleManager.WriteLine($"$wBranching factor: $y{aiResult.Stats.BranchingFactor}"); ConsoleManager.WriteLine($"$wNodes per second: $c{aiResult.NodesPerSecond / 1000} kN"); ConsoleManager.WriteLine($"$wTime per node: $c{aiResult.TimePerNode} ns"); ConsoleManager.WriteLine($"$wTime: $m{aiResult.Time} s"); ConsoleManager.WriteLine(); ConsoleManager.WriteLine($"$wQ Total nodes: $g{aiResult.Stats.QuiescenceTotalNodes} N"); ConsoleManager.WriteLine($"$wQ End nodes: $g{aiResult.Stats.QuiescenceEndNodes} N"); ConsoleManager.WriteLine(); ConsoleManager.WriteLine($"$wBest move: $g{aiResult.PVNodes}"); ConsoleManager.WriteLine($"$wScore: $m{aiResult.Score}"); } ConsoleManager.WriteLine(); }