Files
RGKT/rg-09112127/html/play/AI数学比大小游戏.html
2025-10-10 19:35:04 +08:00

654 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>