Beispiel #1
0
        private void GetValidSlides(PieceName target, Position currentPosition, HashSet <Position> visitedPositions, int currentRange, int?maxRange, MoveSet validMoves)
        {
            if (!maxRange.HasValue || currentRange < maxRange.Value)
            {
                for (int slideDirection = 0; slideDirection < EnumUtils.NumDirections; slideDirection++)
                {
                    Position slidePosition = currentPosition.NeighborAt(slideDirection);

                    if (!visitedPositions.Contains(slidePosition) && !HasPieceAt(slidePosition))
                    {
                        // Slide position is open

                        int right = EnumUtils.RightOf(slideDirection);
                        int left  = EnumUtils.LeftOf(slideDirection);

                        if (HasPieceAt(currentPosition.NeighborAt(right)) != HasPieceAt(currentPosition.NeighborAt(left)))
                        {
                            // Can slide into slide position
                            Move move = new Move(target, slidePosition);

                            if (validMoves.Add(move))
                            {
                                // Sliding from this position has not been tested yet
                                visitedPositions.Add(move.Position);

                                GetValidSlides(target, slidePosition, visitedPositions, currentRange + 1, maxRange, validMoves);
                            }
                        }
                    }
                }
            }
        }
Beispiel #2
0
        private MoveSet GetValidGrasshopperMovements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            Position startingPosition = targetPiece.Position;

            for (int direction = 0; direction < EnumUtils.NumDirections; direction++)
            {
                Position landingPosition = startingPosition.NeighborAt(direction);

                int distance = 0;
                while (HasPieceAt(landingPosition))
                {
                    // Jump one more in the same direction
                    landingPosition = landingPosition.NeighborAt(direction);
                    distance++;
                }

                if (distance > 0)
                {
                    // Can only move if there's at least one piece in the way
                    Move move = new Move(targetPiece.PieceName, landingPosition);
                    validMoves.Add(move);
                }
            }

            return(validMoves);
        }
Beispiel #3
0
        private MoveSet GetValidPillbugSpecialAbilityMovements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            Position positionAboveTargetPiece = targetPiece.Position.GetAbove();

            for (int dir = 0; dir < EnumUtils.NumDirections; dir++)
            {
                Position neighbor = targetPiece.Position.NeighborAt(dir);
                Piece    piece    = GetPieceInternal(neighbor);
                if (null != piece && piece.PieceName != LastPieceMoved && null == piece.PieceAbove && CanMoveWithoutBreakingHive(piece))
                {
                    // Piece can be moved
                    Move firstMove = new Move(piece.PieceName, positionAboveTargetPiece);
                    if (GetValidBeetleMovements(piece).Contains(firstMove))
                    {
                        // Piece can be moved on top
                        Position pieceStartingPosition = piece.Position;
                        MovePiece(piece, positionAboveTargetPiece, false);

                        foreach (Move secondMove in GetValidBeetleMovements(piece))
                        {
                            if (secondMove.Position.Stack == 0 && secondMove.Position != pieceStartingPosition)
                            {
                                validMoves.Add(secondMove);
                            }
                        }

                        MovePiece(piece, pieceStartingPosition, false);
                    }
                }
            }

            return(validMoves);
        }
Beispiel #4
0
        private MoveSet GetValidSpiderMovements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            // Get all slides up to 2 spots away
            MoveSet upToTwo = GetValidSlides(targetPiece, 2);

            if (upToTwo.Count > 0)
            {
                // Get all slides up to 3 spots away
                MoveSet upToThree = GetValidSlides(targetPiece, 3);

                if (upToThree.Count > 0)
                {
                    // Get all slides ONLY 3 spots away
                    upToThree.Remove(upToTwo);

                    if (upToThree.Count > 0)
                    {
                        validMoves.Add(upToThree);
                    }
                }
            }

            return(validMoves);
        }
Beispiel #5
0
        public MoveSet GetValidMoves()
        {
            MoveSet moves = new MoveSet();

            if (GameInProgress)
            {
                foreach (PieceName pieceName in CurrentTurnPieces)
                {
                    moves.Add(GetValidMoves(pieceName));
                }

                if (moves.Count == 0)
                {
                    moves.Add(Move.Pass);
                }
            }

            return(moves);
        }
