private bool IsValidEarthLinkDrop(List <PieceEV> piecesAtLocation, PieceSide?side)
        {
            // Since this is called after IsEmptyTile with an OR condition, we know there is at least one piece on the tile
            PieceEV topPiece = piecesAtLocation[piecesAtLocation.Count - 1];

            return(topPiece.Tier.Tier < 3 && AbilityToPiece.HasAbility(GetEarthLinkAbilityType(side), topPiece.Piece.PieceType));
        }
 public List <PieceEV> FindPiecesByTeamAndAbility(PreMoveAbility preMoveAbility, PlayerColor teamColor, IEntitiesDB entitiesDB)
 {
     return(FindAllBoardPieces(entitiesDB).Where(piece =>
                                                 piece.PlayerOwner.PlayerColor == teamColor &&
                                                 piece.Tier.TopOfTower &&
                                                 AbilityToPiece.HasAbility(preMoveAbility, piece.Piece.PieceType)).ToList());
 }
        public bool IsSubstitutionPossible(PieceEV?clickedPiece, TileEV?clickedTile, IEntitiesDB entitiesDB)
        {
            // Remember, Commander cannot run to Samurai during check, b/c that's a violation of a different rule

            /* Conditions:
             *      piece clicked
             *      not a destination tile (user is clicking this piece to access substitution ability or click-highlight it)
             *      commander in check
             *      samurai (has substitution ability)
             *      piece is topOfTower
             *      piece tier == 1
             *      piece is adjacent to Commander vertically or horizontally
             *      substitution would resolve check
             */

            TurnEV  currentTurn = turnService.GetCurrentTurnEV(entitiesDB);
            PieceEV commander   = pieceFindService.FindCommander(currentTurn.TurnPlayer.PlayerColor, entitiesDB);

            return(currentTurn.Check.CommanderInCheck &&
                   clickedPiece.HasValue &&
                   clickedTile.HasValue &&
                   (!clickedTile.Value.Tile.PieceRefEntityId.HasValue || clickedTile.Value.Tile.PieceRefEntityId.Value == 0) &&
                   AbilityToPiece.HasAbility(OtherMoveAbility.SUBSTITUTION, clickedPiece.Value.Piece.PieceType) &&
                   clickedPiece.Value.Tier.Tier == 1 &&
                   clickedPiece.Value.Tier.TopOfTower &&
                   IsAdjacentLocationToCommander(clickedPiece.Value, commander) &&
                   DoesSubstitutionResolveCheck(clickedPiece.Value, commander, entitiesDB));
        }
 private bool TwoFileMoveViolated(List <PieceEV> towerPieces, PlayerColor currentTurnColor)
 {
     // 2+ Friendly Bronze pieces in the tower counts as a violation
     return(towerPieces.Where(piece => piece.PlayerOwner.PlayerColor == currentTurnColor &&
                              piece.Location.Location != BoardConst.HAND_LOCATION &&
                              AbilityToPiece.HasAbility(PreMoveAbility.TWO_FILE_MOVE, piece.Piece.PieceType))
            .ToList().Count > 1);
 }
