Exemple #1
0
        /// <summary>
        /// Examines the board's position to detect whethet '_side' is in check
        /// </summary>
        /// <param name="_side">The side in question</param>
        /// <returns>True if _side is in check, false otherwise</returns>
        internal bool IsInCheck(int _side)
        {
            //compute attackers
            int attackedPiece = Piece.BlackKing + _side;

            return(MovesGenerator.EnemyAttacksOn(this, Position.LSB(BitBoards[attackedPiece]), _side) != 0);
        }
Exemple #2
0
        private static void MakeMove(object _board)
        {
            Board board = _board as Board;

            //check if we only have one move
            var moves = MovesGenerator.GetMoves(board, false);

            if (moves.Count == 1)
            {
                Moved(moves[0]);
            }

            Move move;

            if (OpeningBook.IsInBook)
            {
                move = OpeningBook.GetRandomMove();
            }
            else
            {
                BoardEvaluator.m_EvaluationCounter = 0;
                //Move move = AlphaBetaRoot(m_GameBoard, Depth);
                move = IterativeDeepeningAlphaBeta(board).BestMove;
            }

            Clock.Stop();

            if (Moved != null)
            {
                Moved(move);
            }


            m_MoveThread.Abort();
        }
Exemple #3
0
        private static IterativeDeepeningResult IterativeDeepeningAlphaBeta(Board _board)
        {
            IterativeDeepeningResult result = new IterativeDeepeningResult();

            //Move bestMove = null;
            //Move currentMove = null;


            var moves = MovesGenerator.GetMoves(_board, true);

            //iterative deepening current depth
            int depth;

            Move lastMove = _board.LastMove[1 - _board.CurrentPlayer];

            if (lastMove != null && m_Pondering.Keys.Any(x => x.EqualMove(lastMove)))
            {
                Move lastMoveOnPondering = m_Pondering.Keys.First(x => x.EqualMove(lastMove));
                IterativeDeepeningResult ponderingResult = m_Pondering[lastMoveOnPondering];
                foreach (Move move in ponderingResult.PV_Moves)
                {
                    Move moveToReorder = moves.First(x => x.EqualMove(move));
                    moves.Remove(moveToReorder);
                    moves.Insert(0, moveToReorder);
                }
                depth = ponderingResult.DepthReeched + 1;
            }
            else
            {
                depth = 1;
            }

            int alpha = -31000, beta = 32000;

            //iterative deepening
            for (; !Clock.TimesUp && depth <= Depth; depth++)
            {
                _board.NullMoveOk = true;
                m_NodesSearched   = 0;
                AlphaBetaRootResult alphaBetaResult = AlphaBetaRoot(_board, depth, moves, false, alpha, beta);

                if (!Clock.TimesUp && alphaBetaResult.BestMove != null && alphaBetaResult.Finished == true)
                {
                    //used in case of researching
                    bool isSearchOk = true;

                    /*if (alphaBetaResult.Score <= alpha || alphaBetaResult.Score >= beta)
                     * {
                     *  alpha = -31000;
                     *  beta = 32000;
                     *  alphaBetaResult = AlphaBetaRoot(_board, depth, moves, false, alpha, beta);
                     *  if (Clock.TimesUp || alphaBetaResult.BestMove == null && alphaBetaResult.Finished == false)
                     *      isSearchOk = false; ;
                     * }
                     * else
                     * {
                     *  alpha = alphaBetaResult.Score - 50;
                     *  beta = alphaBetaResult.Score + 50;
                     * }*/

                    if (isSearchOk)
                    {
                        result.BestMove     = alphaBetaResult.BestMove;
                        result.PV_Moves     = alphaBetaResult.PV_Moves;
                        result.DepthReeched = depth;
                    }
                    //order moves by the PV moves.
                    foreach (Move move in alphaBetaResult.PV_Moves)
                    {
                        moves.Remove(move);
                        moves.Insert(0, move);
                    }
                }

                Global.WriteToLog(depth.ToString() + ' ' + "100" + ' ' + (Clock.CurrentMoveTimeElapsed.TotalMilliseconds) + ' ' + m_NodesSearched + ' ' + (alphaBetaResult.BestMove != null));
            }
            return(result);
        }
