Pārlūkot izejas kodu

Add sanity checking for success/fail conditions

Ryan C. Thompson 6 gadi atpakaļ
vecāks
revīzija
6355ff3134
2 mainītis faili ar 9 papildinājumiem un 8 dzēšanām
  1. 0 7
      README.mkdn
  2. 9 1
      roll.py

+ 0 - 7
README.mkdn

@@ -124,10 +124,3 @@ up with the total. This also lets you figure out whether you rolled a
 natural 20 or natural 1 on the die for critical hits and misses, and
 if your damage roll involves multiple different kinds of damage, it
 lets you figure out how much of each damage type was dealt.
-
-## Known Issues
-
-* There is no sanity checking for dice roll effects that will never
-  take effect, such as exploding a d6 on 7 (i.e. `d6!=7)
-* Error messages are pretty much just reported as is, with no attempt
-  to explain or contextualize them.

+ 9 - 1
roll.py

@@ -456,6 +456,8 @@ def roll_dice(roll_desc: Dict) -> DiceRolled:
         reroll_type: str = roll_desc['reroll_type']
         reroll_limit = 1 if reroll_type == 'r' else None
         reroll_desc: Dict = roll_desc['reroll_desc']
+        # TODO: sanity check the reroll comparator. Make sure it
+        # doesn't pass all values or fail all values.
         reroll_comparator = Comparator(
             operator = reroll_desc['comparator'],
             value = reroll_desc['target'],
@@ -514,6 +516,9 @@ def roll_dice(roll_desc: Dict) -> DiceRolled:
             operator = success_desc['comparator'],
             value = success_desc['target'],
         )
+        # Sanity check: make sure the success test can be met
+        if not any(map(success_test, range(1, die_face +1))):
+            raise ValueError(f"Test {str(success_test)!r} can never succeed for d{die_face}")
         success_count = sum(success_test(x) for x in kept_rolls)
         if 'count_failure' in roll_desc:
             failure_desc = roll_desc['count_failure']
@@ -521,7 +526,10 @@ def roll_dice(roll_desc: Dict) -> DiceRolled:
                 operator = failure_desc['comparator'],
                 value = failure_desc['target'],
             )
-            # Make sure the two conditions don't overlap
+            # Sanity check: make sure the failure test can be met
+            if not any(map(failure_test, range(1, die_face +1))):
+                raise ValueError(f"Test {str(failure_test)!r} can never succeed for d{die_face}")
+            # Sanity check: make sure the two conditions don't overlap
             for i in range(1, die_face + 1):
                 if success_test(i) and failure_test(i):
                     raise ValueError(f"Can't use overlapping success and failure conditions: {str(success_test)!r}, {str(failure_test)!r}")