private void ExecuteNextAction(BoardPress action, BoardPressStateInfo stateInfo)
        {
            switch (action)
            {
            case BoardPress.CLICK_HIGHLIGHT:
                NextActionHighlight(stateInfo.piece.Value);
                break;

            case BoardPress.MOVE_PIECE:
                NextActionMovePiece(stateInfo.piece.Value, stateInfo.tile.Value);
                break;

            case BoardPress.DROP:
                NextActionDropPiece(stateInfo.handPiece.Value, stateInfo.tile.Value);
                break;

            case BoardPress.SUBSTITUTION:
                NextActionSubstitution(stateInfo.piece.Value, stateInfo.tile.Value);
                break;

            case BoardPress.TIER_1_3_EXCHANGE:
                NextActionTierExchange(stateInfo.tile.Value);
                break;

            case BoardPress.NOTHING:
                break;

            default:
                throw new InvalidOperationException("Invalid or unsupported BoardPress state");
            }
        }
        public void Step(ref BoardPressStepState token, int condition)
        {
            ConstraintCheck(ref token);

            BoardPressStateInfo stateInfo = pieceTileService.FindBoardPressStateInfo(entitiesDB, ref token);
            bool   substitutionPossible   = pieceTileService.IsSubstitutionPossible(stateInfo, entitiesDB);
            bool   tierExchangePossible   = pieceTileService.IsTierExchangePossible(stateInfo, entitiesDB);
            TurnEV currentTurn            = turnService.GetCurrentTurnEV(entitiesDB);

            BoardPress action = boardPressService.DecideAction(
                stateInfo,
                substitutionPossible,
                tierExchangePossible,
                currentTurn);

            ExecuteNextAction(action, stateInfo);
        }
        public BoardPress DecideAction(
            BoardPressStateInfo stateInfo,
            bool substitutionPossible,
            bool tierExchangePossible,
            TurnEV currentTurn)
        {
            BoardPress returnValue = BoardPress.NOTHING;
            TileEV     tileEV      = stateInfo.tile.Value;
            int        tilePieceId = tileEV.Tile.PieceRefEntityId.GetValueOrDefault();

            // TODO Scenario: Clicked highlighted tile containing opponent piece to initiate mobile capture

            // If hand piece highlighted, it's an attempted drop
            if (stateInfo.handPiece.HasValue)
            {
                returnValue = BoardPress.DROP;
            }
            else if (currentTurn.InitialArrangement.IsInitialArrangementInEffect)
            {   // User is not dropping during Initial Arrangement, so deny
                returnValue = BoardPress.NOTHING;
            }
            else if (substitutionPossible)
            {
                returnValue = BoardPress.SUBSTITUTION;
            }
            else if (tierExchangePossible)
            {
                returnValue = BoardPress.TIER_1_3_EXCHANGE;
            }
            // Tile is clicked, tile highlighted, piece reference exists; move vs mobile capture determined in later engine
            else if (tileEV.Highlight.IsHighlighted &&
                     stateInfo.piece.HasValue &&
                     tilePieceId != 0 &&
                     stateInfo.piece.Value.PlayerOwner.PlayerColor == currentTurn.TurnPlayer.PlayerColor)
            {
                returnValue = BoardPress.MOVE_PIECE;
            }
            // NOT move scenario, Piece/Tile clicked, both piece and tile exist, piece reference does not exist
            else if (stateInfo.piece.HasValue && tilePieceId == 0)
            {
                returnValue = BoardPress.CLICK_HIGHLIGHT;
            }

            return(returnValue);
        }