2026-01-07 17:08:47 +08:00
|
|
|
|
<!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>
|
|
|
|
|
|
* {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
body {
|
|
|
|
|
|
font-family: '微软雅黑', Arial, sans-serif;
|
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
line-height: 1.6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.container {
|
|
|
|
|
|
max-width: 800px;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
h1 {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #ff6b35;
|
|
|
|
|
|
margin-bottom: 30px;
|
|
|
|
|
|
font-size: 2.5em;
|
|
|
|
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-info {
|
|
|
|
|
|
background-color: #f8f9fa;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
border-left: 4px solid #ff6b35;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.story-section {
|
|
|
|
|
|
background-color: #fff3cd;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
border: 2px solid #ffeeba;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.story-title {
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #856404;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
font-size: 1.2em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.story-content {
|
|
|
|
|
|
font-size: 1.1em;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-section {
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-history {
|
|
|
|
|
|
height: 300px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
background-color: #f8f9fa;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
border: 1px solid #dee2e6;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.message {
|
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.user-message {
|
|
|
|
|
|
align-items: flex-end;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bot-message {
|
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.message-content {
|
|
|
|
|
|
padding: 10px 15px;
|
|
|
|
|
|
border-radius: 18px;
|
|
|
|
|
|
max-width: 80%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.user-message .message-content {
|
|
|
|
|
|
background-color: #007bff;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.bot-message .message-content {
|
|
|
|
|
|
background-color: #e9ecef;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.message-time {
|
|
|
|
|
|
font-size: 0.8em;
|
|
|
|
|
|
color: #6c757d;
|
|
|
|
|
|
margin-top: 5px;
|
|
|
|
|
|
margin-right: 10px;
|
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.input-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#question-input {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
border: 2px solid #dee2e6;
|
|
|
|
|
|
border-radius: 25px;
|
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
|
outline: none;
|
|
|
|
|
|
transition: border-color 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#question-input:focus {
|
|
|
|
|
|
border-color: #007bff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#send-btn {
|
|
|
|
|
|
padding: 12px 24px;
|
|
|
|
|
|
background-color: #ff6b35;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 25px;
|
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: background-color 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#send-btn:hover {
|
|
|
|
|
|
background-color: #ee5a24;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.command-buttons {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
gap: 10px;
|
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cmd-btn {
|
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
|
background-color: #28a745;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
border-radius: 15px;
|
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
transition: background-color 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cmd-btn:hover {
|
|
|
|
|
|
background-color: #218838;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
z-index: 1000;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
background-color: rgba(0,0,0,0.5);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.modal-content {
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
margin: 15% auto;
|
|
|
|
|
|
padding: 30px;
|
|
|
|
|
|
border: 1px solid #888;
|
|
|
|
|
|
border-radius: 10px;
|
|
|
|
|
|
width: 80%;
|
|
|
|
|
|
max-width: 500px;
|
|
|
|
|
|
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.close {
|
|
|
|
|
|
color: #aaa;
|
|
|
|
|
|
float: right;
|
|
|
|
|
|
font-size: 28px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.close:hover {
|
|
|
|
|
|
color: black;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.form-group {
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
label {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
input[type="text"], textarea {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
border: 1px solid #dee2e6;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
textarea {
|
|
|
|
|
|
height: 100px;
|
|
|
|
|
|
resize: vertical;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-primary {
|
|
|
|
|
|
background-color: #007bff;
|
|
|
|
|
|
color: white;
|
|
|
|
|
|
border: none;
|
|
|
|
|
|
padding: 10px 20px;
|
|
|
|
|
|
border-radius: 5px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.btn-primary:hover {
|
|
|
|
|
|
background-color: #0056b3;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.game-over {
|
|
|
|
|
|
background-color: #d4edda;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
border: 2px solid #c3e6cb;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
color: #155724;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.stats-section {
|
|
|
|
|
|
background-color: #d1ecf1;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
border-left: 4px solid #17a2b8;
|
|
|
|
|
|
margin-bottom: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 滚动条样式 */
|
|
|
|
|
|
.chat-history::-webkit-scrollbar {
|
|
|
|
|
|
width: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-history::-webkit-scrollbar-track {
|
|
|
|
|
|
background: #f1f1f1;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-history::-webkit-scrollbar-thumb {
|
|
|
|
|
|
background: #888;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-history::-webkit-scrollbar-thumb:hover {
|
|
|
|
|
|
background: #555;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@media (max-width: 600px) {
|
|
|
|
|
|
.container {
|
|
|
|
|
|
padding: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.story-content {
|
|
|
|
|
|
font-size: 1em;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chat-history {
|
|
|
|
|
|
height: 200px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.command-buttons {
|
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.cmd-btn {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.message-content {
|
|
|
|
|
|
max-width: 90%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
<h1>🐢 海龟汤游戏 🐢</h1>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="game-info">
|
|
|
|
|
|
<p>🔍 海龟汤是一种情境猜谜游戏,我会给出一个奇怪的情境,你可以通过提问来猜测故事的真相。</p>
|
|
|
|
|
|
<p>💬 我只会回答'是'、'否'或'无关'。</p>
|
|
|
|
|
|
<p>📋 输入'答案'查看完整故事,输入'新题'生成新的题目,输入'自定义'创建自己的题目,</p>
|
|
|
|
|
|
<p>📋 输入'提示'获取线索,输入'猜测 内容'尝试猜测答案,输入'结束'退出游戏。</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="stats-section">
|
|
|
|
|
|
<div id="stats"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="story-section">
|
|
|
|
|
|
<div class="story-title">🥣 汤面</div>
|
|
|
|
|
|
<div class="story-content" id="story-content">请选择游戏模式开始游戏</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div id="game-over" class="game-over" style="display: none;">
|
|
|
|
|
|
<h3 id="game-over-message"></h3>
|
|
|
|
|
|
<p id="solution-display"></p>
|
|
|
|
|
|
<button class="cmd-btn" onclick="startNewGame()">开始新游戏</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="command-buttons">
|
|
|
|
|
|
<button class="cmd-btn" onclick="selectMode(1)">AI生成题目</button>
|
|
|
|
|
|
<button class="cmd-btn" onclick="selectMode(2)">自定义题目</button>
|
|
|
|
|
|
<button class="cmd-btn" onclick="showHint()">获取提示</button>
|
|
|
|
|
|
<button class="cmd-btn" onclick="showSolution()">查看答案</button>
|
|
|
|
|
|
<button class="cmd-btn" onclick="startNewGame()">新题</button>
|
|
|
|
|
|
<button class="cmd-btn" onclick="endGame()">结束游戏</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="chat-section">
|
|
|
|
|
|
<div class="chat-history" id="chat-history"></div>
|
|
|
|
|
|
<div class="input-section">
|
2026-01-08 19:36:33 +08:00
|
|
|
|
<input type="text" id="question-input" placeholder="请输入问题或命令...(输入'猜测 内容'或'我猜 内容'来尝试猜测答案)">
|
2026-01-07 17:08:47 +08:00
|
|
|
|
<button id="send-btn" onclick="sendMessage()">发送</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 自定义题目模态框 -->
|
|
|
|
|
|
<div id="custom-modal" class="modal">
|
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
|
<span class="close" onclick="closeModal()">×</span>
|
|
|
|
|
|
<h2>创建自定义题目</h2>
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="custom-story">汤面(奇怪的情境)</label>
|
|
|
|
|
|
<textarea id="custom-story" placeholder="请输入汤面..."></textarea>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-group">
|
|
|
|
|
|
<label for="custom-solution">汤底(完整解释)</label>
|
|
|
|
|
|
<textarea id="custom-solution" placeholder="请输入汤底..."></textarea>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button class="btn-primary" onclick="saveCustomStory()">保存题目</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
|
// 游戏状态
|
|
|
|
|
|
let gameState = {
|
|
|
|
|
|
story: null,
|
|
|
|
|
|
solution: null,
|
|
|
|
|
|
gameOver: false,
|
|
|
|
|
|
hints: [],
|
|
|
|
|
|
questions: [],
|
|
|
|
|
|
guesses: [],
|
|
|
|
|
|
startTime: null,
|
|
|
|
|
|
endTime: null,
|
|
|
|
|
|
result: "未完成",
|
|
|
|
|
|
isCustom: false
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 预设题目列表
|
|
|
|
|
|
const presetStories = [
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个男人走进一家餐厅,点了一份海龟汤。喝了一口后,他放下汤匙,默默地付了钱离开了餐厅。",
|
|
|
|
|
|
solution: "这个男人曾经遭遇海难,和同伴被困在荒岛上。为了生存,同伴们煮了海龟汤给他喝,并告诉他这是他妻子的肉。获救后,他在餐厅喝到真正的海龟汤,才知道自己被骗了,同伴们牺牲了自己来救他。",
|
|
|
|
|
|
keywords: ["海难", "荒岛", "同伴", "牺牲", "被骗"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个女人独居在公寓里,一天晚上她熄灭了灯准备睡觉。第二天早上,她打开报纸,看到一条消息后跳楼自杀了。",
|
|
|
|
|
|
solution: "这个女人是灯塔管理员,她熄灭的不是自己家的灯,而是灯塔的灯。结果导致一艘船在夜间触礁沉没,船上所有人都遇难了。看到报纸上的这个消息后,她因为内疚而自杀了。",
|
|
|
|
|
|
keywords: ["灯塔管理员", "灯塔", "船", "触礁", "遇难"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人在雨中行走,没有带任何雨具,头发却一点也没湿。",
|
|
|
|
|
|
solution: "这个人是光头,没有头发,所以即使在雨中行走,头发也不会湿。",
|
|
|
|
|
|
keywords: ["光头", "没有头发"]
|
2026-01-08 19:36:33 +08:00
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个女人打开冰箱,看到里面有一瓶牛奶,她喝了一口,然后马上把牛奶扔掉了。",
|
|
|
|
|
|
solution: "这瓶牛奶已经过期了,女人喝了一口发现味道不对,所以马上把它扔掉了。",
|
|
|
|
|
|
keywords: ["牛奶", "过期", "味道不对"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人走进电梯,按下了10楼的按钮。当电梯到达5楼时,他开始疯狂地按10楼的按钮,但电梯还是继续上升。",
|
|
|
|
|
|
solution: "这个人在电梯里遭遇了火灾,他想尽快到达10楼逃生,但电梯已经被火灾影响,开始自动向顶层运行。",
|
|
|
|
|
|
keywords: ["电梯", "火灾", "逃生", "顶层"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人在沙漠中行走,他看到远处有一个瓶子,他跑过去捡起瓶子,打开瓶盖后,里面没有水,他却很高兴。",
|
|
|
|
|
|
solution: "这个瓶子里有一张藏宝图,所以即使没有水,他也很高兴。",
|
|
|
|
|
|
keywords: ["沙漠", "瓶子", "藏宝图"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人在房间里看书,突然灯灭了,他放下书,走到窗前,看到窗外有人在跳舞。",
|
|
|
|
|
|
solution: "房间里的灯灭了是因为停电了,而窗外有人在跳舞是因为他们在庆祝某个节日,使用了篝火照明。",
|
|
|
|
|
|
keywords: ["停电", "窗外", "跳舞", "篝火"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人走进一家商店,买了一包口香糖,付了钱后,他没有打开口香糖,而是直接离开了商店。",
|
|
|
|
|
|
solution: "这个人是为了找零才买的口香糖,他需要一些零钱来乘坐公共汽车。",
|
|
|
|
|
|
keywords: ["口香糖", "找零", "公共汽车"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个女人在午夜接到一个电话,电话那头没有人说话,只有沉重的呼吸声。她挂断电话后,听到门外有脚步声,于是她拨打了报警电话。警察到达后,却发现门外什么人都没有。",
|
|
|
|
|
|
solution: "打电话的人是这个女人的邻居,他在监视她。当女人挂断电话后,邻居正准备敲门,但听到她拨打报警电话,就迅速离开了。警察到达时,邻居已经跑远了。",
|
|
|
|
|
|
keywords: ["午夜电话", "脚步声", "邻居", "监视", "报警"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个男人在森林里迷路了,他找到了一个小屋,里面有一张桌子和一把椅子,桌子上放着一个手电筒和一张纸条,纸条上写着'不要打开手电筒'。男人打开了手电筒,然后他就死了。",
|
|
|
|
|
|
solution: "这个小屋是一个猎人的陷阱,手电筒是触发陷阱的开关。当男人打开手电筒时,触发了机关,导致小屋倒塌,男人被压死了。",
|
|
|
|
|
|
keywords: ["森林迷路", "小屋", "手电筒", "陷阱", "机关"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个女人在浴缸里洗澡,突然她听到门外有钥匙转动的声音。她从浴缸里出来,走到门口,透过猫眼看到一个陌生男人正在开门。她吓得赶紧跑回卧室,锁上门。过了一会儿,她听到客厅里有脚步声,然后脚步声消失了。她打开卧室门,发现客厅里没有人,但她的钱包不见了。",
|
|
|
|
|
|
solution: "这个陌生男人是一个小偷,他用万能钥匙打开了门。当他听到女人的声音时,他躲在了客厅的窗帘后面。女人跑回卧室后,他趁机偷走了钱包,然后从窗户逃跑了。",
|
|
|
|
|
|
keywords: ["浴缸洗澡", "陌生男人", "万能钥匙", "窗帘", "窗户逃跑"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个人在电影院看电影,当电影放到一半时,他突然站起来,走出电影院,然后自杀了。",
|
|
|
|
|
|
solution: "这个人是一个凶手,他杀了人后,将尸体藏在了电影院的座椅下面。当电影放到一半时,他看到银幕上显示的是他杀人的场景,他以为自己的罪行被发现了,所以选择了自杀。",
|
|
|
|
|
|
keywords: ["电影院", "尸体", "座椅", "杀人场景", "罪行暴露"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个女人在晚上开车回家,她看到路边有一个穿着白色衣服的女人在挥手。她停下来,让那个女人上车。那个女人坐在后座上,一句话也不说。当女人开到家门口时,她回头一看,发现后座上没有人,只有一件白色的衣服。",
|
|
|
|
|
|
solution: "那个挥手的女人是一个幽灵,她在车祸中丧生,一直徘徊在事故地点。当女人让她上车时,她的灵魂上了车,但当车开到安全的地方时,她的灵魂就消失了。",
|
|
|
|
|
|
keywords: ["晚上开车", "白色衣服", "幽灵", "车祸", "灵魂"]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
story: "一个男人在酒店房间里睡觉,突然他被一声巨响惊醒。他打开灯,发现房间里什么都没有。他走到窗前,看到楼下有一个人躺在地上,已经死了。第二天早上,警察来到酒店,询问他昨晚是否听到了什么声音。他告诉警察他听到了一声巨响,然后看到楼下有人死了。警察听完后,立即逮捕了他。",
|
|
|
|
|
|
solution: "这个男人是一个杀手,他用狙击枪杀死了楼下的人。当他开枪时,房间的窗户被枪声震得发出巨响。他走到窗前查看是否命中目标,却被对面建筑的监控摄像头拍了下来。警察通过监控录像找到了他。",
|
|
|
|
|
|
keywords: ["酒店房间", "巨响", "狙击枪", "监控摄像头", "杀手"]
|
2026-01-07 17:08:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化游戏
|
|
|
|
|
|
function initGame() {
|
|
|
|
|
|
loadGameStats();
|
|
|
|
|
|
updateStats();
|
|
|
|
|
|
addMessage("系统", "欢迎来到海龟汤游戏!请选择游戏模式开始游戏。");
|
2026-01-08 19:36:33 +08:00
|
|
|
|
|
|
|
|
|
|
// 添加回车键监听事件
|
|
|
|
|
|
const inputElement = document.getElementById('question-input');
|
|
|
|
|
|
inputElement.addEventListener('keypress', function(e) {
|
|
|
|
|
|
if (e.key === 'Enter') {
|
|
|
|
|
|
sendMessage();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2026-01-07 17:08:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 选择游戏模式
|
|
|
|
|
|
function selectMode(mode) {
|
|
|
|
|
|
if (mode === 1) {
|
|
|
|
|
|
// 生成AI题目(使用预设题目)
|
|
|
|
|
|
generateStory();
|
|
|
|
|
|
} else if (mode === 2) {
|
|
|
|
|
|
// 显示自定义题目模态框
|
|
|
|
|
|
openModal();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成题目
|
|
|
|
|
|
function generateStory() {
|
|
|
|
|
|
// 随机选择一个预设题目
|
|
|
|
|
|
const randomIndex = Math.floor(Math.random() * presetStories.length);
|
|
|
|
|
|
const selectedStory = presetStories[randomIndex];
|
|
|
|
|
|
|
|
|
|
|
|
gameState.story = selectedStory.story;
|
|
|
|
|
|
gameState.solution = selectedStory.solution;
|
|
|
|
|
|
gameState.isCustom = false;
|
|
|
|
|
|
gameState.gameOver = false;
|
|
|
|
|
|
gameState.startTime = new Date().toISOString();
|
|
|
|
|
|
gameState.endTime = null;
|
|
|
|
|
|
gameState.result = "未完成";
|
|
|
|
|
|
gameState.hints = [];
|
|
|
|
|
|
gameState.questions = [];
|
|
|
|
|
|
gameState.guesses = [];
|
|
|
|
|
|
|
|
|
|
|
|
// 更新界面
|
|
|
|
|
|
document.getElementById('story-content').textContent = gameState.story;
|
|
|
|
|
|
document.getElementById('game-over').style.display = 'none';
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", `汤面:${gameState.story}`);
|
|
|
|
|
|
addMessage("系统", "你可以通过提问来猜测故事的真相,游戏中我只会回答'是'、'否'或'无关'。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 打开自定义题目模态框
|
|
|
|
|
|
function openModal() {
|
|
|
|
|
|
document.getElementById('custom-modal').style.display = 'block';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭自定义题目模态框
|
|
|
|
|
|
function closeModal() {
|
|
|
|
|
|
document.getElementById('custom-modal').style.display = 'none';
|
|
|
|
|
|
// 清空表单
|
|
|
|
|
|
document.getElementById('custom-story').value = '';
|
|
|
|
|
|
document.getElementById('custom-solution').value = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存自定义题目
|
|
|
|
|
|
function saveCustomStory() {
|
|
|
|
|
|
const customStory = document.getElementById('custom-story').value.trim();
|
|
|
|
|
|
const customSolution = document.getElementById('custom-solution').value.trim();
|
|
|
|
|
|
|
|
|
|
|
|
if (!customStory || !customSolution) {
|
|
|
|
|
|
alert("汤面和汤底不能为空!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gameState.story = customStory;
|
|
|
|
|
|
gameState.solution = customSolution;
|
|
|
|
|
|
gameState.isCustom = true;
|
|
|
|
|
|
gameState.gameOver = false;
|
|
|
|
|
|
gameState.startTime = new Date().toISOString();
|
|
|
|
|
|
gameState.endTime = null;
|
|
|
|
|
|
gameState.result = "未完成";
|
|
|
|
|
|
gameState.hints = [];
|
|
|
|
|
|
gameState.questions = [];
|
|
|
|
|
|
gameState.guesses = [];
|
|
|
|
|
|
|
|
|
|
|
|
// 更新界面
|
|
|
|
|
|
document.getElementById('story-content').textContent = gameState.story;
|
|
|
|
|
|
document.getElementById('game-over').style.display = 'none';
|
|
|
|
|
|
closeModal();
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", `汤面:${gameState.story}`);
|
|
|
|
|
|
addMessage("系统", "自定义题目创建成功!你可以通过提问来猜测故事的真相。");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发送消息
|
|
|
|
|
|
function sendMessage() {
|
|
|
|
|
|
const input = document.getElementById('question-input');
|
|
|
|
|
|
const message = input.value.trim();
|
|
|
|
|
|
|
|
|
|
|
|
if (!message) return;
|
|
|
|
|
|
|
|
|
|
|
|
// 清空输入框
|
|
|
|
|
|
input.value = '';
|
|
|
|
|
|
|
|
|
|
|
|
if (!gameState.story) {
|
|
|
|
|
|
addMessage("系统", "请先选择游戏模式开始游戏!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (gameState.gameOver) {
|
|
|
|
|
|
addMessage("系统", "游戏已结束,请开始新游戏!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("我", message);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理命令
|
|
|
|
|
|
const lowerMessage = message.toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.includes("答案") || lowerMessage.includes("查看答案")) {
|
|
|
|
|
|
showSolution();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.includes("结束") || lowerMessage.includes("退出")) {
|
|
|
|
|
|
endGame();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.includes("新题") || lowerMessage.includes("重新开始") || lowerMessage.includes("换一个")) {
|
|
|
|
|
|
startNewGame();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.includes("自定义") || lowerMessage.includes("创建题目")) {
|
|
|
|
|
|
openModal();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.includes("提示") || lowerMessage.includes("线索")) {
|
|
|
|
|
|
showHint();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (lowerMessage.startsWith("猜测") || lowerMessage.startsWith("我猜")) {
|
|
|
|
|
|
const guess = message.substring(2).trim();
|
|
|
|
|
|
handleGuess(guess);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理普通问题
|
|
|
|
|
|
handleQuestion(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理问题
|
|
|
|
|
|
function handleQuestion(question) {
|
|
|
|
|
|
// 记录问题
|
|
|
|
|
|
gameState.questions.push({
|
|
|
|
|
|
question: question,
|
|
|
|
|
|
timestamp: new Date().toISOString()
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 简单的回答逻辑
|
|
|
|
|
|
let answer = "无关";
|
2026-01-08 19:36:33 +08:00
|
|
|
|
const lowerQuestion = question.toLowerCase();
|
|
|
|
|
|
const lowerSolution = gameState.solution.toLowerCase();
|
2026-01-07 17:08:47 +08:00
|
|
|
|
|
2026-01-08 19:36:33 +08:00
|
|
|
|
// 专门处理与死亡相关的问题
|
|
|
|
|
|
const deathKeywords = ["死", "死亡", "遇难", "杀", "自杀", "丧生", "去世", "毙命", "丧命", "暴毙"];
|
|
|
|
|
|
const isDeathQuestion = deathKeywords.some(keyword => lowerQuestion.includes(keyword));
|
|
|
|
|
|
const hasDeathInSolution = deathKeywords.some(keyword => lowerSolution.includes(keyword));
|
|
|
|
|
|
|
|
|
|
|
|
if (isDeathQuestion) {
|
|
|
|
|
|
if (hasDeathInSolution) {
|
|
|
|
|
|
// 检查问题是否包含否定词
|
|
|
|
|
|
if (lowerQuestion.includes("不") || lowerQuestion.includes("没") || lowerQuestion.includes("无")) {
|
|
|
|
|
|
answer = "否";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
answer = "是";
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 检查问题是否包含否定词
|
|
|
|
|
|
if (lowerQuestion.includes("不") || lowerQuestion.includes("没") || lowerQuestion.includes("无")) {
|
|
|
|
|
|
answer = "是";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
answer = "否";
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 原有逻辑,处理其他问题
|
|
|
|
|
|
if (lowerSolution.includes(lowerQuestion)) {
|
|
|
|
|
|
answer = "是";
|
|
|
|
|
|
} else if (lowerSolution.includes(lowerQuestion.replace("不", "")) ||
|
|
|
|
|
|
lowerSolution.includes(lowerQuestion.replace("不是", "是"))) {
|
|
|
|
|
|
answer = "否";
|
|
|
|
|
|
}
|
2026-01-07 17:08:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 记录回答
|
|
|
|
|
|
gameState.questions[gameState.questions.length - 1].answer = answer;
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("AI", answer);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 处理猜测
|
|
|
|
|
|
function handleGuess(guess) {
|
|
|
|
|
|
// 记录猜测
|
|
|
|
|
|
gameState.guesses.push({
|
|
|
|
|
|
guess: guess,
|
|
|
|
|
|
timestamp: new Date().toISOString()
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 简单的猜测评估逻辑
|
|
|
|
|
|
const lowerGuess = guess.toLowerCase();
|
|
|
|
|
|
const lowerSolution = gameState.solution.toLowerCase();
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否包含所有关键词
|
|
|
|
|
|
const keywords = getKeywords(gameState.solution);
|
|
|
|
|
|
let matchCount = 0;
|
|
|
|
|
|
|
|
|
|
|
|
keywords.forEach(keyword => {
|
|
|
|
|
|
if (lowerGuess.includes(keyword)) {
|
|
|
|
|
|
matchCount++;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 评估结果
|
|
|
|
|
|
if (matchCount >= keywords.length * 0.7) {
|
|
|
|
|
|
// 完全正确
|
|
|
|
|
|
addMessage("系统", "🎉 恭喜你!你的猜测完全正确!");
|
|
|
|
|
|
showSolution();
|
|
|
|
|
|
} else if (matchCount >= keywords.length * 0.3) {
|
|
|
|
|
|
// 部分正确
|
|
|
|
|
|
addMessage("系统", "👍 你的猜测部分正确,但还有一些关键信息没有猜出来。");
|
|
|
|
|
|
addMessage("系统", "🔍 继续提问,获取更多线索吧!");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 错误
|
|
|
|
|
|
addMessage("系统", "👎 你的猜测不正确,再试一次吧!");
|
|
|
|
|
|
addMessage("系统", "🔍 继续提问,获取更多线索吧!");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 提取关键词
|
|
|
|
|
|
function getKeywords(text) {
|
|
|
|
|
|
// 简单的关键词提取(移除常见停用词,取名词)
|
|
|
|
|
|
const stopWords = ['的', '了', '和', '是', '在', '有', '我', '你', '他', '她', '它', '们', '这', '那', '个', '件', '条', '只', '对', '于', '就', '也', '都', '但', '而', '所以', '因为', '如果', '虽然', '但是', '然而', '不过'];
|
|
|
|
|
|
|
|
|
|
|
|
// 简单分词(这里使用空格分词,实际应用中可以使用更复杂的分词方法)
|
|
|
|
|
|
let words = text.split(/[\s,。?!,.;?!]+/).filter(word => word.length > 1);
|
|
|
|
|
|
|
|
|
|
|
|
// 移除停用词
|
|
|
|
|
|
words = words.filter(word => !stopWords.includes(word));
|
|
|
|
|
|
|
|
|
|
|
|
// 返回前10个关键词
|
|
|
|
|
|
return words.slice(0, 10);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示提示
|
|
|
|
|
|
function showHint() {
|
|
|
|
|
|
if (!gameState.solution) {
|
|
|
|
|
|
addMessage("系统", "请先选择游戏模式开始游戏!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (gameState.gameOver) {
|
|
|
|
|
|
addMessage("系统", "游戏已结束,无法获取提示!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 生成提示(基于汤底的部分内容)
|
|
|
|
|
|
let hint = "";
|
|
|
|
|
|
const solutionWords = gameState.solution.split(/\s+/);
|
|
|
|
|
|
|
|
|
|
|
|
if (gameState.hints.length === 0) {
|
|
|
|
|
|
// 第一个提示:提供人物信息
|
|
|
|
|
|
hint = "提示1:故事中涉及到的主要人物是" + getMainCharacter(gameState.solution) + "。";
|
|
|
|
|
|
} else if (gameState.hints.length === 1) {
|
|
|
|
|
|
// 第二个提示:提供事件发生的地点
|
|
|
|
|
|
hint = "提示2:故事发生在" + getLocation(gameState.solution) + "。";
|
|
|
|
|
|
} else if (gameState.hints.length === 2) {
|
|
|
|
|
|
// 第三个提示:提供关键物品
|
|
|
|
|
|
hint = "提示3:故事中的关键物品是" + getKeyItem(gameState.solution) + "。";
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 没有更多提示
|
|
|
|
|
|
hint = "没有更多提示了,请尝试自己思考!";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!gameState.hints.includes(hint)) {
|
|
|
|
|
|
gameState.hints.push(hint);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", hint);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:获取主要人物
|
|
|
|
|
|
function getMainCharacter(solution) {
|
|
|
|
|
|
// 简单的人物提取,实际应用中可以更复杂
|
|
|
|
|
|
const possibleCharacters = ["男人", "女人", "男孩", "女孩", "老人", "孩子", "他", "她", "他们", "她们"];
|
|
|
|
|
|
|
|
|
|
|
|
for (let character of possibleCharacters) {
|
|
|
|
|
|
if (solution.includes(character)) {
|
|
|
|
|
|
return character;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return "一个人";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:获取地点
|
|
|
|
|
|
function getLocation(solution) {
|
|
|
|
|
|
// 简单的地点提取,实际应用中可以更复杂
|
|
|
|
|
|
const possibleLocations = ["餐厅", "家里", "医院", "海滩", "森林", "办公室", "学校", "公寓", "灯塔"];
|
|
|
|
|
|
|
|
|
|
|
|
for (let location of possibleLocations) {
|
|
|
|
|
|
if (solution.includes(location)) {
|
|
|
|
|
|
return location;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return "某个地方";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 辅助函数:获取关键物品
|
|
|
|
|
|
function getKeyItem(solution) {
|
|
|
|
|
|
// 简单的物品提取,实际应用中可以更复杂
|
|
|
|
|
|
const possibleItems = ["海龟汤", "灯", "雨伞", "报纸", "手机", "钥匙", "汤勺", "笔", "纸"];
|
|
|
|
|
|
|
|
|
|
|
|
for (let item of possibleItems) {
|
|
|
|
|
|
if (solution.includes(item)) {
|
|
|
|
|
|
return item;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return "某个物品";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 显示答案
|
|
|
|
|
|
function showSolution() {
|
|
|
|
|
|
if (!gameState.solution) {
|
|
|
|
|
|
addMessage("系统", "请先选择游戏模式开始游戏!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
gameState.gameOver = true;
|
|
|
|
|
|
gameState.endTime = new Date().toISOString();
|
|
|
|
|
|
gameState.result = "查看答案";
|
|
|
|
|
|
|
|
|
|
|
|
// 显示答案
|
|
|
|
|
|
const gameOverMessage = document.getElementById('game-over-message');
|
|
|
|
|
|
const solutionDisplay = document.getElementById('solution-display');
|
|
|
|
|
|
|
|
|
|
|
|
gameOverMessage.textContent = "游戏结束!汤底如下:";
|
|
|
|
|
|
solutionDisplay.innerHTML = `<strong>汤底:</strong>${gameState.solution}`;
|
|
|
|
|
|
document.getElementById('game-over').style.display = 'block';
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", `汤底:${gameState.solution}`);
|
|
|
|
|
|
|
|
|
|
|
|
// 保存游戏数据
|
|
|
|
|
|
saveGameSession();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 结束游戏
|
|
|
|
|
|
function endGame() {
|
|
|
|
|
|
gameState.gameOver = true;
|
|
|
|
|
|
gameState.endTime = new Date().toISOString();
|
|
|
|
|
|
gameState.result = "中途退出";
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", "游戏已结束,感谢参与!");
|
|
|
|
|
|
|
|
|
|
|
|
// 保存游戏数据
|
|
|
|
|
|
saveGameSession();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 开始新游戏
|
|
|
|
|
|
function startNewGame() {
|
|
|
|
|
|
// 清空聊天记录
|
|
|
|
|
|
document.getElementById('chat-history').innerHTML = '';
|
|
|
|
|
|
|
|
|
|
|
|
addMessage("系统", "正在准备新游戏...");
|
|
|
|
|
|
|
|
|
|
|
|
// 生成新题目
|
|
|
|
|
|
generateStory();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存游戏会话
|
|
|
|
|
|
function saveGameSession() {
|
|
|
|
|
|
// 获取现有游戏数据
|
|
|
|
|
|
let gameData = JSON.parse(localStorage.getItem('turtleSoupData')) || {
|
|
|
|
|
|
games: [],
|
|
|
|
|
|
statistics: {
|
|
|
|
|
|
totalGames: 0,
|
|
|
|
|
|
totalQuestions: 0,
|
|
|
|
|
|
winRate: 0
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 添加当前游戏数据
|
|
|
|
|
|
gameData.games.push({
|
|
|
|
|
|
...gameState,
|
|
|
|
|
|
sessionId: `game_${Date.now()}`
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 更新统计信息
|
|
|
|
|
|
const totalGames = gameData.games.length;
|
|
|
|
|
|
const wonGames = gameData.games.filter(game => game.result === "胜利" || game.result === "查看答案").length;
|
|
|
|
|
|
const totalQuestions = gameData.games.reduce((sum, game) => sum + game.questions.length, 0);
|
|
|
|
|
|
|
|
|
|
|
|
gameData.statistics = {
|
|
|
|
|
|
totalGames: totalGames,
|
|
|
|
|
|
totalQuestions: totalQuestions,
|
|
|
|
|
|
winRate: wonGames / totalGames
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 保存数据到本地存储
|
|
|
|
|
|
localStorage.setItem('turtleSoupData', JSON.stringify(gameData));
|
|
|
|
|
|
|
|
|
|
|
|
// 更新统计信息显示
|
|
|
|
|
|
updateStats();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载游戏统计信息
|
|
|
|
|
|
function loadGameStats() {
|
|
|
|
|
|
const gameData = JSON.parse(localStorage.getItem('turtleSoupData')) || {
|
|
|
|
|
|
games: [],
|
|
|
|
|
|
statistics: {
|
|
|
|
|
|
totalGames: 0,
|
|
|
|
|
|
totalQuestions: 0,
|
|
|
|
|
|
winRate: 0
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return gameData.statistics;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 更新统计信息显示
|
|
|
|
|
|
function updateStats() {
|
|
|
|
|
|
const stats = loadGameStats();
|
|
|
|
|
|
const statsElement = document.getElementById('stats');
|
|
|
|
|
|
|
|
|
|
|
|
statsElement.innerHTML = `
|
|
|
|
|
|
<p>📊 游戏统计:</p>
|
|
|
|
|
|
<p>总游戏数:${stats.totalGames}</p>
|
|
|
|
|
|
<p>总提问数:${stats.totalQuestions}</p>
|
|
|
|
|
|
<p>完成率:${(stats.winRate * 100).toFixed(1)}%</p>
|
|
|
|
|
|
`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加消息到聊天记录
|
|
|
|
|
|
function addMessage(sender, content) {
|
|
|
|
|
|
const chatHistory = document.getElementById('chat-history');
|
|
|
|
|
|
const messageDiv = document.createElement('div');
|
|
|
|
|
|
messageDiv.className = `message ${sender === "我" ? "user-message" : "bot-message"}`;
|
|
|
|
|
|
|
|
|
|
|
|
const messageContentDiv = document.createElement('div');
|
|
|
|
|
|
messageContentDiv.className = 'message-content';
|
|
|
|
|
|
messageContentDiv.textContent = content;
|
|
|
|
|
|
|
|
|
|
|
|
const messageTimeDiv = document.createElement('div');
|
|
|
|
|
|
messageTimeDiv.className = 'message-time';
|
|
|
|
|
|
messageTimeDiv.textContent = new Date().toLocaleTimeString();
|
|
|
|
|
|
|
|
|
|
|
|
messageDiv.appendChild(messageContentDiv);
|
|
|
|
|
|
messageDiv.appendChild(messageTimeDiv);
|
|
|
|
|
|
chatHistory.appendChild(messageDiv);
|
|
|
|
|
|
|
|
|
|
|
|
// 滚动到底部
|
|
|
|
|
|
chatHistory.scrollTop = chatHistory.scrollHeight;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 键盘事件监听
|
|
|
|
|
|
document.getElementById('question-input').addEventListener('keypress', function(e) {
|
|
|
|
|
|
if (e.key === 'Enter') {
|
|
|
|
|
|
sendMessage();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭模态框(点击外部区域)
|
|
|
|
|
|
window.onclick = function(event) {
|
|
|
|
|
|
const modal = document.getElementById('custom-modal');
|
|
|
|
|
|
if (event.target === modal) {
|
|
|
|
|
|
closeModal();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化游戏
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', initGame);
|
|
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
|
|
|
|
|
</html>
|