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); }
private MoveSet GetValidQueenBeeMovements(Piece targetPiece) { // Get all slides one away return(GetValidSlides(targetPiece, 1)); }
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); }
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()); }
protected bool PieceIsOnTop(Piece targetPiece) { return(null == targetPiece.PieceAbove); }
protected bool PieceIsOnBottom(Piece targetPiece) { return(null == targetPiece.PieceBelow); }
protected void MovePiece(Piece piece, Position newPosition) { MovePiece(piece, newPosition, true); }
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"); } }
private MoveSet GetValidPillbugBasicMovements(Piece targetPiece) { return(GetValidSlides(targetPiece, 1)); }
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); }
private MoveSet GetValidSoldierAntMovements(Piece targetPiece) { // Get all slides all the way around return(GetValidSlides(targetPiece, null)); }