From 3be59a1381217c5485bcfad178404e981f93598a Mon Sep 17 00:00:00 2001 From: Christopher Toth Date: Sun, 26 Jul 2026 18:31:52 -0600 Subject: [PATCH] Fix Dice.roll() ValueError for sides=0, matching ROM's dice() randrange(1, 1) is an empty range, so any Dice with sides == 0 -- including a default-constructed Dice() -- raised ValueError. ROM's dice() (src/db.c) defines size 0 as rolling 0, so a 0-sided roll now returns just the bonus. Negative sides follow ROM's number_range(), which clamps a degenerate range to its low bound (1 per die). Fixes #8 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01HfQ678eD83tiAALqNkct1U --- area_reader/__init__.py | 8 +++++++- test_area_reader.py | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/area_reader/__init__.py b/area_reader/__init__.py index 4b2f3c3..4af9922 100644 --- a/area_reader/__init__.py +++ b/area_reader/__init__.py @@ -761,9 +761,15 @@ def read(cls, reader, **kwargs): return cls(number=number, sides=sides, bonus=bonus, **kwargs) def roll(self): + # ROM's dice() (src/db.c) returns 0 for size 0, and its + # number_range() clamps a degenerate range to the low bound, + # so negative sides roll 1 per die. + if self.sides == 0: + return self.bonus score = 0 + sides = max(self.sides, 1) for roll in range(self.number): - score += random.randrange(1, self.sides + 1) + score += random.randrange(1, sides + 1) score += self.bonus return score diff --git a/test_area_reader.py b/test_area_reader.py index 44b9b31..679394f 100644 --- a/test_area_reader.py +++ b/test_area_reader.py @@ -29,6 +29,16 @@ def test_dice_roll_includes_the_maximum_face(monkeypatch): assert area_reader.Dice(number=2, sides=1, bonus=3).roll() == 5 +def test_dice_roll_zero_sides_contributes_zero(): + assert area_reader.Dice(number=2, sides=0, bonus=0).roll() == 0 + assert area_reader.Dice(number=5, sides=0, bonus=7).roll() == 7 + assert area_reader.Dice().roll() == 0 + + +def test_dice_roll_negative_sides_rolls_one_per_die(): + assert area_reader.Dice(number=3, sides=-4, bonus=2).roll() == 5 + + reset_command = st.sampled_from(["M", "O", "P", "G", "E", "D", "R"]) small_int = st.integers(min_value=0, max_value=9999) rom_source_dir = Path(r"C:\Users\Q\src\Rom24b6\area")