-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.Rmd
196 lines (147 loc) · 5.97 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r, include = FALSE}
library(droll)
set.seed(42)
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# droll <a href='https://curso-r.com/'><img src='man/figures/logo.png' align="right" height="139" /></a>
<!-- badges: start -->
[![CRAN status](https://www.r-pkg.org/badges/version/droll)](https://CRAN.R-project.org/package=droll)
[![R-CMD-check](https://github.com/curso-r/droll/workflows/Check/badge.svg)](https://github.com/curso-r/droll/actions)
[![Codecov test coverage](https://codecov.io/gh/curso-r/droll/branch/main/graph/badge.svg)](https://codecov.io/gh/curso-r/droll?branch=master)
[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental)
<!-- badges: end -->
## Overview
**droll** \\ˈdrōl\\ _adjective_. **1**. having a humorous, whimsical, or odd
quality.
droll is an R package for parsing dice notation, analyzing rolls, calculating
success probabilities, and plotting outcome distributions. It can help
detail-oriented DMs prepare (un)fair encounters in advance or decide on skill
check DCs on the fly. Players might also find it useful for determining the
best course of action when in a tough situation.
It is designed to be a very lightweight (only one required dependency), very
fast (less than 0.4s to get the full distribution of 40d6), and very precise
(symbolic internal representation courtesy of Ryacas)
[anydice](https://anydice.com/) for R.
## Installation
Install the released version of droll from CRAN with:
``` r
install.packages("droll")
```
Or install the development version from GitHub with:
``` r
# install.packages("remotes")
remotes::install_github("curso-r/droll")
```
## Usage
What are you looking for in droll? Are you a level 1 user, a seasoned
level 10 programmer, or a god-like level 20 statistician? Choose your class:
### 🖍️ User
The most basic usage of droll involves simply rolling dice. You can create any
die you want with the `d()` function and then write an expression that involves
that die. Note that, if you want to roll NdX, you should write `N * dX`.
```{r}
# Create some dice
d20 <- d(20)
d6 <- d(6)
d4 <- d(4)
# Roll a skill check while blessed
(d20 + 8) + d4
# Roll for damage!
8 * d6
# Dexterity saving throw with disadvantage
if (min(d20, d20) + 4 < 18) {
print("Full damage!")
} else {
print("Half damage.")
}
```
Nice and easy, right? If you are a DM, you might also want to use two
functions: `check_prob()` and `check_dc()`. They allow you to, respectively,
calculate the probability of passing (or failing) a skill check and find the
necessary DC so a skill check has a given probability of success (or failure).
You don't even need to create the dice you're going to use inside these two!
```{r}
# What's the probability of this player succeeding in a DC 15 skill check?
check_prob(d20 + 8, 15)
# What should the DC be for this player to have a 50% chance of success?
check_dc(d20 + 8, 0.5)
# What's the probability of this player failing in a DC 10 skill check?
check_prob(d20 + 8, 10, success = FALSE)
# What should the DC be for this player to have a 90% chance of failure?
check_dc(d20 + 8, 0.9, success = FALSE)
```
There are no `attack_*()` functions because the mechanics of checks and attacks
is the same, i.e., success means rolling a value higher than or equal to a
certain threshold. These functions can, therefore, be used for attacks too!
### 🗡️ Programmer
If you are already used to R's d/p/q/r notation, you might want to get deeper
insights into the roll distribution. This is why the `droll()`, `proll()`,
`qroll()`, and `rroll()` functions exist! They are, respectively, the density,
the distribution function, the quantile function, and the random generation for
the distribution described by a roll expression.
```{r}
# P[d20 + 8 = 12]
droll(12, d20 + 8)
# P[d20 + 8 <= 12]
proll(12, d20 + 8)
# inf{x: P[d20 + 8 <= x] >= 0.5}
qroll(0.5, d20 + 8)
# Draw 3 simulations from d20 + 8
rroll(3, d20 + 8)
```
Once you know how to use these four functions, you can look for their
`plot_*()` variations. They generate plots (using ggplot2 if it's available)
corresponding to the full distributions of d/p/q and a simple histogram in the
case of `plot_rroll()`.
```{r}
# Density of 8d6
droll_plot(8 * d6)
# Distribution function of 8d6
proll_plot(8 * d6)
# Quantile function of 8d6
qroll_plot(8 * d6)
# Histogram of 1000 rolls of 8d6
rroll_plot(1000, 8 * d6)
```
Every p/q function also has a convenient `lower.tail` argument that can be set
to `FALSE` in order to run calculations from the upper tail of the distribution.
### 🪄 Statistician
Since you are an R veteran, you should be able to bend droll to your will. If
you'd like to peek into the fabric of droll's reality, you can use the `r()`
function to get a full roll distribution. If you want maximum precision, you
can also stop droll from casting its internal representation (powered by
Ryacas) to doubles with `precise = TRUE`.
```{r}
# Get full distribution of 8d6
r(8 * d6)
# Unlimited power
r(8 * d6, precise = TRUE)
```
The data frame returned by `r()` can be used as the `roll` argument of every
function discussed above. This skips all internal calculations, so it's a useful
shortcut if you want to run multiple diagnostics on the same roll expression.
As a level 20 statistician, you are not constrained by droll's built-in dice
either. You can create custom dice using the same `d()` function described
before.
```{r}
# Create a fudge die
dF <- d(-1:1)
rroll(5, dF)
# Create a 2d20kh, the "advantage die"
df <- r(max(d20, d20))
kh <- d(rep(df$outcome, df$n))
rroll(5, kh)
```
## Code of Conduct
Please note that the droll project is released with a
[Contributor Code of Conduct](https://contributor-covenant.org/version/2/0/CODE_OF_CONDUCT.html).
By contributing to this project, you agree to abide by its terms.