Add game core logic, CSV storage, tests and ADR-0001 (MIL-002)
Task: MIL-002#1 Task: MIL-002#2 Task: MIL-002#3 Task: MIL-002#4 Task: MIL-002#5
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
"""Pure domain logic of the U.S. States Game: states, answers and misses.
|
||||
|
||||
@file states.py
|
||||
@brief State model, answer matching and the list of missing states.
|
||||
|
||||
Nothing here reads files or touches the screen, so the rules run under test
|
||||
with no display and no file system.
|
||||
"""
|
||||
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class State:
|
||||
"""A U.S. state and the position of its name on the map.
|
||||
|
||||
@param name Name of the state, for example "Ohio".
|
||||
@param x Horizontal map coordinate of the state.
|
||||
@param y Vertical map coordinate of the state.
|
||||
"""
|
||||
|
||||
name: str
|
||||
x: int
|
||||
y: int
|
||||
|
||||
|
||||
def find_state(answer: str, states: Iterable[State]) -> State | None:
|
||||
"""Find the state the player named, ignoring case and surrounding spaces.
|
||||
|
||||
@param answer Text the player typed.
|
||||
@param states The states to search.
|
||||
@return The matching state, or None if the answer matches no state.
|
||||
"""
|
||||
wanted = answer.strip().casefold()
|
||||
if not wanted:
|
||||
return None
|
||||
for state in states:
|
||||
if state.name.casefold() == wanted:
|
||||
return state
|
||||
return None
|
||||
|
||||
|
||||
def get_missing_states(
|
||||
states: Iterable[State], guessed_states: Iterable[str]
|
||||
) -> list[str]:
|
||||
"""List the names of the states the player did not guess.
|
||||
|
||||
@param states All states of the game, in the order to report them.
|
||||
@param guessed_states Names of the states the player guessed.
|
||||
@return Names of the states not guessed, in the order of `states`.
|
||||
"""
|
||||
guessed = set(guessed_states)
|
||||
return [state.name for state in states if state.name not in guessed]
|
||||
Reference in New Issue
Block a user