掷骰子工具看起来像是一个只需一行代码的项目:
const value = Math.floor(Math.random() * 6) + 1;
这一行代码足以生成一个 1 到 6 之间的数字。但这还不足以构成一个实用的概率工具。
当用户提出以下问题时,有趣的工程挑战才真正开始:
- 我可以一次投掷多个骰子吗?
- 我可以在不冻结页面的情况下运行 10、50 或 100 次试验吗?
- 结果分布是否符合预期?
- 显示的平均值究竟衡量的是什么?
- 我可以导出观测数据并在其他地方进行检查吗?
本文旨在构建这些功能背后的思维模型和实现方案。其目标并非制作花哨的动画,而是提供一个小型、诚实的实验,使其状态、统计信息和局限性易于理解。
1. 在编写用户界面之前定义实验
假设用户选择了 k 个六面骰子并按下“投掷”按钮一次。该动作构成一次试验,但会产生 k 个独立的点数观测值。
这种区分至关重要。在使用 6 个骰子进行 100 次试验后:
- 试验次数为 100;
- 观测到的点数总数为 600;
- 单个点数的期望均值为 3.5;
- 每次试验总点数的期望均值为
3.5 * 6 = 21; - 每个点数应约占 600 个点数观测值的六分之一。
如果直方图将点数计数除以 100 而不是 600,那么它展示的并不是概率。它混淆了两种不同的单位。
紧凑的状态模型使这些单位变得明确:
const state = {
diceCount: 1,
trialCount: 0,
grandTotal: 0,
faceCounts: [0, 0, 0, 0, 0, 0],
history: []
};
我使用 trialCount 记录完成的投掷次数,并通过以下方式推导点数观测值的数量:
const sampleCount = state.faceCounts.reduce(
(sum, count) => <
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。
分享到:
长按或扫码识别 分享给好友