Exemple #4
0
        private static int AlphaBeta(Board _board, int _depth, int alpha, int beta)
        {
            m_NodesSearched++;

            /*TranspositionEntry _tableEntry;
             * if (_depth > 1 && m_TranspositionTable.TryLookupBoard(_board, out _tableEntry) && _tableEntry.Player == _board.CurrentPlayer)
             * {
             *  if (_tableEntry.Depth >= _depth && _tableEntry.EvaluationType == EvaluationType.Exact)
             *      return _tableEntry.Value;
             * }*/

            if (_depth <= 0)
            {
                int score = QuiescenceSearch(_board, 0, alpha, beta);

                return(score);
            }

            if (_board.IsTerminal != TerminalType.NotTerminal)
            {
                if (_board.IsTerminal == TerminalType.Stalemate)
                {
                    return(0);
                }
            }

            if (_depth > 4 && Clock.TimesUp)
            {
                return(TIMES_UP);
            }

            //try a null move first, maybe we will get a cutoff (fail-high) , or just a better lower bound
            if (_board.NullMoveOk)
            {
                Board nullMoveClone = Board.Clone(_board);
                nullMoveClone.ApplyNullMove();
                int nullMoveSearchValue = -AlphaBeta(nullMoveClone, _depth - SHALLOWER_DEPTH_R - 1, -beta, -beta + 1);
                if (nullMoveSearchValue >= beta)
                {
                    return(nullMoveSearchValue);
                }
            }
            _board.NullMoveOk = true;

            List <Move> movesBoards;

            if (_depth == 1)
            {
                movesBoards = MovesGenerator.GetMoves(_board, false);
            }
            else
            {
                movesBoards = MovesGenerator.GetMoves(_board, true);
            }

            //if terminal, evaluate
            if (movesBoards == null)
            {
                switch (_board.IsTerminal)
                {
                case TerminalType.BlackWon:
                    if (_board.CurrentPlayer == Side.Black)
                    {
                        return(32000);
                    }
                    else
                    {
                        return(-32000);
                    }

                case TerminalType.WhiteWon:
                    if (_board.CurrentPlayer == Side.White)
                    {
                        return(32000);
                    }
                    else
                    {
                        return(-32000);
                    }

                case TerminalType.Stalemate:
                    return(0);
                }
            }

            foreach (Move move in movesBoards)
            {
                Board clone = Board.Clone(_board);
                clone.ApplyMove(move);

                int childAlphaBeta = -AlphaBeta(clone, _depth - 1, -beta, -alpha);
                if (childAlphaBeta > alpha)
                {
                    alpha = childAlphaBeta;
                }

                if (childAlphaBeta == TIMES_UP)
                {
                    return(TIMES_UP);
                }

                if (beta <= alpha)
                {
                    break;
                }
            }

            //m_TranspositionTable.StoreBoard(_board, alpha, EvaluationType.Exact, _depth);
            return(alpha);
        }
