Skip to content

Commit

Permalink
Add roll list and probs
Browse files Browse the repository at this point in the history
  • Loading branch information
abelsiqueira committed Aug 14, 2020
1 parent 31afec6 commit f3ccf8a
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 2 deletions.
23 changes: 22 additions & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,30 @@ UnicodePlots.barplot(results, frequency)

## Statistics

You can compute some statistical information of a dice or roll with the function [`mean`], [`median`], [`std`] and [`var`]
You can compute some statistical information of a dice or roll with the function [`mean`](@ref), [`median`](@ref), [`std`](@ref) and [`var`](@ref)

```@example ex1
r = drop(3d4)
mean(r), median(r), std(r), var(r)
```

## Comparisons and Probabilities

Using comparison operators on a roll will return (a compact representation of) all rolls that
satisfy that comparison. For instance,

```@example ex1
r = drop(3d4)
collect(r > 7)
```

```@example ex1
collect(r == 7)
```

Using [`prob`](@ref) one can compute the probability of that situation happening.

```@example ex1
r = drop(4d6)
prob(r > 14)
```
4 changes: 3 additions & 1 deletion src/roll.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ end
include("diceroll.jl")
include("compositeroll.jl")
include("droproll.jl")
include("keeproll.jl")
include("keeproll.jl")

include("rolllist.jl")
75 changes: 75 additions & 0 deletions src/rolllist.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
export CompactedComparison, rolllist, prob
import Base.<, Base.>, Base.≤, Base.≥, Base.==

"""
rolllist(d :: Dice; generator=false)
rolllist(r :: Roll; generator=false)
Show all possible rolllist of dice `d` or roll `r`. For `DiceRoll`s this is a list of all dice results.
For `CompositeRoll`s and other `Roll`s where its parts are made of `Roll`s.
"""
function rolllist(d :: Dice; generator=false)
gen = [i for i = 1:d.sides]
if generator
return gen
else
return collect(gen)
end
end

function rolllist(r :: Roll; generator=false)
gen = Iterators.product(rolllist.(r.parts, generator=generator)...)
if generator
return gen
else
return [vcat(x...) for x in gen][:]
end
end

"""
CompactedComparison(r, op, x)
Stores a comparison between a roll r and a value x. Use `collect` to collect all the roll values
that satisfy that comparison.
"""
mutable struct CompactedComparison{R}
r :: Roll
op
x
end

function CompactedComparison(r :: T, op, x :: Real) where T <: Roll
CompactedComparison{T}(r, op, x)
end

<(r :: Roll, x :: Real) = CompactedComparison(r, <, x)
(r :: Roll, x :: Real) = CompactedComparison(r, , x)
>(r :: Roll, x :: Real) = CompactedComparison(r, >, x)
(r :: Roll, x :: Real) = CompactedComparison(r, , x)
<(x :: Real, r :: Roll) = CompactedComparison(r, >, x)
(x :: Real, r :: Roll) = CompactedComparison(r, , x)
>(x :: Real, r :: Roll) = CompactedComparison(r, <, x)
(x :: Real, r :: Roll) = CompactedComparison(r, , x)
==(r :: Roll, x :: Real) = CompactedComparison(r, ==, x)
==(x :: Real, r :: Roll) = CompactedComparison(r, ==, x)

function Base.show(io :: IO, tr :: CompactedComparison)
print(io, "Compact ($(tr.r)) $(tr.op) $(tr.x) - Use collect to the list")
end

function Base.collect(tr :: CompactedComparison)
rolls = rolllist(tr.r)
I = findall(tr.op.(tr.r.activator.(rolls), tr.x))
rolls[I]
end

"""
prob(comparison)
Compute the probability of the given comparison, e.g., `prod(2d4 > 3)`.
"""
function prob(tr :: CompactedComparison)
v, f = histogram(tr.r)
I = findall(tr.op.(v, tr.x))
sum(f[I]) / sum(f)
end
64 changes: 64 additions & 0 deletions test/rolllist.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@testset "Roll list" begin
@test rolllist(1d4) == [[i] for i = 1:4]
@test rolllist(2d4) == [[i, j] for i = 1:4, j = 1:4][:]
@test rolllist(drop(2d4)) == [[i, j] for i = 1:4, j = 1:4][:]
@test rolllist((1d4 - 1) * (1d6 - 1)) == [[i, j] for i = 1:4, j = 1:6][:]
end

