蒙蒂·霍尔模拟网络应用

JavaScriptJavaScriptBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

欢迎来到蒙提霍尔问题模拟项目。蒙提霍尔问题是一个基于游戏节目场景的概率谜题。在这个项目中,我们将指导你创建一个简单的基于网络的模拟来演示这个谜题。到最后,你将拥有一个功能齐全的蒙提霍尔模拟程序,供你自己测试这个理论。

👀 预览

蒙提霍尔

🎯 任务

在这个项目中,你将学习:

  • 如何为一个网络应用程序设置基本的项目结构。
  • 如何使用 HTML 和 CSS 设计一个带有交互元素的简单用户界面。
  • 如何使用 JavaScript 实现游戏逻辑,模拟蒙提霍尔问题。
  • 如何根据用户的交互向他们显示动态反馈。
  • 如何通过实际模拟来理解和应用概率的基本概念。

🏆 成果

完成这个项目后,你将能够:

  • 开发一个基本的网络应用程序结构。
  • 使用 HTML 和 CSS 创建一个交互式用户界面。
  • 在 JavaScript 中实现游戏逻辑和条件决策。
  • 根据用户的操作向他们提供动态反馈。
  • 通过实际模拟更深入地理解概率概念。

设置项目文件

在开始编码之前,让我们先准备好项目结构。我们需要三个文件:

  1. index.html - 这个文件将包含我们网页的结构。
  2. styles.css - 在这里,我们将定义模拟的外观。
  3. script.js - 这个文件将包含模拟背后的逻辑。

首先,创建上述三个文件。

cd ~/project
## 创建所需文件
touch index.html styles.css script.js

在这一步中,我们正在为基于网络的模拟设置基础文件。这些文件将包含我们应用程序的结构、样式和逻辑。

构建 HTML 页面

在这一步中,我们将构建网页的结构。打开 index.html 文件并添加以下内容:

<!-- index.html 内容 -->
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>蒙提霍尔问题模拟</title>
    <link rel="stylesheet" href="styles.css" />
    <script src="script.js" defer></script>
  </head>

  <body>
    <h2>蒙提霍尔问题模拟</h2>
    <!-- 其余内容将在后续步骤中添加。 -->
  </body>
</html>

index.html 提供了我们网页的基本结构。用户将在这里与我们的模拟进行交互。

✨ 查看解决方案并练习

添加交互元素

现在,让我们在 HTML 页面中添加交互元素,以便用户与模拟进行交互。

将以下内容添加到 index.html 中:

<!-- 在 index.html 的 body 标签内 -->
<p>选择一扇门开始:</p>
<button onclick="pickDoor(1)">门 1</button>
<button onclick="pickDoor(2)">门 2</button>
<button onclick="pickDoor(3)">门 3</button>

<div id="result"></div>

<h3>结果:</h3>
<p>换门时获胜次数:<span id="switchWins">0</span></p>
<p>换门时失败次数:<span id="switchLosses">0</span></p>
<p>不换门时获胜次数:<span id="stayWins">0</span></p>
<p>不换门时失败次数:<span id="stayLosses">0</span></p>

我们现在正在用交互元素增强我们的网页。通过添加按钮和结果显示,用户可以积极参与蒙提霍尔游戏,并查看他们决策的结果。

✨ 查看解决方案并练习

设计页面样式

为了让我们的模拟在视觉上更具吸引力,让我们添加一些样式。打开 styles.css 文件并粘贴以下内容:

/* styles.css 内容 
基本网页布局的样式表:
- 为页面主体设置默认的浅灰色背景、文本居中对齐以及 Arial 字体。
- h2 和 h3 标题的样式为特定的蓝色。
- 按钮样式包括:
  - 蓝色背景搭配白色文本。
  - 圆角。
  - 悬停效果,使背景颜色变深并使按钮略微放大。
- #result 是一个带有内边距、边框和阴影的样式化容器。
- 段落的上下边距为 10 像素。
*/

body {
  font-family: "Arial", sans-serif;
  margin: 0;
  padding: 0;
  background-color: #f8f9fa;
  color: #333;
  text-align: center;
  padding-top: 50px;
}

h2,
h3 {
  color: #007bff;
}

button {
  background-color: #007bff;
  border: none;
  color: white;
  padding: 10px 20px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  border-radius: 4px;
  transition:
    background-color 0.3s,
    transform 0.3s;
}

button:hover {
  background-color: #0056b3;
  transform: scale(1.05);
}

#result {
  margin-top: 20px;
  padding: 20px;
  border: 1px solid #e0e0e0;
  background-color: #ffffff;
  border-radius: 5px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

p {
  margin: 10px 0;
}

