📅  最后修改于: 2023-12-03 15:40:52.474000             🧑  作者: Mango
Monty Hall 游戏是一种现代的概率谜题,其灵感来源于电视节目“让我们做个交易”(Let's Make a Deal)。该游戏由三扇关闭的门组成,其中一扇门后面有奖品,而其他两扇门后面则是空的。玩家选择其中一扇门,主持人随机打开一扇未被选中的门(其中必须没有奖品),然后问玩家是否要改变他们的选择。经典的解决方案是,如果玩家改变他们的选择,则他们将获胜的概率为 2/3,而如果他们不改变选择,则他们获胜的概率为 1/3。
在本文中,我们将使用 Vanilla JavaScript 创建一个 Monty Hall 游戏,以了解在 JavaScript 中如何运用概率计算。
首先,我们需要创建一个 HTML 结构,包含三个门和相应的按钮:
<div class="doors">
<div class="door" id="1"></div>
<div class="door" id="2"></div>
<div class="door" id="3"></div>
</div>
<button id="chooseDoor">Choose a door</button>
<button id="changeChoice">Change your choice</button>
在这段 HTML 代码中,我们使用 div
元素来创建三扇门,并使用 id
属性来标识它们。我们还使用两个按钮,一个用于玩家初次选择门,另一个用于改变选择。
接下来,我们需要添加一些基本的 CSS 样式,以使门看起来更真实:
.doors {
display: flex;
justify-content: space-around;
margin-top: 2em;
}
.door {
width: 100px;
height: 200px;
background-color: brown;
border-radius: 0.5em;
}
button {
margin: 1em;
padding: 0.5em 1em;
font-size: 1.2em;
border-radius: 0.5em;
}
在这段 CSS 代码中,我们使用 flexbox 将门放置在一个水平行中,并添加了一些基本的样式。
最后,我们需要编写一些 JavaScript 代码,来实现游戏的逻辑。以下是完整的 JavaScript 代码:
// 获取门元素
const doors = document.querySelectorAll('.door');
// 获取按钮元素
const chooseButton = document.querySelector('#chooseDoor');
const changeButton = document.querySelector('#changeChoice');
// 将奖品随机放置在其中一个门后面
let prizeIndex = Math.floor(Math.random() * 3);
let prizeDoor = doors[prizeIndex];
prizeDoor.dataset.prize = true;
// 玩家选择门的函数
function chooseDoor() {
// 将所有门元素从门选中类中移除
doors.forEach(door => door.classList.remove('selected', 'opened'));
// 随机选择一个门,并将其添加到门选中类中
let selectedIndex = Math.floor(Math.random() * 3);
let selectedDoor = doors[selectedIndex];
selectedDoor.classList.add('selected');
// 显示选择的门号码
alert(`You've chosen door number ${selectedDoor.id}.`);
// 显示打开的门,并询问是否更改选择
let openedIndex = getOpenedIndex(selectedIndex);
let openedDoor = doors[openedIndex];
openedDoor.classList.add('opened');
let result = confirm(`Do you want to change your choice to door number ${getOtherIndex(selectedIndex, openedIndex) + 1}?`);
// 如果更改了选择,则将选择的门更改为未选择的另一个门
if (result) {
selectedIndex = getOtherIndex(selectedIndex, openedIndex);
selectedDoor = doors[selectedIndex];
selectedDoor.classList.add('selected');
}
// 显示结果
let resultText = selectedDoor.dataset.prize ? 'Congratulations! You win!' : 'Sorry, you lose.';
alert(resultText);
}
// 玩家更改选择的函数
function changeChoice() {
// 获取当前选中的门元素,并移除门选中类
let selectedDoor = document.querySelector('.door.selected');
selectedDoor.classList.remove('selected');
// 获取当前打开的门元素,将其从打开类中移除,并将其设为选中的门
let openedDoor = document.querySelector('.door.opened');
openedDoor.classList.remove('opened');
selectedDoor = doors[getOtherIndex(parseInt(selectedDoor.id) - 1, parseInt(openedDoor.id) - 1)];
selectedDoor.classList.add('selected');
// 显示结果
let resultText = selectedDoor.dataset.prize ? 'Congratulations! You win!' : 'Sorry, you lose.';
alert(resultText);
}
// 获取打开的门的索引
function getOpenedIndex(selectedIndex) {
if (doors[selectedIndex].dataset.prize) {
return Math.floor(Math.random() * 2) + ((selectedIndex + 1) % 2);
} else {
for (let i = 0; i < 3; i++) {
if (i !== selectedIndex && !doors[i].dataset.prize) {
return i;
}
}
}
}
// 获取未选中的另一个门的索引
function getOtherIndex(selectedIndex, openedIndex) {
for (let i = 0; i < 3; i++) {
if (i !== selectedIndex && i !== openedIndex) {
return i;
}
}
}
// 为按钮添加事件监听器
chooseButton.addEventListener('click', chooseDoor);
changeButton.addEventListener('click', changeChoice);
在这段 JavaScript 代码中,我们首先获取门元素和按钮元素。然后,使用 Math.random()
函数来将奖品随机放置在其中一个门的后面。接下来,我们编写函数 chooseDoor()
和 changeChoice()
来分别表示玩家初次选择门和改变选择。我们还编写了两个辅助函数:getOpenedIndex()
和 getOtherIndex()
,用于获取打开的门的索引和未选中的另一个门的索引。最后,我们将这些函数添加到相应的按钮上。
现在,我们已经成功地创建了一个 Monty Hall 游戏,玩家可以用它来测试他们的概率技能。此外,本文还向您展示了如何使用 Vanilla JavaScript 创建一个基本的 Web 应用程序。