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