Beispiel #6
0
        private MoveSet GetValidBeetleMovements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            // Look in all directions
            for (int direction = 0; direction < EnumUtils.NumDirections; direction++)
            {
                Position newPosition = targetPiece.Position.NeighborAt(direction);

                Piece topNeighbor = GetPieceOnTopInternal(newPosition);

                // Get positions to left and right or direction we're heading
                int      leftOfTarget          = EnumUtils.LeftOf(direction);
                int      rightOfTarget         = EnumUtils.RightOf(direction);
                Position leftNeighborPosition  = targetPiece.Position.NeighborAt(leftOfTarget);
                Position rightNeighborPosition = targetPiece.Position.NeighborAt(rightOfTarget);

                Piece topLeftNeighbor  = GetPieceOnTopInternal(leftNeighborPosition);
                Piece topRightNeighbor = GetPieceOnTopInternal(rightNeighborPosition);

                // At least one neighbor is present
                uint currentHeight     = targetPiece.Position.Stack + 1;
                uint destinationHeight = null != topNeighbor ? topNeighbor.Position.Stack + 1 : 0;

                uint topLeftNeighborHeight  = null != topLeftNeighbor ? topLeftNeighbor.Position.Stack + 1 : 0;
                uint topRightNeighborHeight = null != topRightNeighbor ? topRightNeighbor.Position.Stack + 1 : 0;

                // "Take-off" beetle
                currentHeight--;

                if (!(currentHeight == 0 && destinationHeight == 0 && topLeftNeighborHeight == 0 && topRightNeighborHeight == 0))
                {
                    // Logic from http://boardgamegeek.com/wiki/page/Hive_FAQ#toc9
                    if (!(destinationHeight < topLeftNeighborHeight && destinationHeight < topRightNeighborHeight && currentHeight < topLeftNeighborHeight && currentHeight < topRightNeighborHeight))
                    {
                        Position targetPosition = (newPosition.Stack == destinationHeight) ? newPosition : topNeighbor.Position.GetAbove();
                        Move     targetMove     = new Move(targetPiece.PieceName, targetPosition);
                        validMoves.Add(targetMove);
                    }
                }
            }

            return(validMoves);
        }
Beispiel #7
0
        public static MoveSet ParseMoveStringList(Board board, string moveStringList)
        {
            if (null == board)
            {
                throw new ArgumentNullException(nameof(board));
            }

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

            string[] split = moveStringList.Split(new char[] { MoveSet.MoveStringSeparator }, StringSplitOptions.RemoveEmptyEntries);

            MoveSet moves = new MoveSet();

            for (int i = 0; i < split.Length; i++)
            {
                Move parseMove = ParseMoveString(board, split[i]);
                moves.Add(parseMove);
            }
            return(moves);
        }
Beispiel #8
0
        private MoveSet GetValidLadybugMovements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            Position startingPosition = targetPiece.Position;

            foreach (Move firstMove in GetValidBeetleMovements(targetPiece))
            {
                if (firstMove.Position.Stack > 0)
                {
                    MovePiece(targetPiece, firstMove.Position, false);

                    foreach (Move secondMove in GetValidBeetleMovements(targetPiece))
                    {
                        if (secondMove.Position.Stack > 0)
                        {
                            MovePiece(targetPiece, secondMove.Position, false);

                            foreach (Move thirdMove in GetValidBeetleMovements(targetPiece))
                            {
                                if (thirdMove.Position.Stack == 0 && thirdMove.Position != startingPosition)
                                {
                                    validMoves.Add(thirdMove);
                                }
                            }

                            MovePiece(targetPiece, firstMove.Position, false);
                        }
                    }

                    MovePiece(targetPiece, startingPosition, false);
                }
            }

            return(validMoves);
        }