Exemple #5
0
        private static void MakePondering(object _board)
        {
            Board board = _board as Board;

            m_Pondering = new Dictionary <Move, IterativeDeepeningResult>();

            var moves = MovesGenerator.GetMoves(board, true);
            Dictionary <Move, List <Move> > responseMoves = new Dictionary <Move, List <Move> >();
            bool finishedDepth = true;

            for (int depth = 1; finishedDepth && depth <= Depth; depth = depth + 1)
            {
                for (int i = 0; i < moves.Count; i++)
                {
                    Move move = moves[i];

                    //order moves by the PV moves.
                    if (depth > 1)
                    {
                        foreach (Move pvMove in m_Pondering[move].PV_Moves)
                        {
                            responseMoves[move].Remove(pvMove);
                            responseMoves[move].Insert(0, pvMove);
                        }
                    }

                    //now clone the game board (to avoid any changes)
                    Board clone = Board.Clone(board);
                    clone.ApplyMove(move);

                    List <Move> response;
                    if (responseMoves.ContainsKey(move))
                    {
                        response = responseMoves[move];
                    }
                    else
                    {
                        response = MovesGenerator.GetMoves(clone, true);

                        if (response == null)
                        {
                            continue;
                        }

                        responseMoves.Add(move, response);
                    }

                    //launch alpha beta
                    AlphaBetaRootResult alphaBetaResult = AlphaBetaRoot(clone, depth, response, true);

                    if (alphaBetaResult.Finished == false)
                    {
                        finishedDepth = false;
                        break;
                    }

                    IterativeDeepeningResult moveResult;
                    if (m_Pondering.ContainsKey(move))
                    {
                        moveResult = m_Pondering[move];

                        moveResult.BestMove = alphaBetaResult.BestMove;
                        moveResult.PV_Moves = alphaBetaResult.PV_Moves;
                        moveResult.DepthReeched++;
                    }
                    else
                    {
                        m_Pondering.Add(move, new IterativeDeepeningResult {
                            BestMove = alphaBetaResult.BestMove, DepthReeched = 1, PV_Moves = alphaBetaResult.PV_Moves
                        });
                    }
                }
            }

            m_PonderThread.Abort();
        }
        /// <summary>
        /// Parses one single move.
        /// </summary>
        /// <param name="_board">The current board , current opening book's game board</param>
        /// <param name="_pgnMove">the move's PGN notation</param>
        /// <param name="moves">A list of all availible moves</param>
        /// <returns>An opening move represents the parsed response.</returns>
        private static OpeningMove PGNMoveParser(Board _board, string _pgnMove, List <Move> moves)
        {
            bool isCapture = _pgnMove.Contains('x');

            bool test = false;

            if (test)
            {
                moves = MovesGenerator.GetLegalMoves(_board);
            }

            OpeningMove move = new OpeningMove();

            try
            {
                //first check if it is castle
                if (_pgnMove.StartsWith("O-O-O"))
                {
                    move.Move = moves.First(x => x.MoveType == MoveTypes.CastleQueenSide);
                }
                else if (_pgnMove.StartsWith("O-O"))
                {
                    move.Move = moves.First(x => x.MoveType == MoveTypes.CastleKingSide);
                }
                else
                {
                    int piece = PGNletterToPieceParser(_pgnMove[0], _board.CurrentPlayer);

                    var pieceMoves = moves.Where(x => x.MovingPiece == piece);



                    if (pieceMoves.Count() == 1)
                    {
                        move.Move = pieceMoves.ElementAt(0);
                    }
                    else
                    {
                        if (piece == Piece.BlackPawn || piece == Piece.WhitePawn)
                        {
                            var sourceMoves = pieceMoves.Where(x => x.SourceFile == _pgnMove[0]);
                            if (sourceMoves.Count() == 1)
                            {
                                move.Move = sourceMoves.ElementAt(0);
                            }
                            else
                            {
                                if (isCapture)
                                {
                                    string dest = _pgnMove.Substring(_pgnMove.IndexOf('x') + 1, 2);
                                    move.Move = sourceMoves.First(x => x.DestinationSquareString == dest);
                                }
                                else
                                {
                                    string dest = _pgnMove.Substring(0, 2);
                                    move.Move = sourceMoves.First(x => x.DestinationSquareString.StartsWith(dest));
                                }
                            }
                        }
                        else
                        {
                            IEnumerable <Move> destMoves;
                            if (isCapture)
                            {
                                string dest = _pgnMove.Substring(_pgnMove.IndexOf('x') + 1, 2);
                                destMoves = pieceMoves.Where(x => x.DestinationSquareString == dest);
                            }
                            else
                            {
                                int    indexDestRank = _pgnMove.LastIndexOfAny(new char[] { '1', '2', '3', '4', '5', '6', '7', '8', '9' });
                                string dest          = _pgnMove.Substring(indexDestRank - 1, 2);
                                destMoves = pieceMoves.Where(x => x.DestinationSquareString == dest);
                            }

                            switch (destMoves.Count())
                            {
                            case 1:
                                move.Move = destMoves.ElementAt(0);
                                break;

                            case 2:
                                //either rank or file ambiguity
                                if (_pgnMove[1] >= '1' && _pgnMove[1] <= '9')
                                {
                                    //rank ambiguity
                                    move.Move = destMoves.First(x => x.SourceRank == _pgnMove[1]);
                                }
                                else
                                {
                                    move.Move = destMoves.First(x => x.SourceFile == _pgnMove[1]);
                                }
                                break;

                            case 3:
                                move.Move = destMoves.First(x => x.SourceSquareString == _pgnMove.Substring(1, 2));
                                break;
                            }
                        }
                    }

                    //now get move type
                    if (_pgnMove.Contains("!!"))
                    {
                        move.MoveType = OpeningMoveType.Excellent;
                    }
                    else if (_pgnMove.Contains("!?"))
                    {
                        move.MoveType = OpeningMoveType.Interesting;
                    }
                    else if (_pgnMove.Contains("?!"))
                    {
                        move.MoveType = OpeningMoveType.Dubious;
                    }
                    else if (_pgnMove.Contains("!"))
                    {
                        move.MoveType = OpeningMoveType.Good;
                    }
                    else if (_pgnMove.Contains("??"))
                    {
                        move.MoveType = OpeningMoveType.Blunder;
                    }
                    else if (_pgnMove.Contains("?"))
                    {
                        move.MoveType = OpeningMoveType.Bad;
                    }
                }

                if (move.Move == null)
                {
                    throw new System.Exception("not found");
                }

                return(move);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// Parses the book string in the standard PGN format, and inserts it into the starting position node
        /// </summary>
        /// <param name="book">A standard PGN formatted string</param>
        /// <param name="startingPoint">The starting node to add responses to</param>
        private static void AnalyzeBook(string book, OpeningMove startingPoint)
        {
            try
            {
                string[] tags = book.Replace("\r\n", " ").Split(new string[] { "[" }, StringSplitOptions.RemoveEmptyEntries);
                for (int i = 6; i < tags.Length; i += 7)
                {
                    string   movesString = tags[i].Substring(tags[i].IndexOf(']') + 1);
                    string[] movesArray  = movesString.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                    Board board = new Board();
                    board.StartingPosition();

                    //parentMove will slide, containing the parent to the move.
                    OpeningMove parentMove = startingPoint;
                    bool        abortMatch = false;

                    for (int j = 0; j < movesArray.Length && !abortMatch; j++)
                    {
                        if (j % 3 == 0)
                        {
                            continue;
                        }

                        if (parentMove.LegalMoves == null)
                        {
                            parentMove.LegalMoves = MovesGenerator.GetLegalMoves(board);
                        }

                        OpeningMove move = PGNMoveParser(board, movesArray[j], parentMove.LegalMoves);

                        if (move.MoveType != OpeningMoveType.Excellent && move.MoveType != OpeningMoveType.Good)
                        {
                            abortMatch = true;
                            break;
                        }

                        //to avoid duplicate entries problem, we make sure to use same instance of a move.
                        OpeningMove storedSameMove = parentMove.Responses.FirstOrDefault(x => x.Move.EqualMove(move.Move));

                        if (storedSameMove == null)
                        {
                            move.Count = 1;
                            parentMove.Responses.Add(move);
                        }
                        else
                        {
                            parentMove.Count++;
                            move = storedSameMove;
                        }

                        parentMove = move;

                        board.ApplyMove(move.Move);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemple #8
0
        public void WinBoardGame()
        {
            m_Clocks             = new Clock[2];
            m_Clocks[Side.White] = new Clock();
            m_Clocks[Side.Black] = new Clock();

            AIPlayer.Moved += new MoveEventHandler(m_EnginePlayer_Moved);
            //m_GameBoard.CurrentPlayer = (Side)(((int)currentPlayer + 1) & 0x1);
            //move = Players[currentPlayer].Move();
            Global.WriteToLog("-----------------" + DateTime.Now.ToString() + "-----------------");
            while (m_toContinue)
            {
                string input;
                if (m_GetResponseFromFile)
                {
                    while (AIPlayer.IsThinking)
                    {
                        System.Threading.Thread.Sleep(2000);
                    }

                    input = m_FileResponse[0];
                    m_FileResponse.RemoveAt(0);

                    //pause at level
                    if (m_FileResponse.Count == 2)
                    {
                        int x = 1;
                        if (x == 1)
                        {
                            x = 2;
                        }
                    }
                }
                else
                {
                    while (AIPlayer.IsThinking)
                    {
                        System.Threading.Thread.Sleep(2000);
                    }

                    input = Console.ReadLine();

                    if (m_WriteToScript)
                    {
                        Global.WriteToScript(input);
                    }
                }

                Global.WriteToLog("I:" + input);
                string arg         = String.Empty;
                string commandType = String.Empty;
                int    pos         = input.IndexOf(' ');
                if (pos > 0)
                {
                    commandType = input.Substring(0, pos);
                    if (input.Length > pos + 1)
                    {
                        arg = input.Substring(pos + 1);
                    }
                }
                else
                {
                    commandType = input;
                }


                WinBoardCommands command  = WinBoardCommands.Nopost;
                string           response = String.Empty;

                if (m_editMode)
                {
                    /*if (commandType.Length > 0)
                     * {
                     *  if (commandType.Length > 1)
                     *  {
                     *      int Col = input[1] - 'a';
                     *      int Row = int.Parse(input[2].ToString()) - 1;
                     *      int position = Row * 8 + Col;
                     *      switch (commandType[0])
                     *      {
                     *          case 'P':
                     *              m_GameBoard.AddPiece(position, Piece.BlackPawn + m_GameBoard.CurrentPlayer);
                     *              break;
                     *          case 'R':
                     *              m_GameBoard.AddPiece(position, Piece.BlackRook + m_GameBoard.CurrentPlayer);
                     *              break;
                     *          case 'Q':
                     *              m_GameBoard.AddPiece(position, Piece.BlackQueen + m_GameBoard.CurrentPlayer);
                     *              break;
                     *          case 'K':
                     *              m_GameBoard.AddPiece(position, Piece.BlackKing + m_GameBoard.CurrentPlayer);
                     *              break;
                     *          case 'B':
                     *              m_GameBoard.AddPiece(position, Piece.BlackBishop + m_GameBoard.CurrentPlayer);
                     *              break;
                     *          case 'N':
                     *              m_GameBoard.AddPiece(position, Piece.BlackKnight + m_GameBoard.CurrentPlayer);
                     *              break;
                     *      }
                     *  }
                     *  else
                     *  {
                     *      switch (commandType[0])
                     *      {
                     *          case '#':
                     *              int currentPlayer = m_GameBoard.CurrentPlayer;
                     *              m_GameBoard = new Board();
                     *              m_GameBoard.ClearedBoard();
                     *              m_GameBoard.CurrentPlayer = currentPlayer;
                     *              break;
                     *          case '.':
                     *              m_editMode = false;
                     *              break;
                     *      }
                     *  }
                     * }*/
                }
                else
                {
                    try
                    {
                        command = (WinBoardCommands)Enum.Parse(typeof(WinBoardCommands), commandType, true);
                    }
                    catch (Exception ex)
                    {
                        switch (commandType)
                        {
                        case "?": command = WinBoardCommands.QMark;
                            break;

                        default:
                            command = WinBoardCommands.Unknown;
                            break;
                        }
                    }


                    switch (command)
                    {
                    case WinBoardCommands.New:
                        break;

                    case WinBoardCommands.Protover:
                        response = "feature time=0 colors=0 usermove=1 done=1";
                        break;

                    case WinBoardCommands.Quit:
                        m_toContinue = false;
                        AIPlayer.Dispose();
                        break;

                    case WinBoardCommands.Force:
                        AIPlayer.ToForce = true;
                        break;

                    case WinBoardCommands.Level:
                        string[] timeData;
                        timeData = arg.Split(' ');
                        if (timeData[1].Contains(':'))
                        {
                            string[] timeDataParts = timeData[1].Split(':');
                            int      minutes = int.Parse(timeDataParts[0]), seconds = int.Parse(timeDataParts[1]);
                            m_Clocks[Side.Black].Time = m_Clocks[Side.White].Time = TimeSpan.FromMinutes(minutes).Add(TimeSpan.FromSeconds(seconds));
                        }
                        else
                        {
                            int minutes = int.Parse(timeData[1]);
                            m_Clocks[Side.Black].Time = m_Clocks[Side.White].Time = TimeSpan.FromMinutes(minutes);
                        }
                        m_Clocks[Side.Black].Incremental = m_Clocks[Side.White].Incremental = TimeSpan.FromSeconds(int.Parse(timeData[2]));
                        break;

                    case WinBoardCommands.Sd:
                        int depth;
                        if (int.TryParse(arg, out depth))
                        {
                            AIPlayer.Depth = depth;
                        }
                        else
                        {
                            //out error
                        }
                        break;

                    case WinBoardCommands.QMark:
                        AIPlayer.Move(m_GameBoard);
                        break;

                    case WinBoardCommands.Usermove:
                        if (m_EngineSide == -1)
                        {
                            m_EngineSide   = Side.Black;
                            AIPlayer.Clock = m_Clocks[m_EngineSide];
                        }
                        AIPlayer.StopPondering = true;

                        var  moves     = MovesGenerator.GetMoves(m_GameBoard, false);
                        int  sourceCol = arg[0] - 'a';
                        int  sourceRow = int.Parse(arg[1].ToString()) - 1;
                        int  destCol   = arg[2] - 'a';
                        int  destRow   = int.Parse(arg[3].ToString()) - 1;
                        int  source    = sourceRow * 8 + sourceCol;
                        int  dest      = destRow * 8 + destCol;
                        Move move      = (from anyMove in moves
                                          where anyMove.SourceSquare == source && anyMove.DestinationSquare == dest
                                          select anyMove).ElementAtOrDefault(0);
                        if (move == null)
                        {
                            response = "Illegal move: " + arg;
                        }
                        else
                        {
                            m_GameBoard.ApplyMove(move);
                            OpeningBook.MoveApplied(move);
                            m_Clocks[1 - m_GameBoard.CurrentPlayer].Stop();
                            m_Clocks[m_GameBoard.CurrentPlayer].Start();
                            AIPlayer.Move(m_GameBoard);
                        }
                        break;

                    case WinBoardCommands.Go:
                        if (m_EngineSide == -1)
                        {
                            m_EngineSide   = Side.White;
                            AIPlayer.Clock = m_Clocks[m_EngineSide];
                        }

                        if (m_EngineSide != m_GameBoard.CurrentPlayer)
                        {
                            break;
                        }

                        AIPlayer.ToForce = false;
                        m_EngineSide     = m_GameBoard.CurrentPlayer;
                        AIPlayer.Clock   = m_Clocks[m_EngineSide];
                        m_Clocks[m_EngineSide].Start();
                        AIPlayer.Move(m_GameBoard);
                        break;

                    case WinBoardCommands.Accepted:
                        break;

                    case WinBoardCommands.Result:
                        //announce defeat to winboard ?
                        break;

                    case WinBoardCommands.Edit:
                        m_editMode = true;
                        break;

                    default:
                        response = "Error (unknown command): " + commandType;
                        break;
                    }

                    if (response != string.Empty)
                    {
                        Global.WriteToLog("O:" + response);
                        Console.WriteLine(response);
                    }
                }
            }
        }