Exemple #1
0
        /// <summary>
        /// Executes a command and returns a corresponding response.
        /// </summary>
        /// <param name="command">The command.</param>
        protected virtual Response ExecuteCommand(Command command)
        {
            switch (command.Name)
            {
            case "protocol_version":
                return(new Response(command, "2"));

            case "name":
                return(new Response(command, this.Name.Replace('\n', ' ')));

            case "version":
                return(new Response(command, this.Version.Replace('\n', ' ')));

            case "list_commands":
                return(new Response(command, string.Join("\n", this.SupportedCommands)));

            case "known_command":
                return(new Response(
                           command,
                           command.Arguments.Count > 0 && SupportedCommands.Contains(command.Arguments[0]) ? "true" : "false"
                           ));

            case "quit":
                return(new Response(command));

            case "boardsize":
                try {
                    int size = int.Parse(command.Arguments[0]);
                    if (size > 25)
                    {
                        throw new Exception();
                    }
                    this.Board = new Board(size);
                    return(new Response(command));
                } catch {}

                return(new Response(command, "unacceptable size", true));

            case "clear_board":
                this.MoveHistory.Clear();
                this.Board.Clear();

                return(new Response(command));

            case "komi":
                try {
                    this.Komi = float.Parse(command.Arguments[0]);
                    return(new Response(command));
                } catch {}

                return(new Response(command, "syntax error", true));

            case "fixed_handicap":
                if (!this.Board.IsEmpty())
                {
                    return(new Response(command, "board not empty", true));
                }

                try {
                    int count = int.Parse(command.Arguments[0]);
                    if (count < 2 || count > 9 || this.Board.Size < 7)
                    {
                        return(new Response(command, "invalid number of stones", true));
                    }

                    foreach (Vertex v in Board.GetHandicapPlacement(count))
                    {
                        Board[v] = 1;
                    }
                    return(new Response(command));
                } catch {}

                return(new Response(command, "syntax error", true));

            case "set_free_handicap":
                if (!this.Board.IsEmpty())
                {
                    return(new Response(command, "board not empty", true));
                }

                try {
                    List <Vertex> vs = new List <Vertex>();
                    foreach (string input in command.Arguments)
                    {
                        Vertex v = new Vertex(input);
                        if (v == Vertex.Pass || vs.Contains(v))
                        {
                            return(new Response(command, "bad vertex list", true));
                        }
                        vs.Add(v);
                    }

                    foreach (Vertex v in vs)
                    {
                        this.Board[v] = 1;
                    }
                    return(new Response(command));
                } catch {}

                return(new Response(command, "syntax error", true));

            case "play":
                try {
                    Move move = Move.Parse(string.Join(" ", command.Arguments));
                    this.Play(move);
                    return(new Response(command));
                } catch (FormatException) {
                    return(new Response(command, "syntax error", true));
                } catch (InvalidOperationException) {
                    return(new Response(command, "illegal move", true));
                }

            case "genmove":
                try {
                    Color  color  = (Color)Enum.Parse(typeof(Color), command.Arguments[0], true);
                    Vertex?vertex = GenerateMove(color);

                    if (vertex.HasValue)
                    {
                        // Make move and add to move history
                        Move move = new Move(color, vertex.Value);
                        this.Play(move);
                    }

                    return(new Response(command, vertex.HasValue ? vertex.ToString() : "resign"));
                } catch {}

                return(new Response(command, "syntax error", true));

            case "undo":
                if (MoveHistory.Count == 0)
                {
                    return(new Response(command, "cannot undo", true));
                }

                Tuple <Move, Board> tuple = MoveHistory.Pop();
                this.Board = tuple.Item2;

                return(new Response(command));

            case "showboard":
                string result = this.Board.ToString() + "\n-\n";
                result += "(X) captured " + this.Board.Captures[Color.Black] + "\n";
                result += "(O) captured " + this.Board.Captures[Color.White];
                return(new Response(command, result));
            }

            return(new Response(command, "unknown command", true));
        }
        public void UnMake()
        {
            if (!MoveHistory.Any())
            {
                throw new Exception("No move to unmake");
            }
            int MoveToUnmake  = MoveHistory.Pop();
            int ColorMadeMove = 1 - ColorToMove;

            int fromSquare = Move.FromSquare(MoveToUnmake);
            int toSquare   = Move.ToSquare(MoveToUnmake);
            int fromPiece  = Move.FromPiece(MoveToUnmake);
            int toPiece    = Move.ToPiece(MoveToUnmake);

            MovesFiftyHistory.Pop();


            //Moving Back And Cancelling Capturing
            SquarePiece[toSquare]   = toPiece;
            SquarePiece[fromSquare] = fromPiece;

            PieceBitboard[fromPiece] ^= 1UL << fromSquare;              //no changes
            PieceBitboard[fromPiece] ^= 1UL << toSquare;                //no changes

            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << fromSquare; //no changes
            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << toSquare;   //no changes

            OccupiedBB ^= 1UL << fromSquare;                            //no changes
            if (toPiece != 0)
            {
                PieceBitboard[toPiece] ^= 1UL << toSquare;
                PieceBitboard[toPiece & Color.Mask] ^= 1UL << toSquare;

                int EnemyLeftRookIndex = 56 * ColorMadeMove;
                if (toSquare == EnemyLeftRookIndex && toPiece == Piece.Rook && CastleShortIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
                else if (toSquare == EnemyLeftRookIndex + 7 && toPiece == Piece.Rook && CastleLongIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
            }
            else
            {
                OccupiedBB ^= 1UL << toSquare;
            }

            if (CastleShortIndex[ColorMadeMove] <= 0)
            {
                CastleShortIndex[ColorMadeMove]++;
            }
            if (CastleLongIndex[ColorMadeMove] <= 0)
            {
                CastleLongIndex[ColorMadeMove]++;
            }
            if (CastleShortIndex[1 - ColorMadeMove] <= 0)
            {
                CastleShortIndex[1 - ColorMadeMove]++;
            }
            if (CastleLongIndex[1 - ColorMadeMove] <= 0)
            {
                CastleLongIndex[1 - ColorMadeMove]++;
            }

            //Castling Back
            if (Move.Castling(MoveToUnmake))
            {
                int sidePreIndex = 56 * ColorMadeMove;

                int rookSquare, rookToSquare;
                //Short castling (getting rook position)
                if (File(toSquare) == 6)
                {
                    rookSquare   = sidePreIndex + 7;
                    rookToSquare = fromSquare + 1;
                }
                //Long castling (getting rook position)
                else
                {
                    rookSquare   = sidePreIndex;
                    rookToSquare = fromSquare - 1;
                }

                //Moving the rook back
                SquarePiece[rookSquare]   = SquarePiece[rookToSquare];
                SquarePiece[rookToSquare] = 0;

                OccupiedBB ^= 1UL << rookSquare;
                OccupiedBB ^= 1UL << rookToSquare;

                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookToSquare;

                PieceBitboard[ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[ColorMadeMove] ^= 1UL << rookToSquare;
            }

            //Promotion
            if (Move.Promotion(MoveToUnmake))
            {
                int PromotedTo = Move.PromotionPiece(MoveToUnmake); //Either queen, knight, bishop or rook
                //SquarePiece[toSquare] = PromotedTo;

                //If we are here, we've just set the PieceBitboard[fromPiece] to 1 at the toSquare thinking of doing the opposite, so we need to cancel that
                PieceBitboard[fromPiece]  ^= 1UL << toSquare;
                PieceBitboard[PromotedTo] ^= 1UL << toSquare;

                //Color maps do not change, as well as occupied (we're just replacing the piece)
            }

            //Enpassant
            if (Move.EnPassant(MoveToUnmake))
            {
                //Restoring the pawn
                int    EnPassantVictimSquare   = toSquare + 16 * ColorMadeMove - 8;
                UInt64 enPassantVictimBitboard = 1UL << EnPassantVictimSquare;

                OccupiedBB ^= enPassantVictimBitboard;
                PieceBitboard[Piece.Pawn | ColorToMove] ^= enPassantVictimBitboard;
                PieceBitboard[ColorToMove]        ^= enPassantVictimBitboard;
                SquarePiece[EnPassantVictimSquare] = Piece.Pawn | ColorToMove;
            }

            ColorToMove = ColorMadeMove;
            EnPassantHistory.Pop();
        }