Beispiel #1
0
        // POST: api/ChessAI
        public string Post(StringAux gameXml, int timeLimitInSecs)
        {
            if (gameXml == null)
            {
                return("WTF");
            }
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(gameXml.Str);
            XmlNode gameXmlNode = doc.DocumentElement;

            ChessLibrary.Game g1 = new ChessLibrary.Game();
            g1.XmlDeserialize(gameXmlNode);

            Player p = g1.BlackPlayer;

            if (g1.BlackTurn())
            {
                p = g1.WhitePlayer;
            }
            ChessLibrary.Move m = p.GetBestMove();

            string best_str = m.ToString2();

            g1.NextPlayerTurn(); // need to do that because the player is opposite for some reason
            if (g1.DoMove(best_str.Substring(best_str.Length - 5, 2), best_str.Substring(best_str.Length - 2, 2)) == -1)
            {
                return("bad move");
            }
            return(best_str);

            /*XmlDocument doc = new XmlDocument();
             * doc.LoadXml(gameXml.Str);
             * XmlNode gameXmlNode = doc.DocumentElement;
             *
             * Move bestMove = ChessAPI.calculateBestMoveXmlNode(gameXmlNode, timeLimitInSecs);*/

            /*System.Xml.Serialization.XmlSerializer writer =
             * new System.Xml.Serialization.XmlSerializer(typeof(Move));
             * StringBuilder sb = new StringBuilder();
             * StringWriter sw = new StringWriter(sb);
             * writer.Serialize(sw, bestMove);*/
            //return bestMove.ToString(); // seralized move
        }
Beispiel #2
0
 // Fire the computer thinking events to all the subscribers
 public void NotifyComputerThinking(int depth, int currentMove, int TotalMoves, int TotalAnalzyed, Move BestMove)
 {
     if (ComputerThinking != null)               // There are some subscribers
     {
         ComputerThinking(depth, currentMove, TotalMoves, TotalAnalzyed, BestMove);
     }
 }
Beispiel #3
0
        // 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);
        }