Beispiel #9
0
        private MoveSet GetValidPlacements(Piece targetPiece)
        {
            PlayerColor targetColor = CurrentTurnColor;

            if (targetPiece.Color != targetColor)
            {
                return(MoveSet.EmptySet);
            }

            if (null == _cachedValidPlacementPositions)
            {
                _cachedValidPlacementPositions = new HashSet <Position>();

                _visitedPlacements = new HashSet <Position>();

                for (int i = 0; i < EnumUtils.NumPieceNames; i++)
                {
                    Piece piece = _pieces[i];
                    if (null != piece && piece.InPlay && PieceIsOnTop(piece) && piece.Color == targetColor)
                    {
                        // Piece is in play, on the top and is the right color, look through neighbors
                        Position bottomPosition = GetPieceOnBottom(piece).Position;
                        _visitedPlacements.Add(bottomPosition);

                        for (int j = 0; j < EnumUtils.NumDirections; j++)
                        {
                            Position neighbor = bottomPosition.NeighborAt(j);

                            if (_visitedPlacements.Add(neighbor) && !HasPieceAt(neighbor))
                            {
                                // Neighboring position is a potential, verify its neighbors are empty or same color
                                bool validPlacement = true;
                                for (int k = 0; k < EnumUtils.NumDirections; k++)
                                {
                                    Position surroundingPosition = neighbor.NeighborAt(k);
                                    Piece    surroundingPiece    = GetPieceOnTopInternal(surroundingPosition);
                                    if (null != surroundingPiece && surroundingPiece.Color != targetColor)
                                    {
                                        validPlacement = false;
                                        break;
                                    }
                                }

                                if (validPlacement)
                                {
                                    _cachedValidPlacementPositions.Add(neighbor);
                                }
                            }
                        }
                    }
                }
#if DEBUG
                ValidMoveCacheMetricsSet["ValidPlacements"].Miss();
#endif
            }
#if DEBUG
            else
            {
                ValidMoveCacheMetricsSet["ValidPlacements"].Hit();
            }
#endif
            MoveSet validMoves = new MoveSet();

            foreach (Position validPlacement in _cachedValidPlacementPositions)
            {
                validMoves.Add(new Move(targetPiece.PieceName, validPlacement));
            }

            return(validMoves);
        }
Beispiel #10
0
        private MoveSet GetValidMovesInternal(Piece targetPiece)
        {
            if (null != targetPiece && GameInProgress)
            {
                if (targetPiece.Color == CurrentTurnColor && PlacingPieceInOrder(targetPiece))
                {
                    if (CurrentTurn == 0 && targetPiece.Color == PlayerColor.White && targetPiece.InHand)
                    {
                        // First move must be at the origin and not the White Queen Bee
                        if (targetPiece.PieceName == PieceName.WhiteQueenBee)
                        {
                            return(MoveSet.EmptySet);
                        }

                        return(new MoveSet()
                        {
                            new Move(targetPiece.PieceName, Position.Origin)
                        });
                    }
                    else if (CurrentTurn == 1 && targetPiece.Color == PlayerColor.Black && targetPiece.InHand)
                    {
                        // Second move must be around the origin and not the Black Queen Bee
                        if (targetPiece.PieceName == PieceName.BlackQueenBee)
                        {
                            return(MoveSet.EmptySet);
                        }

                        MoveSet validMoves = new MoveSet();

                        for (int i = 0; i < EnumUtils.NumDirections; i++)
                        {
                            Position neighbor = Position.Origin.NeighborAt(i);
                            validMoves.Add(new Move(targetPiece.PieceName, neighbor));
                        }

                        return(validMoves);
                    }
                    else if (targetPiece.InHand && (CurrentPlayerTurn != 4 ||                                                                            // Normal turn OR
                                                    (CurrentPlayerTurn == 4 &&                                                                           // Turn 4 and AND
                                                     (CurrentTurnQueenInPlay || (!CurrentTurnQueenInPlay && targetPiece.BugType == BugType.QueenBee))))) // Queen is in play or you're trying to play it
                    {
                        // Look for valid new placements
                        return(GetValidPlacements(targetPiece));
                    }
                    else if (targetPiece.PieceName != LastPieceMoved && targetPiece.InPlay && CurrentTurnQueenInPlay && PieceIsOnTop(targetPiece))
                    {
                        MoveSet validMoves = new MoveSet();

                        if (CanMoveWithoutBreakingHive(targetPiece))
                        {
                            // Look for basic valid moves of played pieces who can move
                            switch (targetPiece.BugType)
                            {
                            case BugType.QueenBee:
                                validMoves.Add(GetValidQueenBeeMovements(targetPiece));
                                break;

                            case BugType.Spider:
                                validMoves.Add(GetValidSpiderMovements(targetPiece));
                                break;

                            case BugType.Beetle:
                                validMoves.Add(GetValidBeetleMovements(targetPiece));
                                break;

                            case BugType.Grasshopper:
                                validMoves.Add(GetValidGrasshopperMovements(targetPiece));
                                break;

                            case BugType.SoldierAnt:
                                validMoves.Add(GetValidSoldierAntMovements(targetPiece));
                                break;

                            case BugType.Mosquito:
                                validMoves.Add(GetValidMosquitoMovements(targetPiece, false));
                                break;

                            case BugType.Ladybug:
                                validMoves.Add(GetValidLadybugMovements(targetPiece));
                                break;

                            case BugType.Pillbug:
                                validMoves.Add(GetValidPillbugBasicMovements(targetPiece));
                                validMoves.Add(GetValidPillbugSpecialAbilityMovements(targetPiece));
                                break;
                            }
                        }
                        else
                        {
                            // Check for special ability moves
                            switch (targetPiece.BugType)
                            {
                            case BugType.Mosquito:
                                validMoves.Add(GetValidMosquitoMovements(targetPiece, true));
                                break;

                            case BugType.Pillbug:
                                validMoves.Add(GetValidPillbugSpecialAbilityMovements(targetPiece));
                                break;
                            }
                        }

                        return(validMoves);
                    }
                }
            }

            return(MoveSet.EmptySet);
        }