@testset "Comparisons" begin
r = 1d4
@test collect(r > 0) == collect(0 < r) == [[i] for i = 1:4]
@test collect(r > 2) == collect(2 < r) == [[i] for i = 3:4]
@test collect(r > 4) == collect(4 < r) == []
@test collect(r 2) == collect(2 r) == [[i] for i = 2:4]
@test collect(r < 3) == collect(3 > r) == [[i] for i = 1:2]
@test collect(r 3) == collect(3 r) == [[i] for i = 1:3]
@test collect(r == 3) == collect(3 == r) == [[3]]

r = 2d4
@test collect(r > 0) == collect(0 < r) == [[i, j] for i = 1:4, j = 1:4][:]
@test collect(r > 4) == collect(4 < r) == [[i, j] for i = 1:4, j = 1:4 if i + j > 4]
@test collect(r > 8) == collect(8 < r) == []
@test collect(r 4) == collect(4 r) == [[i, j] for i = 1:4, j = 1:4 if i + j 4]
@test collect(r < 5) == collect(5 > r) == [[i, j] for i = 1:4, j = 1:4 if i + j < 5]
@test collect(r 5) == collect(5 r) == [[i, j] for i = 1:4, j = 1:4 if i + j 5]
@test collect(r == 4) == collect(4 == r) == [[3, 1], [2, 2], [1, 3]]

r = drop(2d4)
@test collect(r > 0) == collect(0 < r) == [[i, j] for i = 1:4, j = 1:4][:]
@test collect(r > 2) == collect(2 < r) == [[i, j] for i = 1:4, j = 1:4 if max(i, j) > 2]
@test collect(r > 4) == collect(4 < r) == []
@test collect(r 2) == collect(2 r) == [[i, j] for i = 1:4, j = 1:4 if max(i, j) 2]
@test collect(r < 3) == collect(3 > r) == [[i, j] for i = 1:4, j = 1:4 if max(i, j) < 3]
@test collect(r 3) == collect(3 r) == [[i, j] for i = 1:4, j = 1:4 if max(i, j) 3]
@test collect(r == 3) == collect(3 == r) == [[3, 1], [3, 2], [1, 3], [2, 3], [3, 3]]
end

@testset "Probabilities" begin
r = 1d4
@test prob(r > 0) == prob(0 < r) == 1
@test prob(r > 2) == prob(2 < r) == 0.5
@test prob(r > 4) == prob(4 < r) == 0
@test prob(r 2) == prob(2 r) == 0.75
@test prob(r < 3) == prob(3 > r) == 0.5
@test prob(r 3) == prob(3 r) == 0.75
@test prob(r == 3) == prob(3 == r) == 0.25

r = 2d4
@test prob(r > 0) == prob(0 < r) == 1
@test prob(r > 4) == prob(4 < r) == 0.625
@test prob(r > 8) == prob(8 < r) == 0
@test prob(r 4) == prob(4 r) == 0.8125
@test prob(r < 5) == prob(5 > r) == 0.375
@test prob(r 5) == prob(5 r) == 0.625
@test prob(r == 4) == prob(4 == r) == 0.1875

r = drop(2d4)
@test prob(r > 0) == prob(0 < r) == 1
@test prob(r > 2) == prob(2 < r) == 0.75
@test prob(r > 4) == prob(4 < r) == 0
@test prob(r 2) == prob(2 r) == 0.9375
@test prob(r < 3) == prob(3 > r) == 0.25
@test prob(r 3) == prob(3 r) == 0.5625
@test prob(r == 3) == prob(3 == r) == 0.3125
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ include("error.jl")
include("operations.jl")
include("show.jl")
include("histogram.jl")
include("rolllist.jl")
include("statistics.jl")

0 comments on commit f3ccf8a

Please sign in to comment.