스타가 즐겨하는 게임에서 이벤트로 멀리뛰기 미니게임을 출시했다. 미니게임에 과몰입하던 스타는 프레임마다 입력되는 커맨드가 주어질 때 예상 기록을 계산해 보려고 한다. 다음 명세를 보고 프레임마다 커맨드 입력 여부 및 입력한 커맨드의 종류가 주어질 때 멀리뛰기 기록을 계산해 주는 프로그램을 만들어 보자.
먼저 플레이어의 능력치는 아래와 같다.
- $\text{base}_x$: 플레이어의 기본 $x$축 속도이다.
- $\text{jump}$: 플레이어의 점프력이다.
- $\text{dash}$: 플레이어의 대시 상태를 표현하는 값이다.
- $\text{dash} > 0$이면 대시 상태이고 $\text{dash} = 0$이면 대시 상태가 아니다. 대시 상태 동안에는 중력의 영향을 받지 않으며 이동, 공격, 버프 스킬 및 소비 아이템을 사용할 수 없다.
- $\text{dash} > 0$이면 2ドル$프레임 간격으로 $\text{dash}$가 1ドル$만큼 감소한다. 다시 말해 어떤 프레임에서 $\text{dash}$가 변했고 $\text{dash} > 0$이라면 2ドル$프레임 뒤에 $\text{dash}$를 1ドル$ 감소한다.
- $\text{quick}$: 퀵 드롭 상태이면 1ドル$ 아니면 0ドル$이다.
- $\text{accel}$: 가속 상태이면 1ドル$ 아니면 0ドル$이다.
- $\text{weak}$: 중력 약화 상태면 1ドル$ 아니면 0ドル$이다.
- $\text{maxdrop}$ : 플레이어의 최대 낙하 속도다.
- $\text{motion}$: 플레이어가 아이템 사용모션을 취하고 있는 상태면 1ドル$ 아니면 0ドル$이다.
- 사용모션을 취하고 있는 상태면 해당 프레임에서는 이동, 공격, 버프 스킬 및 소비 아이템을 사용할 수 없고 중력의 영향을 받지 않는다.
그 외 게임과 관련된 정보는 아래와 같다.
- $\text{base}_g$: 기본 중력 크기이다.
- $\text{init}_y$: 플레이어가 처음에 시작하는 $y$좌표이다.
미니게임에서는 이동 스킬, 공격 스킬, 버프 스킬 그리고 소비 아이템을 사용할 수 있다. 각 스킬과 아이템에 대한 명세는 다음과 같다.
- 이동 스킬
- 대시
- 사용 시 $\text{dash} = 5,ドル $y$축 속도는 0ドル$이 된다.
- 에어 점프
- 사용 시 플레이어의 $y$축 속도가 $\text{jump}$가 된다.
- 퀵 드롭
- 사용 시 플레이어는 퀵 드롭 상태가 되며, $y$축 속도가 $-\text{maxdrop}$가 된다.
- 퀵 드롭 상태에서 대시, 수평 대시 공격, 우상향 대시 공격, 소비 아이템을 사용하면 그 즉시 퀵 드롭 상태는 해제된다.
- 공격 스킬
- 회전 공격
- 사용 시 플레이어는 회전 상태가 된다.
- 회전 상태에서 $y$좌표가 0ドル$이면 $y$축 속도가 현재 $y$축 속도의 $-1$배가 되며 회전 상태는 해제된다.
- 회전 상태에서 다른 이동 스킬이나 공격 스킬, 버프 스킬 및 소비 아이템을 사용하면 그 즉시 회전 상태는 해제된다.
- 해당 스킬은 게임이 시작되고 착지할 때까지 단 한 번만 사용할 수 있다.
- 수평 대시 공격
- 사용 시 $\text{dash} = 5,ドル $y$축 속도는 0ドル$이 된다.
- 우상향 대시 공격
- 사용 시 $\text{dash} = 5$가 되며 플레이어의 $y$축 속도는 $x$축 속도에 의존하는 상태가 된다.
- $\text{dash}$가 0ドル$이 되는 순간 $y$축 속도는 $x$축 속도에 의존하지 않는다.
- 버프 스킬
- 가속
- 사용 시 플레이어는 가속 상태가 된다.
- 지속 시간은 600ドル$프레임이며 사용 시점으로부터 600ドル$프레임이 지난 직후 가속 상태는 해제된다.
- 가속 상태 중에 중복하여 사용하면 마지막으로 사용한 프레임으로부터 600ドル$프레임 이후에 해제된다.
- 중력 약화
- 사용 시 플레이어는 중력 약화 상태가 된다.
- 지속 시간은 600ドル$프레임이며 사용 시점으로부터 600ドル$프레임이 지난 직후 중력 약화 상태는 해제된다.
- 중력 약화 상태 중에 중복하여 사용하면 마지막으로 사용한 프레임으로부터 600ドル$프레임 이후에 해제된다.
- 소비 아이템
- 폭탄
- 사용 시 $y$축 속도는 0ドル$이 되며 사용 모션이 시작된다.
- 사용 모션의 지속 시간은 100ドル$프레임이다.
- 쉴드
- 사용 시 $y$축 속도는 0ドル$이 되며 사용 모션이 시작된다.
- 사용 모션의 지속 시간은 30ドル$프레임이다.
- 포션
- 사용 시 $y$축 속도는 0ドル$이 되며 사용 모션이 시작된다.
- 사용 모션의 지속 시간은 150ドル$프레임이다.
미니게임은 프레임마다 아래 과정들을 순서대로 실행한다.
- 착지 상태인지 판단한다. 착지 상태란 플레이어의 $y$좌표가 0ドル$이면서 회전 상태가 아닌 상태이다. 착지 상태라면 게임을 종료한다.
- 플레이어의 일부 능력치를 변경한다. 해당 단계에서 변경되는 능력치는 다음과 같다.
- 해당 프레임에서 $y$좌표가 0ドル$이면서 회전 상태라면 해당 단계에서 $y$축 속도가 변경되고 회전 상태를 해제한다.
- 해당 프레임에서 $\text{dash}$가 1ドル$ 감소해야 한다면 감소한다.
- 해당 프레임에서 버프와 아이템 사용 모션을 해제해야 한다면 해제한다.
- 입력된 커맨드를 적용한다. 만약에 현재 프레임에서 사용할 수 없는 스킬이나 아이템에 대한 커맨드라면 적용하지 않고 무시한다.
- $x$축 방향으로 이동한다. 플레이어의 $x$축 속도만큼 $x$좌표가 증가하며 $x$축 속도 $v_x$는 아래와 같이 계산한다.
$$v_x = (1+\text{dash}+5 \cdot \text{quick}) \cdot (1+\text{accel}) \cdot \text{base}_x \cdot (1-\text{motion})$$
- $y$축 방향으로 이동한다. 플레이어의 $y$축 속도만큼 $y$좌표가 증가하며 만약에 $y$좌표가 0ドル$이하가 된다면 $y$좌표는 0ドル$이 된다. 이때, $y$축 속도가 $x$축 속도에 의존하는 상태라면 이전 단계에서 계산한 $x$축 속도로 $y$축 속도를 변경해 준 뒤 이동한다.
- 해당 프레임에서 중력의 영향을 받는다면 중력을 적용한다. 현재 중력의 크기를 $g,ドル 변화 전 $y$축 속도를 $v_y$라고 하면 변화 후 $y$축 속도 $v'_y = \max(-\text{maxdrop}, v_y-g)$이다. 현재 중력의 크기 $g$는 아래와 같이 계산한다.
$$g = \left\lfloor \frac{\text{base}_g}{1+\text{weak}} \right\rfloor$$
플레이어는 처음에 $(0, \text{init}_y)$에서 $y$축 속도는 $\text{jump}$로 시작한다. 플레이어가 착지한 위치가 $(X, 0)$이라면 멀리뛰기 기록은 $X$가 된다.