예제 #1
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
        private MoveSet GetValidPlacements(Piece targetPiece)
        {
            MoveSet validMoves = new MoveSet();

            Color targetColor = CurrentTurnColor;

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

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

                _visitedPlacements.Clear();

                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);
                                }
                            }
                        }
                    }
                }

                ValidMoveCacheMetricsSet["ValidPlacements"].Miss();
            }
            else
            {
                ValidMoveCacheMetricsSet["ValidPlacements"].Hit();
            }

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

            return(validMoves);
        }
예제 #2
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 private MoveSet GetValidQueenBeeMovements(Piece targetPiece)
 {
     // Get all slides one away
     return(GetValidSlides(targetPiece, 1));
 }
예제 #3
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
        public bool IsOneHive()
        {
            // Whether or not a piece has been found to be part of the hive
            bool[] partOfHive    = new bool[EnumUtils.NumPieceNames];
            int    piecesVisited = 0;

            // Find a piece on the board to start checking
            Piece startingPiece = null;

            foreach (PieceName pieceName in EnumUtils.PieceNames)
            {
                Piece piece = GetPiece(pieceName);
                if (null == piece || piece.InHand)
                {
                    partOfHive[(int)pieceName] = true;
                    piecesVisited++;
                }
                else
                {
                    partOfHive[(int)pieceName] = false;
                    if (null == startingPiece && piece.Position.Stack == 0)
                    {
                        // Save off a starting piece on the bottom
                        startingPiece = piece;
                        partOfHive[(int)pieceName] = true;
                        piecesVisited++;
                    }
                }
            }

            // There is at least one piece on the board
            if (null != startingPiece && piecesVisited < EnumUtils.NumPieceNames)
            {
                Queue <Piece> piecesToLookAt = new Queue <Piece>();
                piecesToLookAt.Enqueue(startingPiece);

                while (piecesToLookAt.Count > 0)
                {
                    Piece currentPiece = piecesToLookAt.Dequeue();

                    // Check all pieces at this stack level
                    for (int i = 0; i < EnumUtils.NumDirections; i++)
                    {
                        Position neighbor      = currentPiece.Position.NeighborAt(i);
                        Piece    neighborPiece = GetPiece(neighbor);
                        if (null != neighborPiece && !partOfHive[(int)neighborPiece.PieceName])
                        {
                            piecesToLookAt.Enqueue(neighborPiece);
                            partOfHive[(int)neighborPiece.PieceName] = true;
                            piecesVisited++;
                        }
                    }

                    // Check for all pieces above this one
                    Piece pieceAbove = currentPiece.PieceAbove;
                    while (null != pieceAbove)
                    {
                        partOfHive[(int)pieceAbove.PieceName] = true;
                        piecesVisited++;
                        pieceAbove = pieceAbove.PieceAbove;
                    }
                }
            }

            return(piecesVisited == EnumUtils.NumPieceNames);
        }
예제 #4
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
        private MoveSet GetValidMovesInternal(Piece targetPiece)
        {
            if (null != targetPiece && GameInProgress)
            {
                if (targetPiece.Color == CurrentTurnColor && PlacingPieceInOrder(targetPiece))
                {
                    if (CurrentTurn == 0 && targetPiece.Color == Color.White && targetPiece.InHand && targetPiece.PieceName != PieceName.WhiteQueenBee)
                    {
                        // First move must be at the origin and not the White Queen Bee
                        MoveSet validMoves = new MoveSet();
                        validMoves.Add(new Move(targetPiece.PieceName, Position.Origin));
                        return(validMoves);
                    }
                    else if (CurrentTurn == 1 && targetPiece.Color == Color.Black && targetPiece.InHand && targetPiece.PieceName != PieceName.BlackQueenBee)
                    {
                        MoveSet validMoves = new MoveSet();
                        // Second move must be around the origin and not the Black Queen Bee
                        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(new MoveSet());
        }
예제 #5
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 protected bool PieceIsOnTop(Piece targetPiece)
 {
     return(null == targetPiece.PieceAbove);
 }
예제 #6
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 protected bool PieceIsOnBottom(Piece targetPiece)
 {
     return(null == targetPiece.PieceBelow);
 }
예제 #7
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 protected void MovePiece(Piece piece, Position newPosition)
 {
     MovePiece(piece, newPosition, true);
 }
예제 #8
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
        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");
            }
        }
예제 #9
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 private MoveSet GetValidPillbugBasicMovements(Piece targetPiece)
 {
     return(GetValidSlides(targetPiece, 1));
 }
예제 #10
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
        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);
        }
예제 #11
0
파일: Board.cs 프로젝트: Khaleesh/Mzinga
 private MoveSet GetValidSoldierAntMovements(Piece targetPiece)
 {
     // Get all slides all the way around
     return(GetValidSlides(targetPiece, null));
 }