Peilonrayz / dice_stats

Dice statistics made simple.
MIT License
3 stars 1 forks source link

How to roll a variable number of dice that depend on another roll #4

Open sponsfreixes opened 4 years ago

sponsfreixes commented 4 years ago

I failed to figure out how to replicate the following situation:

  1. Roll 1d6
  2. The result is the number of d6s that you roll next.

Related to that, I was wondering if the construct:

d6 = Dice.from_dice(6)
result = d6 * d6

Would be a good way to represent that operation.

Peilonrayz commented 4 years ago

I'm not sure I would want that as an operation of d6 * d6. I can imagine other people wanting d6 * d6 to mean something else. If this is really needed then it can become a method.


Currently the methods that I can think of doing this don't seem correct. I'll look into this further.

Peilonrayz commented 4 years ago

Ok, I've found the problem and found a fix. I'll publish the fix tomorrow as I want to fix #2 at the same time. Currently, as I'm using @, the code won't work on your system. However if you replace 1*d6 @ c with (1 * d6).as_total_chance(c) the list comprehension should work. I have pushed the code to git so that you can verify the below.

from dice_stats import Dice
from fractions import Fraction

d6 = Dice.from_dice(6)

# Apply functions - brute force
d6_a = d6.apply_functions({
    (1,): lambda d: 1*d6 @ d,
    (2,): lambda d: 2*d6 @ d,
    (3,): lambda d: 3*d6 @ d,
    (4,): lambda d: 4*d6 @ d,
    (5,): lambda d: 5*d6 @ d,
    (6,): lambda d: 6*d6 @ d,
})

# Apply functions - semi-automatic
d6_b = d6.apply_functions({
    (i,): (lambda i: lambda d: i*d6 @ d)(i)
    for i in range(1, 7)
})

# List comprehension - manual
c = Fraction(1, 6)
d6_c = Dice.sum([
    1*d6 @ c,
    2*d6 @ c,
    3*d6 @ c,
    4*d6 @ c,
    5*d6 @ c,
    6*d6 @ c,
])

# List comprehension - automatic
d6_d = Dice.sum(v*d6 @ c for v, c in d6.items())

print(d6_a == d6_b == d6_c == d6_d)

From the looks of it the best way is to use the comprehension interface.

If you don't like any of these approaches are there any other ways you think you may want to implement this?

sponsfreixes commented 4 years ago

Definitely the automatic list comprehension is my favorite as it's not hard-coded.

I'm not sure about how intuitive it will be to users that they can use this combination of sum and @. If it ends not being encapsulated inside a method (which is totally fine), I think it's worth to at least put an example on the tutorial to increase awareness.

Peilonrayz commented 4 years ago

I have released 1.1.0 and the above code passes in it. Please note that there are breaking changes around apply_functions and apply_dice, and so @ usage is now required, please read #2 for more info.