最近、TRPGで遊びたいなーという機運が高まり、とりあえずフィフスエディションRPG(5eRPG)のコアルールを読んだりしている。
5eRPGってのはTRPGの王道「ダンジョンズ&ドラゴンズ第5版」(D&D5e)から版権にかかわる部分(鈴木土下座ェ門とか)を抜いた、版権フリーなTRPGのシステム。
TRPGは乱数発生器としてサイコロ(ダイス)を使うので統計学、特に確率分布の理解はあった方がよかったりする。
それで5eRPGのコアルールをパラパラ眺めていると「遊び方の基本」の章の中に「“有利”と“不利”」という項目があった。
TRPGは何らかの行動が成功したか失敗したかを判定するために、サイコロを振って決めることが多い。D&D5eや5eRPGの場合、20面体のサイコロを1個振って、出目が目標値以上であれば成功、そうでなければ失敗、とすることが多い。

Photo by Armando Are: https://www.pexels.com/photo/green-d20-dice-for-tabletop-rpg-gaming-32030732/
もし、それが「有利な状況」での出来事であれば20面体のサイコロを2個振って、大きな出目の方が採用される。
逆に、それが「有利な状況」での出来事であれば20面体のサイコロを2個振って、小さな出目の方が採用される。
これが「“有利”と“不利”」のルールである。
さて、20面体のサイコロを1個であれば一様分布なので目標値以上の目が出る確率も直感的に分かるだろう。
しかし、20面体のサイコロを2個振って、大きな(小さな)出目の方が採用される場合の分布の形をすぐに思い浮かべられる人は多くないと思う。
ということで、確認してみた。
まずは準備。
library(conflicted)
library(tidyverse)
library(ggrepel)
d20 <- 1:20 #20面体ダイス
d20x2 <- expand.grid(d20, d20) #20面体ダイス2個の全組み合わせ
d20_Advantage <- pmax.int(d20x2$Var1, d20x2$Var2) # 有利の結果
d20_Disadvantage <- pmin.int(d20x2$Var1, d20x2$Var2) #不利の結果
D20s <- bind_rows(
tibble(type = "通常", value = d20),
tibble(type = "有利", value = d20_Advantage),
tibble(type = "不利", value = d20_Disadvantage)
)
基本統計量を確認します。
D20s |>
summarise(
中央値 = median(value),
平均値 = mean(value),
標準偏差 = sd(value),
.by = type
)
| 状況 | 中央値 | 平均値 | 標準偏差 |
|---|---|---|---|
| 通常 | 10.5 | 10.5 | 5.92 |
| 有利 | 15.0 | 13.8 | 4.72 |
| 不利 | 6.0 | 7.2 | 4.72 |
なるほど、有利だと通常よりも平均で+3.3も期待値が高いうえにバラツキも小さくなる。
数表だけでは分かりにくいので可視化しましょう。
# 可視化用データセット
D20s_viz <- D20s |>
count(type, value) |>
mutate(
percentage = n / sum(n) * 100, # 出目の確率
cum_sum = rev(cumsum(rev(percentage))), # 出目の累積確率
.by = type
)
# 確率分布
D20s_viz |>
ggplot(aes(x = value, y = percentage, fill = type, label = percentage)) +
geom_col() +
geom_text() +
scale_x_continuous(breaks = 1:20, minor_breaks = NULL) +
theme(aspect.ratio = 1) +
labs(
title = "5eRPGにおける能力値判定における有利、不利",
subtitle = "確率分布",
x = "出目",
y = "確率(%)"
) +
facet_wrap(vars(type))

これで見ると、攻撃ロール(命中判定)におけるクリティカル率(出目20が出る確率)は通常 5%、有利 9.75%、不利 0.25%と大きく変わることがよく分かる。
それでは目標値以上が出る確率はどうだろ。累積確率を確認してみる。
D20s_viz |>
ggplot(aes(x = value, y = cum_sum, color = type, label = cum_sum)) +
geom_point(size = 3) +
geom_line() +
geom_text_repel() +
scale_x_continuous(breaks = 1:20, minor_breaks = NULL) +
theme(aspect.ratio = 1 / 1.1) +
labs(
title = "5eRPGの攻撃ロールにおける有利、不利の累積確率分布",
subtitle = "累積確率分布(目標値以上が出る確率)",
x = "目標値",
y = "確率(%)"
)
目標値(難易度、DC)が10の場合、成功する確率は通常55%、有利79.8%、30.2%となっている。
こんな具合でTRPGには様々な確率分布が存在するので、また興味深い確率分布を見つけたら記事にしようと思います。