styles.css 文件是我们定义模拟视觉方面的地方。

  1. 主体样式

    • font-family: "Arial", sans-serif;:将网页主体的默认字体设置为 Arial。如果没有 Arial 字体,则回退到任何无衬线字体。
    • margin: 0; padding: 0;:去除默认边距和内边距。
    • background-color: #f8f9fa;:为整个页面设置浅灰色背景颜色。
    • color: #333;:为文本设置深灰色。
    • text-align: center;:将文本对齐到页面中心。
    • padding-top: 50px;:在主体顶部添加 50 像素的内边距。
  2. 标题样式

    • h2, h3 { color: #007bff; }h2h3 标题用特定的蓝色调着色。
  3. 按钮样式

    • 按钮有蓝色背景、白色文本且无边框。
    • 通过 border-radius 设置圆角。
    • 鼠标悬停在按钮上时,其背景颜色变为更深的蓝色调,并且按钮会略微放大(transform: scale(1.05);)。
  4. 结果容器

    • #result:表示 id 为 “result” 的元素。
    • 它有白色背景、灰色边框和微妙的阴影。
    • 该容器的样式看起来像一个带有圆角的卡片或盒子。
  5. 段落样式

    • 段落(p)的上下边距为 10 像素。这确保了连续段落和其他元素之间的间距。

这一步确保用户界面美观且易于阅读。

✨ 查看解决方案并练习

初始化全局变量

现在,让我们实现游戏逻辑。

首先设置用于跟踪游戏状态的全局变量。

打开 script.js 并添加:

// script.js 内容

// 用于跟踪游戏状态的全局变量
let selectedDoor;
let carBehindDoor;
let switchWins = 0;
let stayWins = 0;
let switchLosses = 0;
let stayLosses = 0;

我们正在 script.js 文件中定义一组全局变量。这些变量有助于管理游戏状态,例如选择了哪扇门、汽车位于何处以及输赢次数。

✨ 查看解决方案并练习

设置游戏初始化函数

现在,我们将添加一个函数来初始化游戏。这个函数将在每一轮开始时随机确定汽车的位置。

将以下内容添加到 script.js 中:

// 通过随机确定汽车的位置来初始化游戏
function initializeGame() {
  carBehindDoor = Math.floor(Math.random() * 3) + 1;
  document.getElementById("result").innerText = "";
}

initializeGame 函数为每一轮游戏做好准备。它随机确定汽车的位置,确保每一次游戏迭代都是不可预测的。

✨ 查看解决方案并练习

实现门选择逻辑

一旦游戏初始化完成,我们需要处理用户对门的选择以及蒙蒂打开一扇有山羊的门这一情况。

script.js 中追加:

// 当一扇门被选中时调用的函数
function pickDoor(doorNumber) {
  initializeGame();
  selectedDoor = doorNumber;
  let goatDoor = getGoatDoor();
  document.getElementById("result").innerHTML =
    `你选择了门 ${selectedDoor}。蒙蒂打开了门 ${goatDoor} 以展示一只山羊。<br>` +
    `你想 <button onclick="revealPrize(true)">换门</button> 还是 ` +
    `<button onclick="revealPrize(false)">不换门</button>?`;
}

pickDoor 函数捕获用户对门的选择。它通过展示一扇有山羊的门来准备下一阶段,并提示用户做出换门或不换门的选择。

✨ 查看解决方案并练习

确定有山羊的门

我们需要一个单独的函数来确定蒙蒂会打开哪扇门以展示一只山羊。这扇门不能是玩家选择的那扇门,也不能是后面有汽车的那扇门。

继续在 script.js 中追加:

// 找到一扇后面有山羊的门
function getGoatDoor() {
  let goatDoor;
  do {
    goatDoor = Math.floor(Math.random() * 3) + 1;
  } while (goatDoor === selectedDoor || goatDoor === carBehindDoor);
  return goatDoor;
}

getGoatDoor 是一个关键函数,它确定除了用户选择的门和汽车所在的门外,哪扇门会被打开以展示一只山羊。它采用了受游戏规则约束的随机选择。

✨ 查看解决方案并练习

设置奖品揭晓逻辑

最后,我们将设置逻辑来根据用户换门或不换门的选择处理最终的揭晓。目前,这个函数将是一个占位符,并将在后续步骤中进行扩展。

用以下内容完成对 script.js 的添加:

// 揭晓所选门后的奖品
function revealPrize(switchDoor) {
  if (switchDoor) {
    selectedDoor = 6 - selectedDoor - getGoatDoor();
  }
  // 我们将在后续步骤中在此处添加更多逻辑。
}

initializeGame();

revealPrize 函数处理游戏的最后部分。根据用户换门或不换门的选择,这个函数最终将确定用户是赢得一辆汽车还是得到一只山羊。

✨ 查看解决方案并练习

显示游戏结果

在这一步中,我们将增强 revealPrize 函数以显示用户选择的结果。将以下代码追加到 script.js 中的 revealPrize 函数:

// 继续script.js中的revealPrize函数

if (selectedDoor === carBehindDoor) {
  if (switchDoor) {
    switchWins++;
    document.getElementById("switchWins").innerText = switchWins;
  } else {
    stayWins++;
    document.getElementById("stayWins").innerText = stayWins;
  }
  document.getElementById("result").innerText =
    "恭喜!你赢了一辆汽车!选择一扇门重新开始游戏。";
} else {
  if (switchDoor) {
    switchLosses++;
    document.getElementById("switchLosses").innerText = switchLosses;
  } else {
    stayLosses++;
    document.getElementById("stayLosses").innerText = stayLosses;
  }
  document.getElementById("result").innerText =
    "很遗憾,你得到了一只山羊。选择一扇门重新开始游戏。";
}

此处对 revealPrize 函数的增强用于向用户传达游戏结果。这一步对于反馈至关重要,它能让用户看到其决策的后果,并鼓励用户多次游戏以观察概率结果。

✨ 查看解决方案并练习

运行项目

要查看蒙蒂·霍尔模拟的实际运行情况:

  1. 确保你所有的文件(index.htmlstyles.cssscript.js)都已保存。
  2. 在网页浏览器中打开 index.html 文件。
打开网页

最后,这一步指导用户如何在其浏览器中运行模拟,将代码转化为视觉和交互体验。

蒙蒂·霍尔

总结

恭喜你!你已经成功构建了一个蒙蒂·霍尔问题模拟。通过完成这个项目,你学会了如何构建一个简单的网页项目、设计其元素样式以及实现交互式的JavaScript功能。现在,你可以运行多个模拟来亲自查看蒙蒂·霍尔问题的概率结果!