/// <summary> /// Draws the winner on the screen /// </summary> /// <param name="game">Game.</param> public void DrawWinner(ChessGame game) { string toCheck = DetermineCheck(game); if (toCheck == "Black checkmated") { SwinGame.DrawText("White wins", Color.Crimson, SwinGame.FontNamed("Chelsea"), 620, 400); } else if (toCheck == "White checkmated") { SwinGame.DrawText("Black wins", Color.Crimson, SwinGame.FontNamed("Chelsea"), 620, 400); } else { SwinGame.DrawText(game.PlayerInturn.Team + " 's turn", Color.Crimson, SwinGame.FontNamed("Chelsea"), 620, 400); } }
/// <summary> /// Determines the checking condition of the game and return a string /// </summary> /// <returns>A string message</returns> /// <param name="game">The game</param> public string DetermineCheck(ChessGame game) { for (int i = 0; i < 2; i++) { if (game.Players[i].King == null || game.Players [i].King.isCheckmated(game.Players [(i + 1) % 2], game.Board)) { return(game.Players [i].Team + " checkmated"); } } for (int i = 0; i < 2; i++) { if (game.Players [i].King.isChecked(game.Players [(i + 1) % 2], game.Board)) { return(game.Players [i].Team + " in check"); } } return("In safety"); }
/// <summary> /// Reverses the move. /// </summary> /// <param name="game">the Game</param> /// <param name="isTurnChanged">If set to <c>true</c> the turn is swapped</param> public void ReverseMove(ChessGame game, bool isTurnChanged) { if (_moves.Count == 0) { return; } Move lastMove = _moves [_moves.Count - 1]; MoveWithoutChecking(new Move(lastMove.PlayerMove, lastMove.PieceMove, null, lastMove.CellTo, lastMove.CellFrom), false); if (lastMove.PieceCaptured != null) { lastMove.PlayerMove.Opponent.AddPiece(lastMove.PieceCaptured, lastMove.CellTo); } _moves.Remove(_moves [_moves.Count - 1]); _moves.Remove(lastMove); if (isTurnChanged) { game.ChangeTurn(); } }
/// <summary> /// Handle input and take a turn for Human Player /// </summary> /// <param name="point">usually the mouse position</param> /// <param name="game">the game in play</param> public virtual void TakeTurn(Point2D point, ChessGame game) { //if the player is selecting piece to move if (game.State == GameState.Selecting) { Cell chosen = game.FetchCell(point); //if the piece chosen is not null and belongs to the player if (chosen != null && chosen.Piece != null && _pieces.Contains(chosen.Piece)) { game.ChangeState(GameState.Moving); chosen.Piece.Select(); game.SetChosenPiece(chosen.Piece); } } //if the player is selecting a cell to move the piece else if (game.State == GameState.Moving) { Cell chosen = game.FetchCell(point); //if the chosen cell is the cell that contains the piece, deselect the piece if (chosen.Piece != null && chosen.Piece.isSelected) { game.ChangeState(GameState.Selecting); chosen.Piece.Deselect(); } //if the chosen cell is in possible moves of the chosen piece else if (chosen.isPossibleMoveOf(game.ChosenPiece, _board)) { game.ChangeState(GameState.Moved); _board.Move(new Move(this, game.ChosenPiece, chosen.Piece, game.ChosenPiece.Cell, chosen)); //if the king is moved, check if whether it is a castle if (game.ChosenPiece.GetType() == typeof(King) && _board.timesKingMovedBefore(_color) == 1) { MoveRookInCastle(_color, chosen); } game.ChosenPiece.Deselect(); game.ChangeTurn(); Opponent.TakeTurn(point, game); } } }
/// <summary> /// Figure out the best move for the AI /// </summary> /// <returns>The Move</returns> /// <param name="depth">Number of moves the AI can see ahead</param> /// <param name="game">the chess game</param> /// <param name="p">the player needing best move</param> public Move BestMove(int depth, ChessGame game, Player p) { List <Move> newGameMoves = GeneratedMoves(); Console.WriteLine(newGameMoves.Count); int bestValue = -9999; Move bestMove = null; for (int i = 0; i < newGameMoves.Count; i++) { Move newMove = newGameMoves [i]; game.Board.Move(newMove); int moveValue = AlphaBetaMin(depth - 1, game, p.Opponent, -10000, 10000); game.Board.ReverseMove(game, false); if (moveValue >= bestValue) { bestValue = moveValue; bestMove = newMove; } } return(bestMove); }
/// <summary> /// Calculate the best move for the Human Player /// </summary> /// <returns>the smallest board value</returns> /// <param name="depth">the number of moves the AI can look ahead</param> /// <param name="game">the chess game</param> /// <param name="minimising">The player trying to minimize the board value</param> /// <param name="alpha">the minimum board value</param> /// <param name="beta">the maximum board value</param> public int AlphaBetaMin(int depth, ChessGame game, Player minimising, int alpha, int beta) { if (depth == 0) { Console.WriteLine(BoardValue()); return(BoardValue()); } List <Move> newGameMoves = minimising.GeneratedMoves(); int bestValue = 9999; for (int i = 0; i < newGameMoves.Count; i++) { game.Board.Move(newGameMoves [i]); bestValue = Math.Min(bestValue, AlphaBetaMax(depth - 1, game, minimising.Opponent, alpha, beta)); beta = Math.Min(beta, bestValue); game.Board.ReverseMove(game, false); if (beta <= alpha) { return(bestValue); } } return(bestValue); }
/// <summary> /// Draws the checking state on the screen /// </summary> /// <param name="game">the Game</param> public void DrawCheckingState(ChessGame game) { SwinGame.DrawText(DetermineCheck(game), Color.Chocolate, SwinGame.FontNamed("Chelsea"), CHECKING_STATE_X, CHECKING_STATE_Y); }
/// <summary> /// Creates the new game. /// </summary> /// <param name="AI">Whether the player is human or AI</param> public void CreateGame(bool AI) { _game = new ChessGame(AI); }