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