Fix trade-in-jail bug: jail handler must not roll during active trade
Added guard in jail turn handler to skip rolling when in_trade is True. The roll happens later when '-- Command:' arrives after trade completes. Added 5 regression tests for the exact failing sequence.
This commit is contained in:
parent
d31a09e754
commit
8bbadba7d9
3 changed files with 79 additions and 2 deletions
Binary file not shown.
|
|
@ -250,7 +250,8 @@ class PlayerBot:
|
|||
self.jail_turns = 2
|
||||
else:
|
||||
self.jail_turns = 1
|
||||
# Try rolling doubles
|
||||
# Try rolling doubles — but not if we're in a trade
|
||||
if not self.in_trade:
|
||||
self.say_delayed("roll")
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -306,6 +306,82 @@ class TestTrading(unittest.TestCase):
|
|||
self.assertIn("roll", msgs)
|
||||
|
||||
|
||||
class TestTradeInJail(unittest.TestCase):
|
||||
"""Regression tests for trade-while-in-jail bug.
|
||||
|
||||
Sequence that caused the hang:
|
||||
1. Checkpoint "charlie (3) (cash $985) on JAIL" → trade initiated
|
||||
2. "(This is your 2nd turn in JAIL)" → roll queued (ignoring in_trade)
|
||||
3. ".trade" sent, then ".roll" sent into trade prompt → hang
|
||||
"""
|
||||
|
||||
def _make_bot(self, nick="charlie"):
|
||||
bot = FakePlayerBot(nick, ["alice", "bob", "charlie"], 2)
|
||||
bot.setup_phase = False
|
||||
bot.game_started = True
|
||||
bot.turns_played = 10 # past trade threshold
|
||||
return bot
|
||||
|
||||
def test_jail_handler_no_roll_during_trade(self):
|
||||
"""Jail turn handler must not queue a roll when in_trade is True."""
|
||||
bot = self._make_bot()
|
||||
bot.current_player = "charlie"
|
||||
bot.in_trade = True
|
||||
bot.in_jail = True
|
||||
msgs = bot.feed("(This is your 2nd turn in JAIL)")
|
||||
self.assertNotIn("roll", msgs,
|
||||
"Should not roll while in_trade is True")
|
||||
|
||||
def test_trade_then_jail_turn_sequence(self):
|
||||
"""Simulate the exact sequence: checkpoint initiates trade, then jail prompt arrives."""
|
||||
bot = self._make_bot()
|
||||
# Force trade to trigger (patch random)
|
||||
with patch("random.random", return_value=0.01): # < 0.10 → triggers trade
|
||||
msgs = bot.feed("charlie (3) (cash $985) on JAIL")
|
||||
self.assertTrue(bot.in_trade, "Trade should be initiated")
|
||||
self.assertIn("trade", msgs, "Should send .trade")
|
||||
self.assertNotIn("roll", msgs, "Should not also roll")
|
||||
|
||||
# Now jail turn prompt arrives
|
||||
msgs = bot.feed("(This is your 2nd turn in JAIL)")
|
||||
self.assertNotIn("roll", msgs,
|
||||
"Jail handler must not roll during active trade")
|
||||
self.assertTrue(bot.in_trade, "Trade should still be active")
|
||||
|
||||
def test_trade_which_player_prompt(self):
|
||||
"""Bot should pick a trade partner when asked."""
|
||||
bot = self._make_bot()
|
||||
bot.current_player = "charlie"
|
||||
bot.in_trade = True
|
||||
msgs = bot.feed("Which player do you wish to trade with?")
|
||||
self.assertTrue(len(msgs) > 0, "Should respond to trade partner prompt")
|
||||
self.assertNotIn("roll", msgs)
|
||||
# Should pick one of the other players
|
||||
self.assertTrue(
|
||||
msgs[0] in ["alice", "bob"],
|
||||
f"Expected a player name, got: {msgs[0]}"
|
||||
)
|
||||
|
||||
def test_no_trade_in_jail_still_rolls(self):
|
||||
"""When NOT in a trade, jail handler should still queue a roll."""
|
||||
bot = self._make_bot()
|
||||
bot.current_player = "charlie"
|
||||
bot.in_trade = False
|
||||
bot.in_jail = True
|
||||
msgs = bot.feed("(This is your 2nd turn in JAIL)")
|
||||
self.assertIn("roll", msgs, "Should roll when not trading")
|
||||
|
||||
def test_command_prompt_after_trade_allows_roll(self):
|
||||
"""After trade ends (-- Command:), bot should roll normally."""
|
||||
bot = self._make_bot()
|
||||
bot.current_player = "charlie"
|
||||
bot.in_trade = True
|
||||
bot.rolled_this_turn = False
|
||||
msgs = bot.feed("-- Command:")
|
||||
self.assertFalse(bot.in_trade)
|
||||
self.assertIn("roll", msgs)
|
||||
|
||||
|
||||
class TestValidInputs(unittest.TestCase):
|
||||
def test_picks_first_option(self):
|
||||
bot = FakePlayerBot("alice", ["alice", "bob"], 0)
|
||||
|
|
|
|||
Loading…
Reference in a new issue