骰子產生器
打 3d6+2,拿到結果 —— 以及它當時面對的精確機率。
本機處理按「擲骰」。每一顆骰子都從你作業系統的密碼學隨機來源取值 —— 沒有取模,也沒有 Math.random。
目前為止的每一顆骰與每一個總和 —— 分布的形狀你可以自己核對
每一顆骰子本身公正嗎?
| 骰子 | 點數 | 次數 | 佔比 | 期望次數 |
|---|
累計總和 vs 精確理論機率
| 總和 | 次數 | 佔比 | 精確機率 | 期望次數 |
|---|
完全在你的瀏覽器裡執行 —— 打開開發者工具的 Network 分頁就能驗證
用桌上遊戲寫了五十年的方式把骰子打進去,然後按「擲骰」。這一頁跟其他幾十個骰子網頁的差別不在動畫,而在累計統計裡多了一欄「精確理論機率」 —— 那一欄是用卷積算出來的,不是從你擲出的結果反推的。所以當一個總和看起來很不可思議時,你可以真的去查它到底是不是。
骰子記法,以及這個欄位吃得下什麼
記法是 NdM:N 顆 M 面的骰子。2d6 是兩顆六面骰,d20 是一顆二十面骰,數量是 1 的時候可以整個省略。修正值寫在最後面,加號或減號都可以,所以 3d6+2 就是擲三顆六面骰再加 2。整組相加也可以,武器傷害與法術效果通常就是這樣寫的:2d6+1d8-1 會把兩組都擲出來,修正值只在最後套用一次。
另外兩個後綴涵蓋了桌上最常出現、線上工具卻幾乎都不支援的情況。kh 是保留最高、kl 是保留最低:4d6kh3 擲四顆六面骰取最高三顆相加,那是產生一項屬性值的標準做法;2d20kh1 與 2d20kl1 則是優勢與劣勢。被擲出來但沒被算進去的骰子會用方括號標示而不是藏起來,這是刻意的 —— 一個把落選骰子悄悄丟掉的「取最高」,跟一個根本沒擲那幾顆的實作,從畫面上看起來一模一樣。
百分骰有自己的簡寫:d% 就是 d100。面數從 2 到 1000 都可以,包含那些現實中不存在的面數 —— 一顆十七面的骰子在數學上是定義完整的隨機變數,即使沒有人做得出公正的實體版本。任何解析不了的輸入都會回一句具體到位的說明,而不是一句「格式錯誤」;一個沒告訴你哪裡錯的訊息,只會讓你在那邊亂試。
總和不是均勻分布,而那正是重點
單一顆骰子是平的:每一面機率相同,那也是大家講「隨機」時通常指的性質。但只要把兩顆骰子加起來,這件事就不成立了,而且這個誤會比想像中普遍。2d6 有三十六種等機率的結果,其中六種的總和是 7,總和是 2 的只有一種。7 不是「比 2 稍微常見一點」—— 它是六倍。換成 3d6 差距更誇張:兩百一十六種結果裡有二十七種總和是 10,而總和是 3 的正好只有一種。
所以「用 1d20 還是 3d6」是一個設計決定,不是喜好問題。d20 的分布是平的,所以「加 2」不論落在刻度的哪裡都恰好值十個百分點;三顆六面骰在中間隆起一個峰,同樣的「加 2」在中央價值極高、在兩端幾乎沒有意義。規則書選哪一種都是有意為之,而把 3d6 系統形容成「大起大落」,剛好把事實講反了。
這一頁的第二張表,就是把精確理論機率擺在你實際擲出的次數旁邊。那一欄不是從你的結果推出來的 —— 它是把每一組骰子的分布做卷積算出來的,所以兩欄真的互相獨立,而那是「拿它們互相比較」唯一有意義的前提。取最高/取最低的情況改用窮舉求精確值;當一條式子大到誠實窮舉不完時,那一欄會直接留白,而不是塞一個近似值進去假裝它是事實。
每一面到底從哪裡來
這一頁每一顆骰子都從 crypto.getRandomValues 取值 —— 那是你作業系統的密碼學隨機來源 —— 再用拒絕取樣折進面數裡。常見的捷徑是 Math.floor(Math.random() * 6),而它有兩個要分開看的問題。第一個是底層值池幾乎永遠不是面數的整數倍:JavaScript 的整數值池是 2 的 53 次方,除以 6 餘 2,所以沒有拒絕取樣的話,最小的那兩個點數會各多拿到一個位置。
對六面骰來說,那等於六個點數裡有兩個,各自在 1,501,199,875,790,165 個位置中多拿到一個 —— 遠低於任何一張桌子有辦法察覺的程度,我們不會假裝它很嚴重。但它會隨面數變大,而且要移除實在太容易:先算出「最大的、能被面數整除的值」,抽到大於或等於它的就丟掉重抽。被丟掉的區間小到可以忽略,剩下的部分可以被完美等分,於是每一面的機率從「大致相同」變成「完全相同」。
第二個問題才是真正要緊的,而且它跟公正性無關。Chrome 與 Edge 裡的 Math.random 是 xorshift128+,只要觀察到一小段連續輸出就能還原它的內部狀態,之後每一個值都算得出來。這對一個人單機玩無所謂,但只要有人有理由想先知道下一次擲出什麼,它就是致命的。既然正確的來源只是一次函式呼叫、而且完全免費,就不存在「用捷徑才是對的決定」的情況。
骰子「感覺被動手腳」的時候
骰子沒有記憶,而幾乎每一則對骰子工具的抱怨,追到底都是在期待它有記憶。一顆連續三次擲出 1 的 d20,下一次擲出 1 的機率跟第一次完全一樣。那個連續本身不是任何東西的證據:連續三次 1 大約每八千組連續三次會出現一次,而一個跑團跑到累積幾千次 d20 的隊伍,本來就該遇到。真正可疑的反而是相反的情況 —— 一個從不出現連續的來源,是「沒做到隨機」,不是「做到了公正」。
另一半的感覺來自記憶的偏誤。在最糟時機出現的大失敗會被記住;在那之前四十次平淡無奇的結果不會。這也是為什麼這一頁的統計是累計而且機械的,而不是一段要你信任的結論:點數表驗的是均勻性,總和表驗的是形狀,兩張都附上「你這個樣本數下預期的擺盪幅度」—— 因為一張只有次數、沒有這個數字的表格,根本沒辦法讀。
如果你真的想抓一顆有偏的骰子,你手上那顆遠比螢幕上這顆值得懷疑。賭場用的骰子會做到很緊的公差、點數挖洞後回填同密度的材料再磨平,正是因為要做到公正就得付這個代價;一般射出成型、點數直接鑽洞不回填的骰子,數字大的那幾面比較輕,而且它們根本不對任何公正性標準負責。把一顆 d20 丟進高濃度鹽水裡反覆轉,如果重心偏了,它會一直把同樣那幾面轉上來 —— 這是一個你十分鐘就能在家做完的檢驗。
在台灣,骰子其實一直都在
骰子在台灣不是只有跑團在用。過年圍爐後常玩的「十八啦」是四顆骰子丟進瓷碗,靠成對相消之後剩下兩顆的點數比大小,兩顆六點就是那句「十八啦」;廟口與尾牙的骰盅、大富翁的兩顆六面骰、甚至抽獎前用來決定順序的那一擲,用的都是同一件東西。值得注意的是,十八啦的計分規則會讓結果的分布跟「四顆骰子的和」完全不一樣 —— 這一頁算的是總和,不是十八啦的點數,這一點要先講清楚,免得你拿這裡的機率去對那個遊戲。
另一個對照很有意思:台灣真正的「隨機儀式」其實是擲筊,而擲筊從來不是公正的隨機來源。筊杯一面平一面鼓,形狀本身就不對稱,聖杯、笑杯、陰杯三種結果的機率不可能相同,而且沒有任何人期待它相同 —— 它要回答的本來就不是「公不公平」這個問題。骰子剛好相反:骰子存在的全部意義就是公正,所以一顆骰子公不公正是可以問、也應該問的。
這個差別也解釋了為什麼這一頁要把統計攤開來。一個線上骰子工具跟一顆實體骰子最大的不同,是你看不到它 —— 你沒辦法把它拿起來對光看、丟進鹽水裡轉。既然看不到,能替代的就只有「把每一次結果留著,並且告訴你理論上該長什麼樣」。這就是這一頁在做的事。
這裡的任何東西都不會離開你的裝置
按下「擲骰」不會產生任何請求。隨機來自你自己的機器,累計數字住在這個分頁的記憶體裡,分頁一關就沒了。沒有任何結果被記錄在伺服器上 —— 這也代表沒有任何結果可以在事後被拿出來當成什麼的證據,而只要那一擲是要在兩個人之間決定什麼,這個性質就比聽起來重要得多。
這件事十秒就能查證,不必用信任來換。打開瀏覽器的開發者工具切到 Network 分頁,然後想擲幾次就擲幾次,那份清單會一直是空的。這個網站也會送出把網路連線限制在自己來源的 Content-Security-Policy,執行它的是你的瀏覽器,不論我們的程式怎麼寫都一樣。
同一個架構也讓它在沒有訊號的地方照樣能用。第一次造訪之後頁面就被快取起來,而熵來自你的作業系統而不是某個遠端服務,所以根本沒有需要連線的地方。一個需要連線的骰子工具,會剛好在桌遊最常發生的那種場合失效 —— 訊號很差的地下室。
常見問題
4d6kh3 是什麼意思?
擲四顆六面骰,取最高的三顆相加,最低的那顆丟掉。這是產生一項屬性值的標準做法,平均值明顯高於 3d6,因為最差的一顆被丟掉了。被丟掉的那顆會用方括號顯示出來,讓你看得到它真的被擲過。
可以一次擲不同面數的骰子嗎?
可以。把幾組寫在同一條式子裡相加:2d6+1d8-1 會把兩組都擲出來,修正值只在最後套用一次。你也可以把「一次擲幾輪」調大來重複整條式子 —— 一次按下去就拿到 4d6kh3 的完整六項屬性值。
2d6 為什麼 7 比 2 常見那麼多?
因為兩顆骰子湊出 7 有六種方法,湊出 2 只有一種。把骰子加起來會把平的分布變成中間隆起的形狀,加的骰子越多、那個峰越尖。總和表會列出每一個總和的精確機率,所以那個形狀是你可以讀到的東西,不是要你背下來的東西。
這些骰子真的公正嗎?
每一面都從你作業系統的密碼學隨機來源加拒絕取樣抽出,所以每一面的機率完全相同 —— 過程裡沒有取模那一步,也就沒有讓偏差鑽進來的縫。點數表放在那裡是為了讓你查證而不是相信,而且它會告訴你在你這個樣本數下多少變異算正常。
換一組骰子之後統計為什麼歸零?
因為你換了骰子。2d6 跟 3d6 的分布是兩個不同的形狀,混在一起會做出一張哪一個都沒描述、卻看起來像證據的表。改「一次擲幾輪」則不會歸零,因為那不改變分布。
可以設定種子重現同一次結果嗎?
不行,而那是刻意的。密碼學隨機來源在設計上就沒有可重現的種子,而一個你看得到的種子就是別人也能預測的種子 —— 那正好是「這一擲要決定什麼」時你最不想要的性質。如果你需要可重現的偽隨機來跑模擬,那是另一種需求。
擲出來的結果會被送到伺服器嗎?
沒有。每一顆骰子都由你自己的瀏覽器擲出。你可以在開發者工具的 Network 分頁確認,而且這個網站的 Content-Security-Policy 本來就把連線限制在自己的來源,跟我們的程式怎麼寫無關。


