最近看韩国电视剧【D.P:逃兵追缉令】里边提到一个风趣的数学概率游戏 -> 蒙提霍尔问题
意思是:参赛者会看见三扇门,其间一扇门的里边有一辆轿车,选中里边是轿车的那扇门,就能够赢得该辆轿车,别的两扇门里边则都是一只山羊,让你恣意挑选其间一个,然后翻开其他两个门中的一个并且是山羊(去掉一个过错答案),这时,让你重新挑选。那么你是会坚持本来的挑选,仍是换选别的一个未被翻开过的门呢?
我们能够想一想如果是自己,我们是会换仍是不会换?
好了,我当时看到后感觉很有意思,所以我简单写了一套代码,源码贴在下面,我们能够验证一下,先告诉我们,换赢得轿车的概率是2/3,不换赢得轿车的概率是1/3
<header>
<h1>请挑选换不换?</h1><button class="refresh">改写</button>
</header>
<section>
<div class="box">
<h2>1</h2>
<canvas width="300" height="100"></canvas>
<div class="prize">奖品</div>
</div>
<div class="box">
<h2>2</h2>
<canvas width="300" height="100"></canvas>
<div class="prize">奖品</div>
</div>
<div class="box">
<h2>3</h2>
<canvas width="300" height="100"></canvas>
<div class="prize">奖品</div>
</div>
</section>
<span>请挑选号码牌</span>
<select name="" id="">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<button class="confirm">确认</button>
<span class="confirm-text"></span>
<span class="opater">
<button class="change">换</button>
<button class="no-change">不换</button>
</span>
<p>
<strong>游戏规则:</strong>
<span>
上面有三个号码牌,其间一个号码牌的里边有轿车,选中里边是轿车的号码牌,
你就能够赢得该辆轿车,别的两个号码牌里边则都是一只山羊,
你恣意挑选其间一个,然后翻开其他两个号码牌中的一个并且是山羊(去掉一个过错答案),
这时,你有一个重新挑选的时机,你挑选换仍是不换?
</span>
</p>
.prize {
width: 300px;
height: 100px;
background-color: pink;
font-size: 36px;
line-height: 100px;
text-align: center;
position: absolute;
}
canvas {
position: absolute;
z-index: 2;
}
section {
display: flex;
}
.box {
width: 300px;
height: 200px;
cursor: pointer;
}
.box+.box {
margin-left: 8px;
}
header {
display: flex;
align-items: center;
}
header button {
margin-left: 8px;
height: 24px;
}
p {
width: 400px;
background-color: pink;
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function getRandomNumber() {
return Math.random() > 0.5 ? 1 : 2;
}
let a1 = [0, 1, 2]
let i1 = undefined
let i2 = undefined
let isChange = false
const opater = document.querySelector('.opater')
opater.style.display = 'none'
// 随机一个奖品
const prizes = document.querySelectorAll('.prize')
let a0 = [0, 1, 2]
a0 = shuffleArray(a0)
a0.forEach((v,i) => {
const innerText = !!v ? '山羊' : '轿车'
prizes[i].innerText = innerText
})
const canvas = document.querySelectorAll('canvas')
const confirmText = document.querySelector('.confirm-text')
canvas.forEach(c => {
// 运用canvas实现功用
// 1. 运用canvas制作一个灰色的矩形
const ctx = c.getContext('2d')
ctx.fillStyle = '#ccc'
ctx.fillRect(0, 0, c.width, c.height)
// 2. 刮奖逻辑
// 鼠标按下且移动的时分,需要擦除canvas画布
let done = false
c.addEventListener('mousedown', function () {
if (i1 === undefined) return alert('请先挑选号码牌,并确认!')
if (!isChange) return alert('请挑选换不换!')
done = true
})
c.addEventListener('mousemove', function (e) {
if (done) {
// offsetX 和 offsetY 能够获取到鼠标在元素中的偏移位置
const x = e.offsetX - 5
const y = e.offsetY - 5
ctx.clearRect(x, y, 10, 10)
}
})
c.addEventListener('mouseup', function () {
done = false
})
})
const confirm = document.querySelector('.confirm')
const refresh = document.querySelector('.refresh')
confirm.onclick = function () {
let select = document.querySelector('select')
const options = Array.from(select.children)
confirmText.innerText = `您挑选的号码牌是${select.value},请问现在换不换?`
// 挑选后,去掉一个过错答案
// i1是下标
i1 = select.value - 1
// delValue是值
let delValue = undefined
// 经过下标找值
if (a0[i1] === 0) {
delValue = getRandomNumber()
} else {
delValue = a0[i1] === 1 ? 2 : 1
}
// 经过值找下标
i2 = a0.indexOf(delValue)
// 挑选的是i1, 去掉的是
const ctx = canvas[i2].getContext('2d')
ctx.clearRect(0, 0, 300, 100)
options.map(v => v.disabled = true)
confirm.style.display = 'none'
opater.style.display = 'inline-block'
}
const change = document.querySelector('.change')
const noChange = document.querySelector('.no-change')
change.onclick = function () {
isChange = true
const x = a1.filter(v => v !== i1 && v !== i2)
confirmText.innerText = `您确认挑选的号码牌是${x[0] + 1},请刮卡!`
opater.style.display = 'none'
}
noChange.onclick = function () {
isChange = true
confirmText.innerText = `您确认挑选的号码牌是${i1 + 1},请刮卡!`
opater.style.display = 'none'
}
refresh.onclick = function () {
window.location.reload()
}