Beispiel #11
0
        private MoveSet GetValidMosquitoMovements(Piece targetPiece, bool specialAbilityOnly)
        {
            if (targetPiece.Position.Stack > 0 && !specialAbilityOnly)
            {
                // Mosquito on top acts like a beetle
                return(GetValidBeetleMovements(targetPiece));
            }

            MoveSet validMoves = new MoveSet();

            bool[] bugTypesEvaluated = new bool[EnumUtils.NumBugTypes];

            for (int dir = 0; dir < EnumUtils.NumDirections; dir++)
            {
                Position neighbor = targetPiece.Position.NeighborAt(dir);
                Piece    piece    = GetPieceOnTopInternal(neighbor);

                if (null != piece && !bugTypesEvaluated[(int)(piece.BugType)])
                {
                    if (specialAbilityOnly)
                    {
                        if (piece.BugType == BugType.Pillbug)
                        {
                            validMoves.Add(GetValidPillbugSpecialAbilityMovements(targetPiece));
                        }
                    }
                    else
                    {
                        switch (piece.BugType)
                        {
                        case BugType.QueenBee:
                            validMoves.Add(GetValidQueenBeeMovements(targetPiece));
                            break;

                        case BugType.Spider:
                            validMoves.Add(GetValidSpiderMovements(targetPiece));
                            break;

                        case BugType.Beetle:
                            validMoves.Add(GetValidBeetleMovements(targetPiece));
                            break;

                        case BugType.Grasshopper:
                            validMoves.Add(GetValidGrasshopperMovements(targetPiece));
                            break;

                        case BugType.SoldierAnt:
                            validMoves.Add(GetValidSoldierAntMovements(targetPiece));
                            break;

                        case BugType.Ladybug:
                            validMoves.Add(GetValidLadybugMovements(targetPiece));
                            break;

                        case BugType.Pillbug:
                            validMoves.Add(GetValidPillbugBasicMovements(targetPiece));
                            validMoves.Add(GetValidPillbugSpecialAbilityMovements(targetPiece));
                            break;
                        }
                    }
                    bugTypesEvaluated[(int)(piece.BugType)] = true;
                }
            }

            return(validMoves);
        }