private PreviousTowerState?SaveDestinationTowerState(PreviousMoveState previousMoveState, List <PieceEV> allPieces)
        {
            PreviousTowerState returnValue = new PreviousTowerState
            {
                Pieces = new List <PreviousPieceState>()
            };

            List <PieceEV> piecesAtDestination = FindPiecesAtLocation(previousMoveState.pieceCaptured.Value.Location, allPieces); // Min size one

            foreach (PieceEV piece in piecesAtDestination)
            {
                returnValue.Pieces.Add(SaveSingleState(piece));
            }

            return(returnValue);
        }
        private PreviousMoveState SaveCurrentMove(PieceEV pieceToMove, Vector2 destination, List <PieceEV> allPieces)
        {
            List <PieceEV> piecesAtCurrentLocation = FindPiecesAtLocation(pieceToMove.Location.Location, allPieces); // Min size one
            List <PieceEV> topPieceAtDestination   = allPieces.Where(piece =>                                        // Size one or zero
                                                                     piece.Location.Location == destination && piece.Tier.TopOfTower).ToList();

            PreviousMoveState returnValue = new PreviousMoveState
            {
                pieceToMove = SaveSingleState(pieceToMove),
                pieceBelow  = piecesAtCurrentLocation.Count == 1
                    ? null : (PreviousPieceState?)SaveSingleState(piecesAtCurrentLocation[pieceToMove.Tier.Tier - 2]),
                pieceCaptured = topPieceAtDestination.Count == 0
                    ? null : (PreviousPieceState?)SaveSingleState(topPieceAtDestination[0])
            };

            return(returnValue);
        }
