Files
RGKT/rg-09112127/html/play/AI数学比大小游戏.html

654 lines
19 KiB
HTML
Raw Normal View History

2025-10-10 19:44:14 +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>AI数学比大小游戏</title>
<!-- 引入后端集成脚本 -->
<script src="../../js/apiService.js"></script>
<script src="../../js/dataManager.js"></script>
<script src="../../js/userManager.js"></script>
<script src="../../js/accessTracker.js"></script>
<script src="../../js/gameTracker.js"></script>
<script src="../../js/virtualTeacher.js"></script>
<script src="../../js/gameVirtualTeacher.js"></script>
<script src="../../js/aiGameGenerator.js"></script>
<style>
:root {
--primary: #ff9aa2;
--secondary: #ffb7b2;
--accent: #ffdac1;
--correct: #b5ead7;
--wrong: #ff9aa2;
--button: #70a1ff;
--text: #5e5346;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Comic Sans MS", "Marker Felt", "微软雅黑", sans-serif;
background-color: #f9f7f0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-image: radial-gradient(circle, #f5f5f5 10%, transparent 10%);
background-size: 30px 30px;
overflow: hidden;
}
.game-container {
width: 80%;
background-color: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
text-align: center;
position: relative;
overflow: hidden;
border: 5px solid #ffdac1;
}
h1 {
color: #ff6b6b;
margin-bottom: 30px;
font-size: 3rem;
text-shadow: 3px 3px 0 #ffdac1;
letter-spacing: 2px;
}
.game-area {
display: flex;
justify-content: space-around;
margin: 30px 0;
}
.math-card {
width: 45%;
padding: 20px;
background-color: #f0f8ff;
border-radius: 15px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
position: relative;
transition: all 0.3s ease;
}
.math-card:hover,
.math-card.active {
transform: translateY(-5px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
}
.math-card::before {
content: "";
position: absolute;
top: -10px;
left: -10px;
right: -10px;
bottom: -10px;
border: 3px dashed #ffb7b2;
border-radius: 20px;
z-index: -1;
opacity: 0.5;
}
.equation {
font-size: 5rem;
margin: 20px 0;
color: #5e5346;
font-weight: bold;
}
.select-btn {
width: 80px;
height: 80px;
border-radius: 50%;
background-color: var(--button);
color: white;
border: none;
font-size: 2rem;
font-weight: bold;
cursor: pointer;
box-shadow: 0 5px 0 #4a6baf;
transition: all 0.2s ease;
margin-top: 10px;
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
}
.select-btn:hover {
background-color: #5d8eff;
transform: scale(1.05);
}
.select-btn:active {
transform: translateY(5px);
box-shadow: 0 2px 0 #4a6baf;
}
.score-area {
position: absolute;
top: 20px;
right: 20px;
background-color: #fff;
padding: 15px;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
font-size: 1.2rem;
font-weight: bold;
color: var(--text);
}
.progress-bar {
width: 100%;
height: 20px;
background-color: #e0e0e0;
border-radius: 10px;
margin: 20px 0;
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: var(--button);
transition: width 0.3s ease;
border-radius: 10px;
}
.message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
background-color: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
z-index: 100;
text-align: center;
max-width: 80%;
transition: all 0.3s ease;
border: 5px solid;
}
.message.show {
transform: translate(-50%, -50%) scale(1);
}
.message.correct {
border-color: #b5ead7;
background-color: #e8f8f3;
}
.message.wrong {
border-color: #ff9aa2;
background-color: #ffeef0;
}
.message h2 {
font-size: 3rem;
margin-bottom: 15px;
}
.message p {
font-size: 2rem;
margin-bottom: 20px;
}
.message-btn {
padding: 10px 20px;
border-radius: 50px;
border: none;
background-color: var(--button);
color: white;
font-size: 2rem;
cursor: pointer;
transition: all 0.2s ease;
}
.message-btn:hover {
background-color: #5d8eff;
transform: scale(1.05);
}
.confetti {
position: absolute;
width: 15px;
height: 15px;
background-color: var(--primary);
opacity: 0;
z-index: 90;
}
@keyframes confetti-fall {
0% {
transform: translateY(-100vh) rotate(0deg);
opacity: 1;
}
100% {
transform: translateY(100vh) rotate(360deg);
opacity: 0;
}
}
@media (max-width: 600px) {
.game-area {
flex-direction: column;
align-items: center;
}
.math-card {
width: 90%;
margin-bottom: 20px;
}
h1 {
font-size: 2rem;
}
.equation {
font-size: 3rem;
}
}
</style>
</head>
<body>
<div class="game-container">
<div class="score-area">
<div>得分: <span id="score">0</span></div>
<div>进度: <span id="progress">0</span>/<span id="total">5</span></div>
</div>
<h1>AI数学比大小游戏</h1>
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<div class="game-area">
<div class="math-card" id="leftCard">
<div class="equation" id="leftEquation">准备中...</div>
<button class="select-btn" id="leftBtn">选择</button>
</div>
<div class="math-card" id="rightCard">
<div class="equation" id="rightEquation">准备中...</div>
<button class="select-btn" id="rightBtn">选择</button>
</div>
</div>
</div>
<div class="message" id="message">
<h2 id="messageTitle">标题</h2>
<p id="messageText">内容</p>
<button class="message-btn" id="messageBtn">继续</button>
</div>
<script>
// DOM元素
const leftEquation = document.getElementById("leftEquation");
const rightEquation = document.getElementById("rightEquation");
const leftBtn = document.getElementById("leftBtn");
const rightBtn = document.getElementById("rightBtn");
const message = document.getElementById("message");
const messageTitle = document.getElementById("messageTitle");
const messageText = document.getElementById("messageText");
const messageBtn = document.getElementById("messageBtn");
const scoreElement = document.getElementById("score");
const progressElement = document.getElementById("progress");
const totalElement = document.getElementById("total");
const progressFill = document.getElementById("progressFill");
// 游戏状态
let currentGame = null;
let currentQuestionIndex = 0;
let leftValue = 0;
let rightValue = 0;
let correctAnswer = "";
let score = 0;
let correctCount = 0;
let gameStarted = false;
let gameId = "ai_math_comparison_" + Date.now();
// 初始化AI游戏生成器
async function initAIGame() {
try {
if (!window.aiGameGenerator) {
throw new Error("AI游戏生成器未加载");
}
await window.aiGameGenerator.init();
console.log("✅ AI游戏生成器初始化成功");
// 生成数学比大小游戏
currentGame = window.aiGameGenerator.generatePersonalizedGame(
"math",
"quiz",
5
);
if (currentGame && currentGame.questions.length > 0) {
// 筛选比大小题目
const comparisonQuestions = currentGame.questions.filter(
(q) =>
q.question.includes("__") ||
q.question.includes(">") ||
q.question.includes("<") ||
q.question.includes("=")
);
if (comparisonQuestions.length > 0) {
currentGame.questions = comparisonQuestions.slice(0, 5);
}
totalElement.textContent = currentGame.questions.length;
console.log("🎮 AI数学比大小游戏生成成功:", currentGame);
return true;
} else {
throw new Error("无法生成游戏题目");
}
} catch (error) {
console.error("❌ AI游戏初始化失败:", error);
return false;
}
}
// 显示当前题目
function showCurrentQuestion() {
if (
!currentGame ||
currentQuestionIndex >= currentGame.questions.length
) {
endGame();
return;
}
const question = currentGame.questions[currentQuestionIndex];
// 解析比大小题目
if (question.question.includes("__")) {
// 格式如 "5 __ 3"
const parts = question.question.split("__");
if (parts.length === 2) {
leftValue = parseInt(parts[0].trim());
rightValue = parseInt(parts[1].trim());
leftEquation.textContent = leftValue.toString();
rightEquation.textContent = rightValue.toString();
}
} else {
// 生成随机数字进行比较
leftValue = Math.floor(Math.random() * 10) + 1;
rightValue = Math.floor(Math.random() * 10) + 1;
leftEquation.textContent = leftValue.toString();
rightEquation.textContent = rightValue.toString();
}
// 确定正确答案
if (leftValue > rightValue) {
correctAnswer = "left";
} else if (rightValue > leftValue) {
correctAnswer = "right";
} else {
correctAnswer = "equal";
}
// 更新进度
progressElement.textContent = currentQuestionIndex + 1;
progressFill.style.width = `${
((currentQuestionIndex + 1) / currentGame.questions.length) * 100
}%`;
// 清除卡片样式
document.querySelectorAll(".math-card")[0].className = "math-card";
document.querySelectorAll(".math-card")[1].className = "math-card";
}
// 检查答案
function checkAnswer(selectedSide) {
if (message.classList.contains("show")) return;
let isCorrect = false;
let messageText = "";
// 高亮选中的卡片
document.querySelectorAll(".math-card")[
selectedSide === "left" ? 0 : 1
].className = "math-card active";
if (correctAnswer === "equal") {
isCorrect = true;
messageText = "两边一样大!";
} else if (selectedSide === correctAnswer) {
isCorrect = true;
messageText = `对了!${leftValue} ${
selectedSide === "left" ? ">" : "<"
} ${rightValue}`;
} else {
isCorrect = false;
messageText = `不对哦!${leftValue} ${
correctAnswer === "left" ? ">" : "<"
} ${rightValue}`;
}
// 虚拟老师反馈
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.stopAllSpeech();
setTimeout(() => {
if (isCorrect) {
window.gameVirtualTeacher.recordCorrect();
} else {
window.gameVirtualTeacher.recordIncorrect();
}
}, 300);
}
// 更新分数
if (isCorrect) {
correctCount++;
score += 10;
scoreElement.textContent = score;
}
// 记录游戏数据
if (gameStarted && window.gameTracker) {
if (isCorrect) {
window.gameTracker.recordCorrect(10, {
question: `${leftValue} vs ${rightValue}`,
selected: selectedSide,
correct: correctAnswer,
leftValue: leftValue,
rightValue: rightValue,
questionNumber: currentQuestionIndex + 1,
});
} else {
window.gameTracker.recordIncorrect(0, {
question: `${leftValue} vs ${rightValue}`,
selected: selectedSide,
correct: correctAnswer,
leftValue: leftValue,
rightValue: rightValue,
questionNumber: currentQuestionIndex + 1,
});
}
}
showMessage(isCorrect, messageText);
if (isCorrect) {
createConfetti();
}
}
// 显示消息
function showMessage(isCorrect, text) {
message.className = "message " + (isCorrect ? "correct" : "wrong");
messageTitle.textContent = isCorrect ? "太棒了!" : "再试一次";
messageText.textContent = text;
message.classList.add("show");
}
// 创建彩色纸屑效果
function createConfetti() {
const colors = [
"#FF9AA2",
"#FFB7B2",
"#FFDAC1",
"#E2F0CB",
"#B5EAD7",
"#C7CEEA",
];
for (let i = 0; i < 50; i++) {
const confetti = document.createElement("div");
confetti.className = "confetti";
confetti.style.left = `${Math.random() * 100}%`;
confetti.style.backgroundColor =
colors[Math.floor(Math.random() * colors.length)];
confetti.style.width = `${Math.random() * 10 + 5}px`;
confetti.style.height = `${Math.random() * 10 + 5}px`;
confetti.style.animation = `confetti-fall ${
Math.random() * 2 + 2
}s linear forwards`;
confetti.style.animationDelay = `${Math.random() * 0.5}s`;
document.body.appendChild(confetti);
setTimeout(() => {
confetti.remove();
}, 3000);
}
}
// 下一题
function nextQuestion() {
message.classList.remove("show");
currentQuestionIndex++;
showCurrentQuestion();
}
// 结束游戏
function endGame() {
const successRate = (correctCount / currentGame.questions.length) * 100;
message.className = "message correct";
messageTitle.textContent = "游戏完成!";
messageText.textContent = `恭喜你完成了游戏!\n得分: ${score}\n正确率: ${successRate.toFixed(
1
)}%`;
message.classList.add("show");
// 虚拟老师游戏结束
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.gameEnd();
}
// 记录游戏结果
if (gameStarted && window.gameTracker) {
if (successRate >= 80) {
window.gameTracker.recordWin(score, {
totalQuestions: currentGame.questions.length,
correctCount: correctCount,
successRate: successRate,
});
} else {
window.gameTracker.recordLose(score, {
totalQuestions: currentGame.questions.length,
correctCount: correctCount,
successRate: successRate,
});
}
}
messageBtn.textContent = "重新开始";
messageBtn.onclick = restartGame;
}
// 重新开始游戏
function restartGame() {
currentQuestionIndex = 0;
score = 0;
correctCount = 0;
scoreElement.textContent = "0";
progressElement.textContent = "0";
progressFill.style.width = "0%";
message.classList.remove("show");
messageBtn.textContent = "继续";
messageBtn.onclick = nextQuestion;
showCurrentQuestion();
}
// 事件监听
leftBtn.addEventListener("click", () => checkAnswer("left"));
rightBtn.addEventListener("click", () => checkAnswer("right"));
messageBtn.addEventListener("click", nextQuestion);
// 页面加载完成后初始化
document.addEventListener("DOMContentLoaded", async function () {
// 初始化虚拟老师
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher
.init({
intro:
"欢迎来到AI数学比大小游戏我会帮你学习数字比较准备好了吗",
})
.then(() => {
console.log("🦉 AI数学比大小游戏虚拟老师初始化成功");
})
.catch((error) => {
console.error("❌ 虚拟老师初始化失败:", error);
});
}
// 初始化后端集成
Promise.all([window.userManager.init(), window.dataManager.init()])
.then(async () => {
console.log("后端集成初始化完成");
// 初始化AI游戏
const success = await initAIGame();
if (success) {
// 开始游戏跟踪
if (window.gameTracker) {
window.gameTracker.startGame(gameId, {
gameType: "ai_math_comparison",
difficulty: "adaptive",
});
}
// 虚拟老师游戏开始
if (window.gameVirtualTeacher) {
window.gameVirtualTeacher.gameStart("AI数学比大小游戏");
setTimeout(() => {
window.gameVirtualTeacher.speak(
"欢迎来到AI数学比大小游戏我会帮你学习数字比较准备好了吗"
);
}, 1000);
}
gameStarted = true;
showCurrentQuestion();
} else {
showMessage(false, "游戏初始化失败,请刷新页面重试");
}
})
.catch((error) => {
console.error("后端集成初始化失败:", error);
showMessage(false, "系统初始化失败,请刷新页面重试");
});
});
</script>
</body>
</html>