コード例 #1
0
ファイル: BoardContext.cs プロジェクト: IvanovAndrew/Hanabi
 public Builder()
 {
     _boardContext = new BoardContext();
 }
コード例 #2
0
ファイル: State.cs プロジェクト: IvanovAndrew/Hanabi
        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()}");
        }