Ejemplo n.º 3
0
        // Will need to be careful of betrayal effect when doing temp move
        private bool IsMobileMoveValid(PieceEV pieceToCalc, Vector2 destination, bool shouldStackEnemyPiece, IEntitiesDB entitiesDB)
        {
            List <PieceEV> allPieces = pieceFindService.FindAllBoardPieces(entitiesDB).ToList();
            // Make temp move while saving old info
            PreviousMoveState  previousMoveState             = destinationTileService.SaveCurrentMove(pieceToCalc, destination, allPieces);
            PreviousTowerState?previousDestinationTowerState = previousMoveState.pieceCaptured.HasValue &&
                                                               destinationTileService.BetrayalInEffect(previousMoveState.pieceToMove.Piece)
                ? destinationTileService.SaveDestinationTowerState(previousMoveState, allPieces) : null;

            destinationTileService.MakeTemporaryMove(pieceToCalc, destination, allPieces, shouldStackEnemyPiece);

            bool returnValue = !checkService.IsCommanderInCheck(pieceToCalc.PlayerOwner.PlayerColor, entitiesDB);

            if (returnValue)
            {
                returnValue = !checkService.CannotCaptureCommanderViolated(destination, pieceToCalc.PlayerOwner.PlayerColor, entitiesDB);
            }

            destinationTileService.RestorePreviousState(previousMoveState, previousDestinationTowerState);

            return(returnValue);
        }
        private void RestorePreviousState(PreviousMoveState previousState, PreviousTowerState?previousDestinationTowerState)
        {
            if (previousDestinationTowerState.HasValue)
            {
                foreach (PreviousPieceState previousTowerPieceState in previousDestinationTowerState.Value.Pieces)
                {
                    RestoreSingleState(previousTowerPieceState);
                }
            }

            RestoreSingleState(previousState.pieceToMove);

            if (previousState.pieceBelow.HasValue)
            {
                RestoreSingleState(previousState.pieceBelow.Value);
            }

            if (previousState.pieceCaptured.HasValue)
            {
                RestoreSingleState(previousState.pieceCaptured.Value);
            }
        }
 private bool HaveCapturedForcedRearrangementPiece(PreviousMoveState previousMoveState)
 {
     return(previousMoveState.pieceCaptured.HasValue &&
            AbilityToPiece.HasAbility(PostMoveAbility.FORCED_REARRANGEMENT, previousMoveState.pieceCaptured.Value.Piece.Piece.PieceType));
 }
        private void ExcludeCheckViolations(PieceEV pieceEV, List <Vector2> returnValue, List <PieceEV> allPieces, IEntitiesDB entitiesDB)
        {
            PieceEV commander = allPieces.First(piece =>
                                                piece.Piece.PieceType == PieceType.COMMANDER && piece.PlayerOwner.PlayerColor == pieceEV.PlayerOwner.PlayerColor);
            List <PieceEV> commanderTowerPieces = FindPiecesAtLocation(commander.Location.Location, allPieces);

            // If Commander safely buried in a tower whose adjacent piece(s) are not changing, Commander cannot be in check this turn
            if (pieceEV.Location.Location != commander.Location.Location && IsCommanderBuried(commander, commanderTowerPieces))
            {
                return;
            }

            // If piece below Commander is enemy piece, moving another piece won't help
            if (pieceEV.ID.entityID != commander.ID.entityID && IsCommanderInDangerFromBelow(commander, commanderTowerPieces))
            {
                returnValue.RemoveAll(delegate(Vector2 v1)
                                      { return(true); });

                return;
            }

            // Commander is topOfTower
            List <Vector2> destinationsToRemove = new List <Vector2>();
            List <PieceEV> enemyThreats         = new List <PieceEV>();

            if (pieceEV.ID.entityID != commander.ID.entityID)
            {
                enemyThreats = FindEnemyThreats(commander, pieceEV, allPieces, entitiesDB);

                if (enemyThreats.Count == 0)
                {
                    return;
                }
            }

            foreach (Vector2 destination in returnValue)
            {
                // Commander in check cannot move to a tile occupied by a friendly piece
                if (pieceEV.ID.entityID == commander.ID.entityID &&
                    DestinationOccupiedByFriendly(pieceEV.PlayerOwner.PlayerColor, destination, allPieces) &&
                    IsCommanderInCheck(pieceEV.PlayerOwner.PlayerColor, entitiesDB))
                {
                    destinationsToRemove.Add(destination);
                    continue;
                }

                // Make temp move while saving old info
                PreviousMoveState  previousMoveState             = SaveCurrentMove(pieceEV, destination, allPieces);
                PreviousTowerState?previousDestinationTowerState = previousMoveState.pieceCaptured.HasValue &&
                                                                   BetrayalInEffect(previousMoveState.pieceToMove.Piece)
                    ? SaveDestinationTowerState(previousMoveState, allPieces) : null;
                MakeTemporaryMove(pieceEV, destination, allPieces);

                // If piece covers Commander, no threat to Commander
                if (pieceEV.ID.entityID != commander.ID.entityID &&
                    !commander.Tier.TopOfTower && pieceEV.Location.Location == commander.Location.Location)
                {
                    RestorePreviousState(previousMoveState, previousDestinationTowerState);
                    continue;
                }

                // If Commander captures enemy piece, it cannot put itself into check b/c of another enemy piece right below that piece
                if (pieceEV.ID.entityID == commander.ID.entityID && SecondFromTopTowerPiecesEnemy(pieceEV, allPieces))
                {
                    destinationsToRemove.Add(destination);
                    RestorePreviousState(previousMoveState, previousDestinationTowerState);
                    continue;
                }

                if (pieceEV.ID.entityID == commander.ID.entityID)
                {
                    enemyThreats = FindEnemyThreats(commander, pieceEV, allPieces, entitiesDB);
                }

                // If no threats
                if (enemyThreats.Count == 0)
                {
                    RestorePreviousState(previousMoveState, previousDestinationTowerState);
                    continue;
                }

                List <PieceEV> actualThreats = FindActualEnemyThreats(commander, enemyThreats, allPieces, entitiesDB);

                if (actualThreats.Count > 0)
                {
                    // Special scenario: Capture enemy lance to initiate Forced Rearrangement, then drop Catapult/Fortress to resolve check
                    if (HaveCapturedForcedRearrangementPiece(previousMoveState) &&
                        ForcedRearrangementCanResolveThreats(commander, previousMoveState.pieceCaptured.Value.Piece, actualThreats, allPieces, entitiesDB))
                    {
                        // TODO Clean up boolean statement logic here
                        RestorePreviousState(previousMoveState, previousDestinationTowerState);
                        continue;
                    }
                    else
                    {
                        destinationsToRemove.Add(destination);
                    }
                }

                // Restore old info into values
                RestorePreviousState(previousMoveState, previousDestinationTowerState);
            }

            foreach (Vector2 removeDestination in destinationsToRemove)
            {
                returnValue.Remove(removeDestination);
            }
        }