feat: implement run-decision algorithm in gb_decide_run (#18)
All checks were successful
Build Docker Image / build (pull_request) Successful in 1m19s

Replace placeholder formula with tier-based algorithm modeled after
tag_from_second and tag_from_third. Uses self.running + aggression_mod
(abs deviation from neutral) for adjusted_running, then brackets into
three min_safe tiers (4/6/8), with a ±2 adjustment for 2-out and 0-out
situations respectively.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-03-07 17:34:53 -06:00
parent a1b0e676c2
commit 6c4ff3bd27
2 changed files with 786 additions and 405 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,42 +7,60 @@ from in_game.managerai_responses import JumpResponse
def test_create_ai(session: Session):
all_ai = session.exec(select(ManagerAi)).all()
assert len(all_ai) == 3
assert ManagerAi.create_ai(session) == True
all_ai = session.exec(select(ManagerAi)).all()
assert len(all_ai) == 3
def test_check_jump(session: Session):
balanced_ai = session.exec(select(ManagerAi).where(ManagerAi.name == 'Balanced')).one()
aggressive_ai = session.exec(select(ManagerAi).where(ManagerAi.name == 'Yolo')).one()
balanced_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Balanced")
).one()
aggressive_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Yolo")
).one()
this_game = session.get(Game, 1)
runner = session.get(Lineup, 5)
this_play = session.get(Play, 2)
this_play = session.get(Play, 2)
this_play.on_first = runner
assert this_play.starting_outs == 1
assert balanced_ai.check_jump(session, this_game, to_base=2) == JumpResponse(ai_note='- SEND **Player 4** to second if they get the jump', min_safe=16)
assert aggressive_ai.check_jump(session, this_game, to_base=2) == JumpResponse(ai_note='- SEND **Player 4** to second if they get the jump', min_safe=13, run_if_auto_jump=True)
assert balanced_ai.check_jump(session, this_game, to_base=2) == JumpResponse(
ai_note="- SEND **Player 4** to second if they get the jump", min_safe=16
)
assert aggressive_ai.check_jump(session, this_game, to_base=2) == JumpResponse(
ai_note="- SEND **Player 4** to second if they get the jump",
min_safe=13,
run_if_auto_jump=True,
)
this_play.on_third = runner
assert balanced_ai.check_jump(session, this_game, to_base=4) == JumpResponse(min_safe=8)
assert aggressive_ai.check_jump(session, this_game, to_base=4) == JumpResponse(min_safe=5)
assert balanced_ai.check_jump(session, this_game, to_base=4) == JumpResponse(
min_safe=8
)
assert aggressive_ai.check_jump(session, this_game, to_base=4) == JumpResponse(
min_safe=5
)
def test_tag_from_second(session: Session):
balanced_ai = session.exec(select(ManagerAi).where(ManagerAi.name == 'Balanced')).one()
aggressive_ai = session.exec(select(ManagerAi).where(ManagerAi.name == 'Yolo')).one()
balanced_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Balanced")
).one()
aggressive_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Yolo")
).one()
this_game = session.get(Game, 1)
runner = session.get(Lineup, 5)
this_play = session.get(Play, 2)
this_play = session.get(Play, 2)
this_play.on_second = runner
assert this_play.starting_outs == 1
@ -53,4 +71,30 @@ def test_tag_from_second(session: Session):
assert balanced_resp.min_safe == 5
assert aggressive_resp.min_safe == 2
def test_gb_decide_run(session: Session):
"""
Verifies that gb_decide_run returns a min_safe threshold based on self.running
plus an aggression modifier, with outs adjustment applied.
With 1 out (no outs adjustment):
- Balanced (running=5, behind_aggression=5): adjusted_running=5 tier 5 min_safe=6
- Yolo (running=10, behind_aggression=10): adjusted_running=15 tier 8 min_safe=4
"""
balanced_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Balanced")
).one()
aggressive_ai = session.exec(
select(ManagerAi).where(ManagerAi.name == "Yolo")
).one()
this_game = session.get(Game, 1)
this_play = session.get(Play, 2)
assert this_play.starting_outs == 1
balanced_resp = balanced_ai.gb_decide_run(session, this_game)
aggressive_resp = aggressive_ai.gb_decide_run(session, this_game)
assert balanced_resp.min_safe == 6
assert aggressive_resp.min_safe == 4