Пример #1
0
        public static Move ParseMoveString(Board board, string moveString)
        {
            if (null == board)
            {
                throw new ArgumentNullException(nameof(board));
            }

            if (string.IsNullOrWhiteSpace(moveString))
            {
                throw new ArgumentNullException(nameof(moveString));
            }

            moveString = moveString.Trim();

            try
            {
                // Attempt to parse as an algebraic move
                return(new Move(moveString));
            }
            catch (Exception) { }

            string[] moveStringParts = moveString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            PieceName movingPiece = EnumUtils.ParseShortName(moveStringParts[0]);

            if (moveStringParts.Length == 1)
            {
                if (board.BoardState == BoardState.NotStarted)
                {
                    // First move is on the origin
                    return(new Move(movingPiece, Position.Origin));
                }

                throw new ArgumentException("You must specify a target piece.", nameof(moveString));
            }

            string targetString   = moveStringParts[1].Trim('-', '/', '\\');
            int    seperatorIndex = moveStringParts[1].IndexOfAny(new char[] { '-', '/', '\\' });

            PieceName targetPiece = EnumUtils.ParseShortName(targetString);

            if (seperatorIndex < 0)
            {
                // Putting a piece on top of another
                return(new Move(movingPiece, board.GetPiecePosition(targetPiece).GetAbove()));
            }

            char seperator = moveStringParts[1][seperatorIndex];

            Position targetPosition = board.GetPiecePosition(targetPiece);

            if (seperatorIndex == 0)
            {
                // Moving piece on the left-hand side of the target piece
                switch (seperator)
                {
                case '-':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.UpLeft)));

                case '/':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.DownLeft)));

                case '\\':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.Up)));
                }
            }
            else if (seperatorIndex == targetString.Length)
            {
                // Moving piece on the right-hand side of the target piece
                switch (seperator)
                {
                case '-':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.DownRight)));

                case '/':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.UpRight)));

                case '\\':
                    return(new Move(movingPiece, targetPosition.NeighborAt(Direction.Down)));
                }
            }

            return(null);
        }
Пример #2
0
 public override string ToString()
 {
     return(string.Format("{0}[{1}]", EnumUtils.GetShortName(PieceName), null != Position ? Position.ToString() : ""));
 }
Пример #3
0
        public void Play(Move move, string moveString = null)
        {
            if (null == move)
            {
                throw new ArgumentNullException(nameof(move));
            }

            if (move.IsPass)
            {
                Pass();
                return;
            }

            if (GameIsOver)
            {
                throw new InvalidMoveException(move, "You can't play, the game is over.");
            }

            if (!GetValidMoves().Contains(move))
            {
                if (move.Color != CurrentTurnColor)
                {
                    throw new InvalidMoveException(move, "It's not that player's turn.");
                }

                if (!EnumUtils.IsEnabled(move.PieceName, ExpansionPieces))
                {
                    throw new InvalidMoveException(move, "That piece is not enabled in this game.");
                }

                if (null == move.Position)
                {
                    throw new InvalidMoveException(move, "You can't put a piece back into your hand.");
                }

                if (CurrentPlayerTurn == 1 && move.BugType == BugType.QueenBee)
                {
                    throw new InvalidMoveException(move, "You can't play your Queen Bee on your first turn.");
                }

                Piece targetPiece = GetPiece(move.PieceName);

                if (!CurrentTurnQueenInPlay)
                {
                    if (CurrentPlayerTurn == 4 && targetPiece.BugType != BugType.QueenBee)
                    {
                        throw new InvalidMoveException(move, "You must play your Queen Bee on or before your fourth turn.");
                    }
                    else if (targetPiece.InPlay)
                    {
                        throw new InvalidMoveException(move, "You can't move a piece in play until you've played your Queen Bee.");
                    }
                }

                if (!PlacingPieceInOrder(targetPiece))
                {
                    throw new InvalidMoveException(move, "When there are multiple pieces of the same bug type, you must play the pieces in order.");
                }

                if (HasPieceAt(move.Position))
                {
                    throw new InvalidMoveException(move, "You can't move there because a piece already exists at that position.");
                }

                if (targetPiece.InPlay)
                {
                    if (!PieceIsOnTop(targetPiece))
                    {
                        throw new InvalidMoveException(move, "You can't move that piece because it has another piece on top of it.");
                    }
                    else if (!CanMoveWithoutBreakingHive(targetPiece))
                    {
                        throw new InvalidMoveException(move, "You can't move that piece because it will break the hive.");
                    }
                }

                throw new InvalidMoveException(move);
            }

            TrustedPlay(move, null != moveString ? NotationUtils.NormalizeBoardSpaceMoveString(moveString) : NotationUtils.ToBoardSpaceMoveString(this, move));
        }
Пример #4
0
        public Board(string boardString)
        {
            if (string.IsNullOrWhiteSpace(boardString))
            {
                throw new ArgumentNullException("boardString");
            }

            string[] split = boardString.Split(BoardStringSeparator);

            ExpansionPieces expansionPieces;

            if (!EnumUtils.TryParseExpansionPieces(split[0], out expansionPieces))
            {
                throw new ArgumentException("Couldn't parse expansion pieces.", "boardString");
            }

            InitPieces(expansionPieces);

            string boardStateString = split[1];

            BoardState boardState;

            if (!Enum.TryParse(boardStateString, out boardState))
            {
                throw new ArgumentException("Couldn't parse board state.", "boardString");
            }
            BoardState = boardState;

            string[] currentTurnSplit = split[2].Split(new char[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);

            string currentTurnColorString = currentTurnSplit[0];

            Color currentTurnColor;

            if (!Enum.TryParse(currentTurnColorString, out currentTurnColor))
            {
                throw new ArgumentException("Couldn't parse current turn color.", "boardString");
            }

            string currentPlayerTurnString = currentTurnSplit[1];

            int currentPlayerTurn;

            if (!int.TryParse(currentPlayerTurnString, out currentPlayerTurn))
            {
                throw new ArgumentException("Couldn't parse current player turn.", "boardString");
            }

            CurrentTurn = 2 * (currentPlayerTurn - 1) + (int)currentTurnColor;

            Queue <Piece> parsedPieces = new Queue <Piece>(EnumUtils.NumPieceNames);

            for (int i = 3; i < split.Length; i++)
            {
                parsedPieces.Enqueue(new Piece(split[i]));
            }

            while (parsedPieces.Count > 0)
            {
                Piece parsedPiece = parsedPieces.Dequeue();
                if (parsedPiece.InPlay)
                {
                    if (parsedPiece.Position.Stack > 0 && !HasPieceAt(parsedPiece.Position.GetBelow()))
                    {
                        parsedPieces.Enqueue(parsedPiece);
                    }
                    else
                    {
                        Piece piece = GetPiece(parsedPiece.PieceName);
                        MovePiece(piece, parsedPiece.Position, true);
                    }
                }
            }

            if (!IsOneHive())
            {
                throw new ArgumentException("The boardString violates the one-hive rule.", "boardString");
            }
        }