public override State Handle(PlayerAction action, IPlayerContext playerContext) { if (IsPlayFiveRankedAction(action) || IsDiscardNoNeedCard(action)) { return(new FinalWithClueState(this)); } // [A, ход картой] -> A if (IsPlayCardAction(action)) { return(this); } // ["требуется подсказка", взрыв] -> "безвыходная ситуация" // ["требуется подсказка", сброс критичной карты] -> "безвыходная ситуация" if (action.IsActionToAvoid) { return(new NoExitState(this)); } // ["требуется подсказка", сброс некритичной карты] -> "конечное состояние. Подсказка есть" if (IsWhateverToPlayCardAction(action)) { return(new FinalWithClueState(this)); } throw new InvalidOperationException($"Неожиданное состояние {action.GetType()}"); }
public override State Handle(PlayerAction action, IPlayerContext playerContext) { // [_, ход пятёркой] -> "конечное состояние без подсказки" if (IsPlayFiveRankedAction(action)) { return(new FinalWithoutClueState(this, playerContext.Player)); } // [_, сброс ненужной карты] -> "конечное состояние без подсказки" if (IsDiscardNoNeedCard(action)) { // пробуем найти альтернативу. var alternativeAction = action.CreateClueToAvoid(BoardContext, playerContext); var defaultState = new FinalWithoutClueState(this, playerContext.Player); if (alternativeAction != null) { BoardContext.AddToFirework(action.Cards.First()); var situation = new OnlyClueExistsSituation(playerContext, alternativeAction.Clue); var optionalState = new OptionalClueState(this, situation); return(new MixedState(optionalState, defaultState)); } else { return(defaultState); } } // [A, ход картой] -> A if (IsPlayCardAction(action)) { BoardContext.AddToFirework(action.Cards.First()); return(this); } // ["никаких подсказок не требуется", сброс некритичной карты] -> "возможна подсказка" или "плюс подсказка" if (IsWhateverToPlayCardAction(action)) { var clueAndAction = action.CreateClueToAvoid(BoardContext, playerContext); if (clueAndAction != null) { // добавить в сброшенные карты карту, которая полетит? return(new OptionalClueState(this, new OnlyClueExistsSituation(playerContext, clueAndAction.Clue))); } else { return(new FinalWithoutClueState(this, playerContext.Player)); } } // ["никаких подсказок не требуется", взрыв] -> "требуется подсказка" или безвыходная ситуация // ["никаких подсказок не требуется", сброс критичной карты] -> "требуется подсказка" или безвыходная ситуация if (action.IsActionToAvoid) { ClueAndAction clueAndAction = action.CreateClueToAvoid(BoardContext, playerContext); if (clueAndAction == null) { return(new NoExitState(this)); } // TODO выяснить, что будет делать игрок после этой подсказки // Если действие порождает подсказку, то можно уходить в конечной состояние. var correctedAction = clueAndAction.Action; var solution = new OnlyClueExistsSituation(playerContext, clueAndAction.Clue); var requiredClueState = new RequiredClue(this, solution); if ((correctedAction.Outcome & OutcomeFlags.Play) > 0) { return(requiredClueState); } else if ((correctedAction.Outcome & (OutcomeFlags.DiscardNoNeedCard | OutcomeFlags.DiscardWhateverToPlayCard | OutcomeFlags.PlayFiveRankCard)) > 0) { return(new FinalWithClueState(requiredClueState)); } throw new InvalidOperationException($"{action.GetType()}"); } throw new InvalidOperationException($"Неизвестный тип {action.GetType()}"); }