// Evaulate the current board position and return the evaluation score public int Evaluate(Side PlayerSide) { int Score = 0; Score = AnalyzeBoard(PlayerSide.type) - AnalyzeBoard(PlayerSide.Enemy()) - 25; if (IsCheckMate(PlayerSide.Enemy())) // If the player is check mate { Score = 1000000; } return(Score); }
// Get the best move available to the player public Move GetBestMove() { int alpha, beta; int depth; // depth to which to do the search TimeSpan ElapsedTime = new TimeSpan(1); // Total elpased time Move BestMove = null; // The best move for the current position // Initialize constants const int MIN_SCORE = -10000000; // Minimum limit of negative for integer const int MAX_SCORE = 10000000; // Maximum limit of positive integer ArrayList TotalMoves = m_Rules.GenerateAllLegalMoves(m_Side); // Get all the legal moves for the current side // Now we use the Iterative deepening technique to search the best move // The idea is just simple, we will keep searching in the more and more depth // as long as we don't time out. // So, it means that when we have less moves, we can search more deeply and which means // better chess game. DateTime ThinkStartTime = DateTime.Now; int MoveCounter; Random RandGenerator = new Random(); // Game is near the end, or the current player is under check if (m_Rules.ChessBoard.GetSideCell(m_Side.type).Count <= 5 || TotalMoves.Count <= 5) { m_GameNearEnd = true; } // Game is near the end, or the Enemy player is under check Side EnemySide; if (m_Side.isBlack()) { EnemySide = m_Rules.ChessGame.WhitePlayer.PlayerSide; } else { EnemySide = m_Rules.ChessGame.BlackPlayer.PlayerSide; } if (m_Rules.ChessBoard.GetSideCell(m_Side.Enemy()).Count <= 5 || m_Rules.GenerateAllLegalMoves(EnemySide).Count <= 5) { m_GameNearEnd = true; } m_TotalMovesAnalyzed = 0; // Reset the total moves anazlye counter for (depth = 1;; depth++) // Keep doing a depth search { alpha = MIN_SCORE; // The famous Alpha & Beta are set to their initial values beta = MAX_SCORE; // at the start of each increasing search depth iteration MoveCounter = 0; // Initialize the move counter variable // Loop through all the legal moves and get the one with best score foreach (Move move in TotalMoves) { MoveCounter++; // Now to get the effect of this move; execute this move and analyze the board m_Rules.ExecuteMove(move); move.Score = -AlphaBeta(m_Rules.ChessGame.EnemyPlayer(m_Side).PlayerSide, depth - 1, -beta, -alpha); m_TotalMovesAnalyzed++; // Increment move counter m_Rules.UndoMove(move); // undo the move // If the score of the move we just tried is better than the score of the best move we had // so far, at this depth, then make this the best move. if (move.Score > alpha) { BestMove = move; alpha = move.Score; } m_Rules.ChessGame.NotifyComputerThinking(depth, MoveCounter, TotalMoves.Count, m_TotalMovesAnalyzed, BestMove); // Check if the user time has expired ElapsedTime = DateTime.Now - ThinkStartTime; if (ElapsedTime.Ticks > (m_MaxThinkTime.Ticks)) // More than 75 percent time is available { break; // Force break the loop } } // Check if the user time has expired ElapsedTime = DateTime.Now - ThinkStartTime; if (ElapsedTime.Ticks > (m_MaxThinkTime.Ticks * 0.25)) // More than 75 percent time is available { break; // Force break the loop } } m_Rules.ChessGame.NotifyComputerThinking(depth, MoveCounter, TotalMoves.Count, m_TotalMovesAnalyzed, BestMove); return(BestMove); }