strat-gameplay-webapp/frontend-sba/constants/outcomes.ts
Cal Corum af598b3dee CLAUDE: Remove hit location requirement from lineout outcomes
Lineouts are simple outs with no runner advancement logic - the backend
doesn't use hit_location for them (unlike flyouts for sac flies or
groundballs for double plays). Updated OUTCOMES_REQUIRING_HIT_LOCATION
to exclude lineout and added documentation explaining the rationale.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 12:14:50 -06:00

118 lines
2.7 KiB
TypeScript

/**
* Outcome Constants
*
* Centralized definitions for play outcomes used across the UI.
* These match the backend PlayOutcome enum values.
*/
import type { PlayOutcome } from '~/types/game'
/**
* Outcome categories for UI display and selection
* Grouped by common baseball categories for user-friendly selection
*/
export const OUTCOME_CATEGORIES = [
{
name: 'Outs',
outcomes: [
'strikeout',
'groundball_a',
'groundball_b',
'groundball_c',
'flyout_a',
'flyout_b',
'flyout_c',
'lineout',
'popout',
] as const satisfies readonly PlayOutcome[],
},
{
name: 'Hits',
outcomes: [
'single_1',
'single_2',
'single_uncapped',
'double_2',
'double_3',
'double_uncapped',
'triple',
'homerun',
] as const satisfies readonly PlayOutcome[],
},
{
name: 'Walks / HBP',
outcomes: [
'walk',
'intentional_walk',
'hbp',
] as const satisfies readonly PlayOutcome[],
},
{
name: 'Special',
outcomes: [
'error',
'x_check',
] as const satisfies readonly PlayOutcome[],
},
{
name: 'Interrupts',
outcomes: [
'stolen_base',
'caught_stealing',
'wild_pitch',
'passed_ball',
'balk',
'pick_off',
] as const satisfies readonly PlayOutcome[],
},
] as const
/**
* Outcomes that require a hit location to be specified
* These outcomes involve defensive plays where location matters for game logic:
* - Groundballs: determines double play eligibility
* - Flyouts: determines sac fly advancement opportunities
* - Uncapped hits/errors: determines runner advancement
*
* Note: lineout and popout are NOT included because they are simple outs
* with no runner advancement logic - the backend doesn't use hit_location for them
*/
export const OUTCOMES_REQUIRING_HIT_LOCATION = [
'groundball_a',
'groundball_b',
'groundball_c',
'flyout_a',
'flyout_b',
'flyout_c',
'single_uncapped',
'double_uncapped',
'error',
] as const satisfies readonly PlayOutcome[]
/**
* Outcomes that only allow infield hit locations (no outfield)
* Groundballs by definition stay in the infield
*/
export const INFIELD_ONLY_OUTCOMES = [
'groundball_a',
'groundball_b',
'groundball_c',
] as const satisfies readonly PlayOutcome[]
/**
* Outcomes that only allow outfield hit locations (no infield)
* Flyballs by definition go to the outfield
*/
export const OUTFIELD_ONLY_OUTCOMES = [
'flyout_a',
'flyout_b',
'flyout_c',
] as const satisfies readonly PlayOutcome[]
/**
* Hit location options
*/
export const HIT_LOCATIONS = {
infield: ['P', 'C', '1B', '2B', '3B', 'SS'] as const,
outfield: ['LF', 'CF', 'RF'] as const,
} as const