public float RateBoard(Board board) { float result = 0; UInt64 whitePieces = board.WhitePieces; UInt64 blackPieces = board.BlackPieces; int whitePiecesAmount = BitHelpers.GetNumberOfSetBits(whitePieces); int blackPiecesAmount = BitHelpers.GetNumberOfSetBits(blackPieces); foreach (var piece in board.PiecePositions) { if (piece.type == PieceType.Empty) { continue; } float value = 1; (int x, int y)pos = Board.Position1DTo2D(piece.pos); if (PieceType.IsPawn(piece.type)) { value = 1; //value += 0.1f*(4.5f-Math.Abs(pos.x-4.5f)); if (PieceType.IsWhite(piece.type)) { value += 0.01f * WhitePawnSquareTable[piece.pos]; } else { value += 0.01f * BlackPawnSquareTable[piece.pos]; } } else if (PieceType.IsKnight(piece.type)) { value = 3; value += 0.01f * KnightSquareTable[piece.pos]; //value += pos.x > 1 && pos.x < 6 ? 0.25f : pos.x > 0 && pos.x < 7 ? 0.125f : 0; //value += pos.y > 1 && pos.y < 6 ? 0.25f : pos.y > 0 && pos.y < 7 ? 0.125f : 0; } else if (PieceType.IsBishop(piece.type)) { value = 3; value += 0.01f * BishopSquareTable[piece.pos]; value += BitHelpers.GetNumberOfSetBits(board.GetMovesForBishop(PieceType.IsWhite(piece.type), piece.pos)) * 0.04f; } else if (PieceType.IsRook(piece.type)) { value = 5; } else if (PieceType.IsQueen(piece.type)) { value = 9; } else if (PieceType.IsKing(piece.type)) { value = 0; value += pos.x < 2 && pos.x > 5 ? 0.2f : pos.x < 3 && pos.x > 4 ? 0.075f : -0.1f; if (PieceType.IsWhite(piece.type)) { value += 0.015f * WhiteKingSquareTable[piece.pos]; value += 0.2f * BitHelpers.GetNumberOfSetBits(RayHelpers.KingShield[piece.pos][1] & board.BitBoard[PieceType.WhitePawn]); value -= 0.1f * BitHelpers.GetNumberOfSetBits(RayHelpers.KingSphere[piece.pos] & blackPieces); value = value * (1f + blackPiecesAmount) / 16; } else { value += 0.015f * BlackKingSquareTable[piece.pos]; value += 0.2f * BitHelpers.GetNumberOfSetBits(RayHelpers.KingShield[piece.pos][0] & board.BitBoard[PieceType.BlackPawn]); value -= 0.1f * BitHelpers.GetNumberOfSetBits(RayHelpers.KingSphere[piece.pos] & whitePieces); value = value * (1f + whitePiecesAmount) / 16; } } result += PieceType.IsWhite(piece.type) ? value : -value; } for (int i = 0; i < 8; i++) { int whitePawnsOnFile = BitHelpers.GetNumberOfSetBits(RayHelpers.Files[i] & board.BitBoard[PieceType.WhitePawn]); int blackPawnsOnFile = BitHelpers.GetNumberOfSetBits(RayHelpers.Files[i] & board.BitBoard[PieceType.BlackPawn]); if (whitePawnsOnFile >= 3) { result -= 1; } else if (whitePawnsOnFile >= 2) { result -= 0.5f; } if (blackPawnsOnFile >= 3) { result += 1; } else if (blackPawnsOnFile >= 2) { result += 0.5f; } } return(result); }
public void StartGame() { DrawBoard(); Random random = new Random(690); while (true) { Console.WriteLine(); var moves = CurrentBoard.GetRealMoves(); GameResult gameResult = CurrentBoard.GetGameResultFromMoves(moves); if (gameResult == GameResult.Draw) { Console.WriteLine("Draw!"); break; } else if (gameResult == GameResult.WhiteWin) { Console.WriteLine("Checkmate! White wins!"); break; } else if (gameResult == GameResult.BlackWin) { Console.WriteLine("Checkmate! Black wins!"); break; } if ((CurrentBoard.WhiteTurn && !playerWhite) || (!CurrentBoard.WhiteTurn && !playerBlack)) { int whitePiecesAmount = BitHelpers.GetNumberOfSetBits(CurrentBoard.WhitePieces); int blackPiecesAmount = BitHelpers.GetNumberOfSetBits(CurrentBoard.BlackPieces); int depth = CurrentBoard.WhiteTurn ? whiteDepth : blackDepth; //todo: implement iterative deepening search /*if (moves.Count <= 4) { * depth += 1; * } * if (whitePiecesAmount+blackPiecesAmount <= 3) { * depth += 5; * } else if (whitePiecesAmount+blackPiecesAmount <= 4) { * depth += 4; * } else if (whitePiecesAmount+blackPiecesAmount <= 5) { * depth += 3; * } else if (whitePiecesAmount+blackPiecesAmount <= 6) { * depth += 2; * } else if (whitePiecesAmount+blackPiecesAmount <= 8) { * depth += 1; * }*/ if (halfTurnCount <= 2) { depth = Math.Max(3, depth - 2); } if (depth % 2 == 0) { depth -= 1; } var sortedMoves = alphaBeta.FindMoveAlphaBeta(CurrentBoard, depth); int selected = 0; if (sortedMoves.Count > 1 && MathF.Abs(sortedMoves[0].Item4 - sortedMoves[1].Item4) < 0.5f) { if (halfTurnCount <= 1) { sortedMoves.Insert(0, (PieceType.WhitePawn, Board.PositionAlgebraicTo1D("e2"), Board.PositionAlgebraicTo1D("e4"), 0)); sortedMoves.Insert(0, (PieceType.WhitePawn, Board.PositionAlgebraicTo1D("d2"), Board.PositionAlgebraicTo1D("d4"), 0)); selected = random.Next(Math.Min(sortedMoves.Count, 6)); } else if (halfTurnCount <= 4) { selected = random.Next(Math.Min(sortedMoves.Count, 3)); } else if (halfTurnCount <= 8) { selected = random.Next(Math.Min(sortedMoves.Count, 2)); } } Console.WriteLine($"{sortedMoves[selected].Item4.ToString("0.000")}: " + $"{Board.Position1DToAlgebraic(sortedMoves[selected].Item2)} -> " + $"{Board.Position1DToAlgebraic(sortedMoves[selected].Item3)} ({depth})"); CurrentBoard.MakeMove(sortedMoves[selected].Item1, sortedMoves[selected].Item2, sortedMoves[selected].Item3); } else { var playerMove = GetPlayerMove(); var moveIndex = moves.FindIndex(m => m.Item2 == playerMove.Item1 && m.Item3 == playerMove.Item2); while (moveIndex == -1) { Console.WriteLine("Invalid move, try again:"); playerMove = GetPlayerMove(); moveIndex = moves.FindIndex(m => m.Item2 == playerMove.Item1 && m.Item3 == playerMove.Item2); } CurrentBoard.MakeMove(moves[moveIndex].Item1, moves[moveIndex].Item2, moves[moveIndex].Item3); } halfTurnCount++; DrawBoard(); Console.WriteLine(CurrentBoard.Zobrist); //System.Threading.Thread.Sleep(1000); } Console.WriteLine(CurrentBoard.BoardToFen((halfTurnCount + 1) / 2)); }