Beispiel #5
0
 private bool IsTier1ExchangePossible(List <PieceEV> towerPieces, PlayerColor currentTurnColor)
 {
     return(towerPieces.Count == 3 &&
            AbilityToPiece.HasAbility(OtherMoveAbility.TIER_1_EXCHANGE, towerPieces[0].Piece.PieceType) &&
            !AbilityToPiece.HasAbility(OtherMoveAbility.TIER_3_EXCHANGE, towerPieces[2].Piece.PieceType) &&
            towerPieces[2].PlayerOwner.PlayerColor == currentTurnColor &&
            towerPieces[0].PlayerOwner.PlayerColor == currentTurnColor);
 }
        private bool TwoFileMoveViolatedByBetrayal(ref MovePieceStepState token)
        {
            List <PieceEV> towerPieces = pieceFindService.FindPiecesByLocation(token.DestinationTile.Location.Location, entitiesDB);
            PieceEV        pieceToMove = token.PieceToMove;

            return(towerPieces.Count > 0 &&
                   AbilityToPiece.HasAbility(PreMoveAbility.TWO_FILE_MOVE, token.PieceToMove.Piece.PieceType) &&
                   AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, token.PieceToMove.Piece.PieceType) &&
                   towerPieces.Where(piece => piece.Piece.PieceType == pieceToMove.Piece.Front &&
                                     !piece.Tier.TopOfTower).ToList().Count > 0);
        }
        public bool CannotCaptureCommanderViolated(List <PieceEV> towerPieces, PlayerColor currentTurnColor, IEntitiesDB entitiesDB)
        {
            List <PieceEV> newTowerPieces = towerPieces.Where(piece => piece.Location.Location != BoardConst.HAND_LOCATION).ToList();

            return(newTowerPieces.Count > 1 &&
                   newTowerPieces[newTowerPieces.Count - 2].PlayerOwner.PlayerColor != currentTurnColor &&
                   newTowerPieces[newTowerPieces.Count - 2].Piece.PieceType == PieceType.COMMANDER &&
                   AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_CAPTURE_COMMANDER, newTowerPieces.Last().Piece.PieceType) &&
                   FindCheckmateFoulThreatsToLocation(newTowerPieces[0].Location.Location, currentTurnColor, entitiesDB).Count > 0 &&
                   FindThreatsToLocation(newTowerPieces[0].Location.Location, currentTurnColor, entitiesDB).Count == 0);
        }
        private bool IsAffectedByMobileRangeExpansionLine(PlayerColor playerColor, Vector2 location, List <PieceEV> allPieces)
        {
            List <PieceEV> piecesMreLine = allPieces.Where(piece =>
                                                           piece.PlayerOwner.PlayerColor == playerColor &&
                                                           AbilityToPiece.HasAbility(PreMoveAbility.MOBILE_RANGE_EXPANSION_LINE, piece.Piece.PieceType)).ToList();

            if (piecesMreLine.Count == 0)
            {
                return(false);
            }

            List <PieceEV> piecesMreLineInRange = piecesMreLine.Where(piece =>
                                                                      distanceService.IsAhead(piece.Location.Location, location, playerColor)).ToList();

            return(piecesMreLineInRange.Count > 0);
        }
        private bool IsAffectedByMobileRangeExpansionRadial(PlayerColor playerColor, Vector2 location, List <PieceEV> allPieces)
        {
            List <PieceEV> piecesMreRadial = allPieces.Where(piece =>
                                                             piece.PlayerOwner.PlayerColor == playerColor &&
                                                             AbilityToPiece.HasAbility(PreMoveAbility.MOBILE_RANGE_EXPANSION_RADIAL, piece.Piece.PieceType)).ToList();

            if (piecesMreRadial.Count == 0)
            {
                return(false);
            }

            List <PieceEV> piecesMreRadialInRange = piecesMreRadial.Where(piece =>
                                                                          distanceService.CalcAbsoluteDistance(location, piece.Location.Location) <= 2).ToList();

            return(piecesMreRadialInRange.Count > 0);
        }
        private void ExcludeDestinationsAtCannotBeStackedPieces(List <Vector2> destinations, List <PieceEV> allPieces)
        {
            List <Vector2> destinationsToRemove  = new List <Vector2>();
            List <PieceEV> cannotBeStackedPieces = allPieces.Where(piece => piece.PlayerOwner.PlayerColor == piece.PlayerOwner.PlayerColor &&
                                                                   AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_BE_STACKED, piece.Piece.PieceType)).ToList();

            foreach (Vector2 destination in destinations)
            {
                List <PieceEV> piecesAtDestination = FindPiecesAtLocation(destination, allPieces);

                if (piecesAtDestination.Count > 0 &&
                    AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_BE_STACKED, piecesAtDestination.Last().Piece.PieceType))
                {
                    destinationsToRemove.Add(destination);
                }
            }

            foreach (Vector2 removeDestination in destinationsToRemove)
            {
                destinations.Remove(removeDestination);
            }
        }
        /**
         * If pieceEV has betrayal and two file move (Bronze), deny all destination tiles with another friendly piece
         * with same abilities (Bronze)
         *
         * Also, deny destination if it has an enemy tier 3 tower with a buried enemy pawn
         *      Reason is capture would be mandatory, triggering betrayal, flipping buried enemy pawn into friendly
         *      bronze, thus violating two file move
         */
        private void ExcludeTwoFileMoveViolations(
            PieceEV pieceEV, List <Vector2> destinations, List <PieceEV> allPieces)
        {
            // Only care about Bronze pieces, which only have Single move sets
            if (!AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, pieceEV.Piece.PieceType) ||
                !AbilityToPiece.HasAbility(PreMoveAbility.TWO_FILE_MOVE, pieceEV.Piece.PieceType))
            {
                return;
            }

            List <Vector2> destinationsToRemove  = new List <Vector2>();
            List <PieceEV> otherPiecesOfSameType = allPieces.Where(piece => piece.Piece.PieceType == pieceEV.Piece.PieceType &&
                                                                   piece.PlayerOwner.PlayerColor == pieceEV.PlayerOwner.PlayerColor &&
                                                                   piece.ID.entityID != pieceEV.ID.entityID).ToList();

            foreach (Vector2 destination in destinations)
            {
                if (otherPiecesOfSameType.Where(piece => piece.Location.Location.x == destination.x).ToList().Count > 0)
                {
                    destinationsToRemove.Add(destination);
                }
                else
                {
                    List <PieceEV> destinationPieces = FindPiecesAtLocation(destination, allPieces);

                    if (destinationPieces.Count == 3 && destinationPieces[2].PlayerOwner.PlayerColor != pieceEV.PlayerOwner.PlayerColor &&
                        ((destinationPieces[0].Piece.PieceType != pieceEV.Piece.PieceType && destinationPieces[0].Piece.Back == pieceEV.Piece.PieceType) ||
                         (destinationPieces[0].Piece.PieceType != pieceEV.Piece.PieceType && destinationPieces[0].Piece.Back == pieceEV.Piece.PieceType)))
                    {
                        destinationsToRemove.Add(destination);
                    }
                }
            }

            foreach (Vector2 removeDestination in destinationsToRemove)
            {
                destinations.Remove(removeDestination);
            }
        }
        private bool DropCheckmateNotViolated(
            PieceEV pieceToDrop,
            Vector2 location,
            PlayerColor playerColor,
            PieceSide side,
            HandPieceEV handPiece,
            DropCheckmateLevel recursionLevel,
            IEntitiesDB entitiesDB)
        {
            bool        returnValue      = true;
            PlayerColor enemyPlayerColor = TurnService.CalcOtherTurnPlayer(playerColor);

            if (recursionLevel != DropCheckmateLevel.FINAL_TURN_PLAYER_CHECK && // Prevent infinite recursion
                AbilityToPiece.HasAbility(DropAbility.CANNOT_DROP_CHECKMATE, pieceToDrop.Piece.PieceType) &&
                checkService.IsCommanderInCheck(enemyPlayerColor, entitiesDB))
            {
                recursionLevel = recursionLevel == DropCheckmateLevel.FIRST_TURN_PLAYER_CHECK
                    ? DropCheckmateLevel.SECOND_ENEMY_PLAYER_CHECK : DropCheckmateLevel.FINAL_TURN_PLAYER_CHECK;
                returnValue = AnyValidMoves(enemyPlayerColor, entitiesDB, recursionLevel);
            }

            return(returnValue);
        }
        private bool CannotCaptureBecauseBetrayViolatesTwoFileMove(PieceEV pieceToMove, Vector2 destination, List <PieceEV> allPieces)
        {
            // Only care about Bronze pieces, which only have Single move sets
            if (!AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, pieceToMove.Piece.PieceType) ||
                !AbilityToPiece.HasAbility(PreMoveAbility.TWO_FILE_MOVE, pieceToMove.Piece.PieceType))
            {
                return(false);
            }

            bool           returnValue = false;
            List <PieceEV> towerPieces = FindPiecesAtLocation(destination, allPieces);

            // Do not examine top piece, since it could be captured
            for (int i = 0; i < towerPieces.Count - 1; ++i)
            {
                if (towerPieces[i].Piece.PieceType == pieceToMove.Piece.Front)
                {
                    returnValue = true;
                    break;
                }
            }

            return(returnValue);
        }
 private bool HasForcedRearrangementAbility(PieceType pieceType)
 {
     return(AbilityToPiece.HasAbility(PostMoveAbility.FORCED_REARRANGEMENT, pieceType));
 }
 // TODO This is duplicated elsewhere, refactor into common service later
 private bool BetrayalInEffect(ref DeterminePostMoveStepState token)
 {
     return(token.PieceMoved.Tier.TopOfTower &&
            token.PieceCaptured.HasValue &&
            AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, token.PieceMoved.Piece.PieceType));
 }
 private bool HasForcedRecoveryAbility(PieceType pieceType)
 {
     return(AbilityToPiece.HasAbility(PostMoveAbility.FORCED_RECOVERY, pieceType));
 }
        private bool ShouldRemoveDestination(
            PieceEV pieceToCalc, Vector2 destination, List <PieceEV> allPieces, bool canIgnoreFriendlyPieces)
        {
            bool    returnValue   = false;
            Vector2 pieceLocation = pieceToCalc.Location.Location;

            Vector2 increment = new Vector2(
                pieceLocation.x == destination.x ?
                0 : (pieceLocation.x - destination.x) / Math.Abs(pieceLocation.x - destination.x),
                pieceLocation.y == destination.y ?
                0 : (pieceLocation.y - destination.y) / Math.Abs(pieceLocation.y - destination.y)
                );

            Vector2 evalLocation = pieceLocation - increment;

            while (evalLocation != destination)
            {
                int numPiecesBarringPath = allPieces.Where(piece =>
                                                           evalLocation == piece.Location.Location &&
                                                           (!canIgnoreFriendlyPieces ||
                                                            (piece.PlayerOwner.PlayerColor != pieceToCalc.PlayerOwner.PlayerColor ||
                                                             (piece.Tier.TopOfTower && AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_BE_STACKED, piece.Piece.PieceType)))
                                                           )).Count();

                if (numPiecesBarringPath > 0)
                {
                    returnValue = true;
                    break;
                }

                evalLocation -= increment;
            }

            return(returnValue);
        }
 private bool HaveCapturedForcedRearrangementPiece(PreviousMoveState previousMoveState)
 {
     return(previousMoveState.pieceCaptured.HasValue &&
            AbilityToPiece.HasAbility(PostMoveAbility.FORCED_REARRANGEMENT, previousMoveState.pieceCaptured.Value.Piece.Piece.PieceType));
 }
 private bool CanMobileRangeExpansion(PieceEV piece)
 {
     return(!AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_MOBILE_RANGE_EXPANSION, piece.Piece.PieceType));
 }
 // TODO This public method belongs in a different service, such as a PieceAbilityService
 public bool IsForcedRearrangementPossible(PieceEV forcedRearrangementPiece)
 {
     return(AbilityToPiece.HasAbility(PostMoveAbility.FORCED_REARRANGEMENT, forcedRearrangementPiece.Piece.PieceType));
 }
 private bool BetrayalInEffect(PieceEV pieceToMove)
 {
     return(pieceToMove.Tier.TopOfTower &&
            AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, pieceToMove.Piece.PieceType));
 }
 // Return true if piece is not a turn player piece or DOES NOT possess CANNOT_IMMOBILE_CAPTURE ability
 public bool CanImmobileCapture(PlayerColor playerColor, PieceEV piece)
 {
     return(piece.PlayerOwner.PlayerColor != playerColor || !AbilityToPiece.HasAbility(PreMoveAbility.CANNOT_IMMOBILE_CAPTURE, piece.Piece.PieceType));
 }
 private bool IsFriendlyBetrayalTopOfTower(List <PieceEV> towerPieces, PlayerColor currentTurnColor, IEntitiesDB entitiesDB)
 {
     return(towerPieces[towerPieces.Count - 1].PlayerOwner.PlayerColor == currentTurnColor &&
            AbilityToPiece.HasAbility(PostMoveAbility.BETRAYAL, towerPieces[towerPieces.Count - 1].Piece.PieceType));
 }