private Move GetHumanMove(int squareIndex) { List <Move> availableMoves = MoveGenerator.GetAvailableMoves(this.chessboard); if (availableMoves.Count == 0) { return(new Move()); } Piece movingPiece = this.chessboard.Board[fromSquare].OccupiedBy; this.toSquare = squareIndex; bool isKing = (movingPiece.Type == PieceType.King); bool isCastleAttempt = isKing ? (Math.Abs(this.fromSquare - this.toSquare) > 1) : false; bool canCastle = availableMoves.Any(m => m.Direction == Direction.Castle); bool isValidCastleAttempt = (isKing && isCastleAttempt && canCastle) ? availableMoves.Any(m => m.KingToSquare == this.toSquare) : false; bool isValidNonCastleMove = isValidCastleAttempt ? false : availableMoves.Any(m => m.FromSquare == this.fromSquare && m.ToSquare == this.toSquare); if (isValidNonCastleMove) { return(availableMoves.FirstOrDefault(m => m.FromSquare == this.fromSquare && m.ToSquare == this.toSquare)); } else if (isValidCastleAttempt) { return(availableMoves.FirstOrDefault(m => m.KingFromSquare == this.fromSquare && m.KingToSquare == this.toSquare)); } return(new Move()); }
public void Chessboard_ShouldCorrectlyIdentifyWhenKingInCheck() { Chessboard position = Utils.LoadPositionFromFenString("3k4/4q3/8/2Q1r3/2PN1P2/3p1K2/8/8 b - - 38 72"); position.MakeMove(new Move(12, 9, Direction.Horizontal)); List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position); Assert.AreEqual(true, position.WhiteInCheck); Assert.AreEqual(false, position.BlackInCheck); }
public void Chessboard_ShouldCorrectlyIdentifyWhenKingInCheckByKnight() { Chessboard position = Utils.LoadPositionFromFenString("3k4/5q1n/P7/2Q1r3/2PN1P2/3p1K2/8/8 b - - 15 58"); position.MakeMove(new Move(15, 30, Direction.L)); List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position); Assert.AreEqual(true, position.WhiteInCheck); Assert.AreEqual(false, position.BlackInCheck); }
private bool IsGameOver() { List <Move> availableMoves = MoveGenerator.GetAvailableMoves(this.chessboard); if (availableMoves.Count == 0) { if (this.chessboard.KingInCheck) { string victor = this.chessboard.OppositeColor == Engine.Defaults.Color.White ? "White" : "Black"; MessageBox.Show(victor + " wins."); } else { MessageBox.Show("Game drawn."); } return(true); } return(false); }
private static int DoAlphaBetaPruning(int depth, int alpha, int beta) { VisitedNodes++; List <Move> availableMoves = MoveGenerator.GetAvailableMoves(position); position.PieceActivity = availableMoves.Count; int gameStateScore = GetGameStateScore(position, availableMoves.Count, depth); if (gameStateScore != 9999) { return(gameStateScore); } MoveSorter.SortMoves(position, availableMoves, killerMoves, depth); for (int moveIndex = 0; moveIndex < availableMoves.Count; moveIndex++) { Move currentMove = availableMoves[moveIndex]; position.MakeMove(currentMove); long zobristKey = ZobristHasher.GetZobristHash(position); if (!position.GameHistory.ContainsKey(zobristKey)) { position.GameHistory.Add(zobristKey, 1); } else { position.GameHistory[zobristKey]++; } int score = (position.TranspositionTable.ContainsKey(zobristKey) && position.TranspositionTable[zobristKey].Depth >= depth) ? position.TranspositionTable[zobristKey].Score : DoAlphaBetaPruning(depth + 1, alpha, beta); position.UndoMove(currentMove); position.GameHistory.Remove(zobristKey); if (position.SideToMove == maximizingSide) { if (score >= beta) { TryAddKillerMove(currentMove, depth); return(beta); } if (score > alpha) { alpha = score; if (depth == 0) { position.MaximizingSideBestMove = currentMove; } UpdatePrincipalVariation(depth, currentMove); TryAddTableEntry(zobristKey, score, depth, currentMove); } } else { if (score <= alpha) { return(alpha); } if (score <= beta) { beta = score; UpdatePrincipalVariation(depth, currentMove); } } } return((position.SideToMove == maximizingSide) ? alpha : beta); }