game/prompt/73_prevent_first_turn_defen...

6.7 KiB

73. Prevent Pre-emptive Defense on First Turn

1. 문제 (Problem)

  • 현재 시스템은 _generateEnemyIntent가 호출되면, 적의 행동이 Defend일 경우 즉시 방어도를 증가시킵니다(Pre-emptive Defense).
  • 스테이지 시작(_prepareNextStage) 시에도 _generateEnemyIntent를 호출하므로, 첫 턴부터 적이 방어도를 가지고 시작하는 경우가 발생합니다.
  • 사용자는 첫 턴에는 적의 방어도가 적용되지 않은 상태로 플레이어가 선공할 수 있기를 원합니다.

2. 해결 방안 (Solution)

  • _generateEnemyIntent 메서드에 applyImmediateEffect (기본값 true) 파라미터를 추가합니다.
  • _prepareNextStage에서 첫 Intent를 생성할 때는 applyImmediateEffect: false로 호출하여, 의도(Intent)는 생성하되 방어도 증가 효과는 적용하지 않도록 합니다.
  • 단, 이렇게 하면 적이 "방어하겠다"고 표시만 하고 실제로는 방어도가 0인 상태가 됩니다.
    • 만약 "첫 턴에는 적이 아예 행동하지 않음"을 원한다면 Intent 자체를 생성하지 않아야 하지만, 로그라이크 특성상 "적의 다음 행동"은 보여줘야 합니다.
    • 따라서 "첫 턴의 방어 Intent는 방어도를 올리지 않는다" 보다는 "첫 턴 Intent 생성 시에는 방어 행동을 제외하거나, 방어도가 턴 시작 시(적 턴)에 올라가도록" 해야 할 수도 있습니다.
    • 하지만 사용자의 요청은 "첫 턴에 방어도가 적용되는 중"인 것을 막는 것이므로, 첫 Intent 생성 시에는 방어도 적용을 스킵하는 것이 가장 직관적입니다.

3. 수정 계획

  1. _generateEnemyIntent({bool applyDefense = true}) 로 시그니처 변경.
  2. _prepareNextStage에서는 applyDefense: false로 호출.
  3. 나머지 _enemyTurn 등에서는 applyDefense: true로 호출.

주의: 이렇게 하면 적의 첫 행동이 Defend일 때, UI에는 "Defends for 10"이라고 뜨지만 실제 방어도는 0입니다. 플레이어가 공격하면 0인 상태로 맞습니다. 그리고 적 턴이 되면? 적은 Defend 행동을 했으므로 (이미 했다고 치고) 아무것도 안 하거나, 그때 방어도를 올릴까요? 현재 로직: _enemyTurn에서 Defend면 "Enemy maintains defensive stance" 로그만 띄우고 끝납니다. 즉, 첫 턴에 방어도를 안 올리면, 적은 첫 턴에 아무것도 안 하는 바보가 됩니다.

재해석: "첫 턴에는 무조건 플레이어가 행동하는 걸로 해야 해" -> "적은 첫 턴에 방어 행동(선제 방어)을 하지 말아야 한다." 즉, 첫 턴 Intent 생성 시에는 Defend가 나오지 않도록 강제하거나, 첫 턴에는 Intent를 생성하되 방어 효과는 적 턴 시작 시점에 발동하도록 유예해야 합니다.

하지만 Slay the Spire 같은 게임을 보면, 첫 턴에 적이 방어 자세를 취할 수도 있습니다. 사용자가 원하는 건 **"전투 시작하자마자 적이 단단해져 있는 게 싫다"**는 것입니다.

결론: _prepareNextStage에서 Intent를 생성할 때, 방어 행동이 당첨되더라도 방어도를 즉시 적용하지 않고, 적 턴이 시작될 때 적용하도록 로직을 분산시켜야 합니다. 하지만 현재 구조상 Intent는 "이미 적용됨"을 가정합니다.

가장 깔끔한 방법: 첫 턴(_prepareNextStage)에서는 _generateEnemyIntent를 호출하지 않습니다. 대신 null로 두거나, "대기(Wait/Stunned)" 상태로 둡니다. 하지만 적이 뭘 할지 모르면 전략을 짤 수 없습니다.

사용자의 의도: "첫 턴에는 무조건 플레이어가 행동" -> 플레이어 선공 보장. 현재도 플레이어 선공입니다. 단지 적이 "방어 버프"를 두르고 있을 뿐.

수정 제안: _prepareNextStage에서 생성하는 첫 Intent는 **applyDefense: false**로 생성합니다. 그리고 _enemyTurn에서 **"만약 현재 Intent가 Defend이고 방어도가 아직 적용 안 됐다면(혹은 첫 턴이라면), 이때 방어도를 적용한다"**는 로직을 추가해야 합니다.

하지만 코드가 복잡해집니다. 더 쉬운 방법: 첫 턴 Intent 생성 시, 아예 Defend 선택지를 배제합니다. (첫 턴은 무조건 공격만 하도록). 이게 밸런스상으론 더 공격적일 수 있지만, "방어도가 적용되는 문제"는 확실히 해결됩니다.

사용자 멘트 재확인: "스테이지 첫번째 enemyIntent 생성 시... isFirst 플래그를 추가해서 첫턴에는 무조건 플레이어가 행동하는걸로 해야해." -> 이 말은 **"적이 아무런 선제 액션(방어)도 취하지 않은 상태여야 한다"**는 뜻입니다.

전략: BattleProviderisFirstTurn 플래그를 추가하는 것이 아니라, _generateEnemyIntent 메서드에 isFirstTurn 파라미터를 추가합니다. 그리고 isFirstTurntrue이면, Defend 확률을 0으로 만들거나, Defend가 선택되어도 방어도를 적용하지 않고 넘깁니다. 후자가 낫습니다. UI에는 "방어 예정"이라고 뜨고, 적 턴이 되었을 때 방어도가 올라가는 것이 가장 자연스럽습니다.

구현:

  1. _generateEnemyIntent({bool applyImmediate = true})
  2. _prepareNextStage -> _generateEnemyIntent(applyImmediate: false)
  3. _enemyTurn -> 만약 currentEnemyIntentDefend인데 방어도가 0이라면? (이미 깎였을 수도 있음). -> Flag 필요: bool _isPreemptiveDefenseApplied 같은 변수가 필요할 수도 있습니다.

아니면 단순히 _prepareNextStage에서는 Defend가 안 나오게 막는 것이 제일 깔끔합니다. (첫 턴은 공격만 함). 하지만 사용자가 "첫턴에는 무조건 플레이어가 행동"이라고 했지 "적은 공격만 해"라고 하진 않았습니다.

가장 적절한 구현: _prepareNextStage에서 Intent 생성 시 applyImmediate: false로 설정. 그리고 _enemyTurn 로직을 수정하여, "Defend Intent인 경우, 기존에는 '이미 적용됨'이라 넘어갔지만, 이제는 '적용 안 됐으면 지금 적용'하도록" 변경.

어떻게 '적용 안 됐음'을 알까요? EnemyIntent 클래스에 bool applied 필드를 추가하면 됩니다!

계획:

  1. EnemyIntent 클래스에 bool isApplied 필드 추가 (기본 false).
  2. _generateEnemyIntent에서 applyImmediate가 true면 방어도 올리고 isApplied = true.
  3. _prepareNextStage에서는 applyImmediate: false로 호출 -> isApplied = false.
  4. _enemyTurn에서 IntentDefend일 때, !isApplied라면 방어도 적용하고 이펙트 띄움.

이 방식이 완벽합니다.