先说一句:一段时间没发文章,好多僵尸粉关注我,这CSDN😠
主要功能
-
玩家设置:在游戏开始前,输入总人数、卧底人数和白板人数。系统会自动计算出剩下的平民人数,并随机分配身份。
-
身份查看:在游戏开始后,所有玩家的身份都会以卡片形式呈现。你可以点击卡片来查看自己的身份,内容会显示“你是白板”或者对应的词语。
-
判决系统:所有玩家看完自己的身份后,可以通过“判决”按钮来猜测谁是卧底或白板。你输入认为是卧底或白板的玩家编号,无论猜测正确与否,都会减少一次判决机会。
-
剩余机会提示:每次判决后,系统会自动计算并提示你剩余的判决机会
-
胜负判定:如果你在机会用完前成功找出了所有的卧底和白板,游戏会提示平民获胜。如果机会用尽而卧底或白板还没被全部找出,游戏会提示失败。
效果图
源代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>谁是卧底</title>
<style>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background-color: #1c1c2b;
color: white;
}
.input-container {
background-color: #2d2d44;
padding: 20px;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0,0,0,0.3);
margin-bottom: 20px;
text-align: center;
}
h1 {
margin-bottom: 15px;
font-size: 24px;
font-weight: bold;
}
label {
display: block;
margin-bottom: 10px;
font-size: 18px;
}
input[type="number"] {
width: 100px;
padding: 8px;
margin-bottom: 15px;
border-radius: 10px;
border: none;
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
text-align: center;
}
button {
padding: 10px 20px;
border: none;
border-radius: 15px;
background-color: #007BFF;
color: white;
font-size: 16px;
cursor: pointer;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
.card-container {
position: relative;
width: 200px;
height: 300px;
perspective: 1000px;
}
.card {
width: 100%;
height: 100%;
background-color: orange;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
position: absolute;
top: 0;
left: 0;
transition: transform 0.6s;
transform-style: preserve-3d;
cursor: pointer;
}
.card.flipped {
transform: rotateY(180deg);
}
.card-content {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
}
.card-content.back {
transform: rotateY(180deg);
background-color: #FFEB3B;
border-radius: 15px;
}
.judge-button {
display: none;
padding: 20px 40px;
border: none;
border-radius: 25px;
background-color: #FFD700;
color: black;
font-size: 20px;
cursor: pointer;
margin-top: 20px;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<div class="input-container">
<h1>谁是卧底游戏</h1>
<label for="totalPlayers">总人数 (2-10):</label>
<input type="number" id="totalPlayers" min="2" max="10">
<label for="undercoverCount">卧底人数:</label>
<input type="number" id="undercoverCount" min="1">
<label for="blankCount">白板人数:</label>
<input type="number" id="blankCount" min="0">
<p></p>
<button onclick="startGame()">开始游戏</button>
</div>
<div class="card-container" id="cardContainer">
<!-- 卡片将会在这里生成 -->
</div>
<button class="judge-button" id="judgeButton" onclick="judge()">判决</button>
<script>
const wordsPairs = [
['苹果', '香蕉'],
['水泥', '瓷砖'],
['博客园', 'CSDN']
];
let totalPlayers, undercoverCount, blankCount, civilians, undercovers, blanks;
let remainingChances;
let cardsFlipped = 0;
function startGame() {
totalPlayers = parseInt(document.getElementById('totalPlayers').value);
undercoverCount = parseInt(document.getElementById('undercoverCount').value);
blankCount = parseInt(document.getElementById('blankCount').value);
if (isNaN(totalPlayers) || isNaN(undercoverCount) || isNaN(blankCount) ||
totalPlayers < 2 || totalPlayers > 10 ||
undercoverCount > totalPlayers || blankCount > totalPlayers ||
blankCount > undercoverCount || (undercoverCount + blankCount) > totalPlayers) {
alert('请检查输入,确保所有数值合理!');
return;
}
civilians = totalPlayers - undercoverCount - blankCount;
// 设置判决机会 = 白板数 + 卧底数 + 1
remainingChances = blankCount + undercoverCount + 1;
const wordPair = wordsPairs[Math.floor(Math.random() * wordsPairs.length)];
undercovers = Array(undercoverCount).fill(wordPair[1]);
blanks = Array(blankCount).fill('白板');
const civiliansArr = Array(civilians).fill(wordPair[0]);
const words = [...undercovers, ...blanks, ...civiliansArr].sort(() => Math.random() - 0.5);
document.querySelector('.input-container').style.display = 'none';
generateCards(words);
}
function generateCards(words) {
const cardContainer = document.getElementById('cardContainer');
cardContainer.innerHTML = '';
words.forEach((word, index) => {
const card = document.createElement('div');
card.className = 'card';
card.setAttribute('data-word', word);
card.onclick = () => flipCard(card, index);
const front = document.createElement('div');
front.className = 'card-content front';
front.innerText = '点击查看';
const back = document.createElement('div');
back.className = 'card-content back';
back.innerText = word === '白板' ? '你是白板' : word;
card.appendChild(front);
card.appendChild(back);
cardContainer.appendChild(card);
card.style.zIndex = words.length - index;
card.style.top = `${index * 5}px`;
card.style.left = `${index * 5}px`;
});
}
function flipCard(card, index) {
if (card.classList.contains('flipped')) return;
card.classList.add('flipped');
cardsFlipped++;
setTimeout(() => {
card.style.display = 'none';
if (cardsFlipped === totalPlayers) {
document.getElementById('judgeButton').style.display = 'block';
}
}, 1500);
}
function judge() {
const guess = prompt('请输入你认为的卧底或白板编号(1-' + totalPlayers + '):');
const guessIndex = parseInt(guess) - 1;
if (isNaN(guessIndex) || guessIndex < 0 || guessIndex >= totalPlayers) {
alert('无效的编号,请重新输入!');
return;
}
const word = document.querySelectorAll('.card')[guessIndex].getAttribute('data-word');
if (word === '白板' || word === undercovers[0]) {
alert(`你找到了${word === '白板' ? '白板' : '卧底'},他们被淘汰了!`);
document.querySelectorAll('.card')[guessIndex].remove();
if (word === '白板') {
blanks.pop();
} else {
undercovers.pop();
}
} else {
alert('你猜错了!');
}
remainingChances--;
alert('剩余机会: ' + remainingChances);
if (undercovers.length === 0 && blanks.length === 0) {
alert('平民获胜!');
resetGame();
} else if (remainingChances === 0) {
alert('游戏失败!');
resetGame();
}
}
function resetGame() {
document.querySelector('.input-container').style.display = 'block';
document.getElementById('cardContainer').innerHTML = '';
document.getElementById('judgeButton').style.display = 'none';
cardsFlipped = 0;
}
</script>
</body>
</html>
游戏规则
1. 角色分配
- 平民:多数玩家会被分配到同一个词语,这些玩家就是平民。平民的目标是找出谁是卧底。
- 卧底:少数玩家(通常只有一人)会被分配到一个与平民词语类似但不同的词语。卧底的目标是混淆视听,让自己不被平民发现。
- 白板(可选):某些版本中还有“白板”角色,他们不会得到任何词语,只能靠别人的描述来猜测其他人的身份。
2. 游戏流程
- 第一轮:描述词语 每个玩家依次用一句话描述自己的词语,注意不能太直白,也不能过于模糊。平民需要小心描述,确保卧底不会轻易发现他们的词语,但又要让其他平民认出自己是同伴。卧底则需要假装自己是平民,在描述时尽量不暴露自己的词语。
- 讨论与投票 一轮描述结束后,玩家可以互相讨论,并试图找出谁的描述最可疑。然后,所有玩家进行投票,选出他们认为是卧底的玩家。得票最多的玩家会被淘汰,并揭示自己的身份。
- 下一轮 剩下的玩家继续进行描述和投票,直到所有的卧底被找出(平民获胜)或平民人数与卧底人数相等(卧底获胜)。
3. 胜负判定
- 平民获胜:如果所有的卧底被投票淘汰,平民获胜。
- 卧底获胜:如果卧底成功存活到剩下人数与卧底人数相等,卧底获胜。
4. 游戏策略
- 平民需要通过描述、观察和推理来识别卧底的微妙差异。
- 卧底则需要运用策略来隐藏自己的身份,并尽量让平民之间互相怀疑。