1698 lines
		
	
	
		
			58 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1698 lines
		
	
	
		
			58 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | ||
|  * AI智能游戏生成器
 | ||
|  * 功能:自动出题、动态难度调整、个性化游戏内容
 | ||
|  */
 | ||
| class AIGameGenerator {
 | ||
|     constructor() {
 | ||
|         this.isInitialized = false;
 | ||
|         this.currentDifficulty = 1; // 1-5级难度
 | ||
|         this.studentProfile = null;
 | ||
|         this.questionBank = new Map();
 | ||
|         this.difficultyHistory = [];
 | ||
|         this.performanceHistory = [];
 | ||
|         
 | ||
|         // 题目类型配置
 | ||
|         this.questionTypes = {
 | ||
|             math: {
 | ||
|                 addition: { min: 1, max: 20, operators: ['+'] },
 | ||
|                 subtraction: { min: 1, max: 20, operators: ['-'] },
 | ||
|                 multiplication: { min: 1, max: 10, operators: ['×'] },
 | ||
|                 comparison: { min: 1, max: 20, operators: ['>', '<', '='] },
 | ||
|                 clock: { min: 1, max: 12, operators: ['hour', 'minute'] }
 | ||
|             },
 | ||
|             language: {
 | ||
|                 pinyin: { min: 1, max: 10, operators: ['声调', '拼音'] },
 | ||
|                 word: { min: 1, max: 20, operators: ['组词', '造句'] },
 | ||
|                 poem: { min: 1, max: 5, operators: ['背诵', '理解'] }
 | ||
|             },
 | ||
|             life: {
 | ||
|                 emotion: { min: 1, max: 8, operators: ['识别', '表达'] },
 | ||
|                 safety: { min: 1, max: 10, operators: ['判断', '选择'] },
 | ||
|                 daily: { min: 1, max: 15, operators: ['分类', '整理'] }
 | ||
|             }
 | ||
|         };
 | ||
|         
 | ||
|         // 难度调整参数
 | ||
|         this.difficultyParams = {
 | ||
|             1: { successRate: 0.9, timeLimit: 30, hints: 3 },
 | ||
|             2: { successRate: 0.8, timeLimit: 25, hints: 2 },
 | ||
|             3: { successRate: 0.7, timeLimit: 20, hints: 1 },
 | ||
|             4: { successRate: 0.6, timeLimit: 15, hints: 0 },
 | ||
|             5: { successRate: 0.5, timeLimit: 10, hints: 0 }
 | ||
|         };
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 初始化AI游戏生成器
 | ||
|      */
 | ||
|     async init() {
 | ||
|         try {
 | ||
|             console.log('🤖 AI游戏生成器初始化中...');
 | ||
|             
 | ||
|             // 加载题目库
 | ||
|             await this.loadQuestionBank();
 | ||
|             
 | ||
|             // 加载学生档案
 | ||
|             await this.loadStudentProfile();
 | ||
|             
 | ||
|             this.isInitialized = true;
 | ||
|             console.log('✅ AI游戏生成器初始化完成');
 | ||
|             
 | ||
|             return true;
 | ||
|         } catch (error) {
 | ||
|             console.error('❌ AI游戏生成器初始化失败:', error);
 | ||
|             return false;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 加载学生档案
 | ||
|      */
 | ||
|     async loadStudentProfile() {
 | ||
|         try {
 | ||
|             // 从后端获取学生数据
 | ||
|             if (window.apiService) {
 | ||
|                 const userData = window.userManager?.getCurrentUser();
 | ||
|                 if (userData) {
 | ||
|                     const stats = await window.apiService.getStudentStats(userData.id, 30);
 | ||
|                     this.studentProfile = {
 | ||
|                         id: userData.id,
 | ||
|                         name: userData.name,
 | ||
|                         grade: userData.grade || 2,
 | ||
|                         strengths: stats.strengths || [],
 | ||
|                         weaknesses: stats.weaknesses || [],
 | ||
|                         learningStyle: stats.learningStyle || 'visual',
 | ||
|                         currentLevel: stats.currentLevel || 1,
 | ||
|                         totalQuestions: stats.totalQuestions || 0,
 | ||
|                         correctRate: stats.correctRate || 0.7
 | ||
|                     };
 | ||
|                 }
 | ||
|             }
 | ||
|             
 | ||
|             // 如果没有后端数据,使用默认配置
 | ||
|             if (!this.studentProfile) {
 | ||
|                 this.studentProfile = {
 | ||
|                     id: 'default',
 | ||
|                     name: '学生',
 | ||
|                     grade: 2,
 | ||
|                     strengths: ['数学'],
 | ||
|                     weaknesses: ['语文'],
 | ||
|                     learningStyle: 'visual',
 | ||
|                     currentLevel: 1,
 | ||
|                     totalQuestions: 0,
 | ||
|                     correctRate: 0.7
 | ||
|                 };
 | ||
|             }
 | ||
|             
 | ||
|             console.log('📊 学生档案加载完成:', this.studentProfile);
 | ||
|         } catch (error) {
 | ||
|             console.error('❌ 加载学生档案失败:', error);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 加载题目库
 | ||
|      */
 | ||
|     async loadQuestionBank() {
 | ||
|         try {
 | ||
|             const response = await fetch('data/questionBank.json');
 | ||
|             if (!response.ok) {
 | ||
|                 throw new Error(`HTTP error! status: ${response.status}`);
 | ||
|             }
 | ||
|             const questionBankData = await response.json();
 | ||
|             
 | ||
|             // 将JSON数据转换为Map格式
 | ||
|             for (const [subject, types] of Object.entries(questionBankData)) {
 | ||
|                 this.questionBank.set(subject, types);
 | ||
|             }
 | ||
|             
 | ||
|             console.log('📚 题目库加载完成:', this.questionBank);
 | ||
|         } catch (error) {
 | ||
|             console.error('❌ 加载题目库失败:', error);
 | ||
|             // 如果加载失败,使用默认题目库
 | ||
|             await this.initializeDefaultQuestionBank();
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 初始化默认题目库(备用)
 | ||
|      */
 | ||
|     async initializeDefaultQuestionBank() {
 | ||
|         // 数学题目库
 | ||
|         this.questionBank.set('math', {
 | ||
|             addition: [
 | ||
|                 { question: "2 + 3 = ?", options: ["4", "5", "6", "7"], correct: 1, difficulty: 1 },
 | ||
|                 { question: "7 + 8 = ?", options: ["14", "15", "16", "17"], correct: 1, difficulty: 2 }
 | ||
|             ],
 | ||
|             subtraction: [
 | ||
|                 { question: "8 - 3 = ?", options: ["4", "5", "6", "7"], correct: 1, difficulty: 1 },
 | ||
|                 { question: "15 - 7 = ?", options: ["7", "8", "9", "10"], correct: 1, difficulty: 2 }
 | ||
|             ]
 | ||
|         });
 | ||
| 
 | ||
|         // 语文题目库
 | ||
|         this.questionBank.set('language', {
 | ||
|             pinyin: [
 | ||
|                 { question: "'猫'的拼音是?", options: ["māo", "máo", "mǎo", "mào"], correct: 0, difficulty: 1 }
 | ||
|             ],
 | ||
|             word: [
 | ||
|                 { question: "用'美丽'组词", options: ["美丽的花", "美丽的人", "美丽的风景", "以上都对"], correct: 3, difficulty: 2 }
 | ||
|             ]
 | ||
|         });
 | ||
| 
 | ||
|         // 生活题目库
 | ||
|         this.questionBank.set('life', {
 | ||
|             emotion: [
 | ||
|                 { question: "看到好吃的食物,应该是什么表情?", options: ["😊", "😢", "😠", "😴"], correct: 0, difficulty: 1 }
 | ||
|             ],
 | ||
|             safety: [
 | ||
|                 { question: "过马路时应该?", options: ["看红绿灯", "直接跑过去", "闭着眼睛", "听音乐"], correct: 0, difficulty: 1 }
 | ||
|             ]
 | ||
|         });
 | ||
| 
 | ||
|         console.log('📚 默认题目库初始化完成');
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 生成个性化游戏
 | ||
|      */
 | ||
|     generatePersonalizedGame(subject = 'math', gameType = 'quiz', questionCount = 5) {
 | ||
|         if (!this.isInitialized) {
 | ||
|             console.error('❌ AI游戏生成器未初始化');
 | ||
|             return null;
 | ||
|         }
 | ||
| 
 | ||
|         console.log(`🎮 生成个性化游戏: ${subject} - ${gameType}`);
 | ||
| 
 | ||
|         const gameConfig = {
 | ||
|             id: this.generateGameId(),
 | ||
|             subject: subject,
 | ||
|             type: gameType,
 | ||
|             difficulty: this.currentDifficulty,
 | ||
|             questions: [],
 | ||
|             timeLimit: this.difficultyParams[this.currentDifficulty].timeLimit,
 | ||
|             hints: this.difficultyParams[this.currentDifficulty].hints,
 | ||
|             studentProfile: this.studentProfile
 | ||
|         };
 | ||
| 
 | ||
|         // 从题目库中获取题目
 | ||
|         const questions = this.getQuestionsFromBank(subject, questionCount);
 | ||
|         gameConfig.questions = questions;
 | ||
| 
 | ||
|         // 个性化调整
 | ||
|         this.personalizeGame(gameConfig);
 | ||
| 
 | ||
|         console.log('✅ 个性化游戏生成完成:', gameConfig);
 | ||
|         return gameConfig;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 生成完整的游戏页面
 | ||
|      */
 | ||
|     generateGamePage(subject = 'math', gameType = 'quiz', questionCount = 5) {
 | ||
|         if (!this.isInitialized) {
 | ||
|             console.error('❌ AI游戏生成器未初始化');
 | ||
|             return null;
 | ||
|         }
 | ||
| 
 | ||
|         console.log(`🎮 生成完整游戏页面: ${subject} - ${gameType}`);
 | ||
| 
 | ||
|         // 生成游戏配置
 | ||
|         const gameConfig = this.generatePersonalizedGame(subject, gameType, questionCount);
 | ||
|         
 | ||
|         if (!gameConfig || !gameConfig.questions.length) {
 | ||
|             console.error('❌ 无法生成游戏配置');
 | ||
|             return null;
 | ||
|         }
 | ||
| 
 | ||
|         // 在当前页面内嵌入游戏
 | ||
|         this.embedGameInCurrentPage(gameConfig);
 | ||
| 
 | ||
|         console.log('✅ 游戏页面生成完成并已嵌入当前页面');
 | ||
|         return gameConfig;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 在当前页面内嵌入游戏
 | ||
|      */
 | ||
|     embedGameInCurrentPage(gameConfig) {
 | ||
|         const subject = gameConfig.subject;
 | ||
|         const gameType = gameConfig.type;
 | ||
|         const questions = gameConfig.questions;
 | ||
|         const difficulty = gameConfig.difficulty;
 | ||
| 
 | ||
|         // 根据学科确定游戏标题和样式
 | ||
|         let gameTitle, gameIntro, gameStyle;
 | ||
|         
 | ||
|         switch (subject) {
 | ||
|             case 'math':
 | ||
|                 if (gameType === 'quiz') {
 | ||
|                     gameTitle = 'AI数学游戏';
 | ||
|                     gameIntro = '欢迎来到AI数学游戏!我会帮你学习数学知识,准备好了吗?';
 | ||
|                 } else {
 | ||
|                     gameTitle = 'AI数学比大小游戏';
 | ||
|                     gameIntro = '欢迎来到AI数学比大小游戏!我会帮你学习数字比较,准备好了吗?';
 | ||
|                 }
 | ||
|                 gameStyle = this.getMathGameStyle();
 | ||
|                 break;
 | ||
|             case 'language':
 | ||
|                 gameTitle = 'AI语文拼音游戏';
 | ||
|                 gameIntro = '欢迎来到AI语文拼音游戏!我会帮你学习拼音和声调,准备好了吗?';
 | ||
|                 gameStyle = this.getLanguageGameStyle();
 | ||
|                 break;
 | ||
|             case 'life':
 | ||
|                 gameTitle = 'AI生活安全游戏';
 | ||
|                 gameIntro = '欢迎来到AI生活安全游戏!我会帮你学习生活中的安全知识,准备好了吗?';
 | ||
|                 gameStyle = this.getLifeGameStyle();
 | ||
|                 break;
 | ||
|             default:
 | ||
|                 gameTitle = 'AI智能游戏';
 | ||
|                 gameIntro = '欢迎来到AI智能游戏!我会帮你学习知识,准备好了吗?';
 | ||
|                 gameStyle = this.getDefaultGameStyle();
 | ||
|         }
 | ||
| 
 | ||
|         // 创建游戏容器
 | ||
|         const gameContainer = document.createElement('div');
 | ||
|         gameContainer.id = 'ai-game-container';
 | ||
|         gameContainer.innerHTML = `
 | ||
|             <style>
 | ||
|                 ${gameStyle}
 | ||
|                 #ai-game-container {
 | ||
|                     position: fixed;
 | ||
|                     top: 0;
 | ||
|                     left: 0;
 | ||
|                     width: 100%;
 | ||
|                     height: 100%;
 | ||
|                     background: rgba(0, 0, 0, 0.8);
 | ||
|                     z-index: 9999;
 | ||
|                     display: flex;
 | ||
|                     justify-content: center;
 | ||
|                     align-items: center;
 | ||
|                 }
 | ||
|                 #ai-game-container .game-container {
 | ||
|                     width: 90%;
 | ||
|                     max-width: 800px;
 | ||
|                     max-height: 90%;
 | ||
|                     overflow-y: auto;
 | ||
|                     position: relative;
 | ||
|                 }
 | ||
|                 .virtual-teacher-sidebar {
 | ||
|                     position: absolute;
 | ||
|                     right: -200px;
 | ||
|                     top: 50%;
 | ||
|                     transform: translateY(-50%);
 | ||
|                     width: 180px;
 | ||
|                     height: 200px;
 | ||
|                     background: rgba(255, 255, 255, 0.9);
 | ||
|                     border-radius: 15px;
 | ||
|                     padding: 20px;
 | ||
|                     box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
 | ||
|                     display: flex;
 | ||
|                     flex-direction: column;
 | ||
|                     align-items: center;
 | ||
|                     justify-content: center;
 | ||
|                 }
 | ||
|                 .virtual-teacher-avatar {
 | ||
|                     width: 80px;
 | ||
|                     height: 80px;
 | ||
|                     background: linear-gradient(135deg, #ff9aa2, #ffb7b2);
 | ||
|                     border-radius: 50%;
 | ||
|                     display: flex;
 | ||
|                     align-items: center;
 | ||
|                     justify-content: center;
 | ||
|                     font-size: 40px;
 | ||
|                     margin-bottom: 10px;
 | ||
|                     box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
 | ||
|                 }
 | ||
|                 .virtual-teacher-status {
 | ||
|                     font-size: 14px;
 | ||
|                     color: #666;
 | ||
|                     text-align: center;
 | ||
|                     margin-bottom: 10px;
 | ||
|                 }
 | ||
|                 .virtual-teacher-controls {
 | ||
|                     display: flex;
 | ||
|                     gap: 10px;
 | ||
|                 }
 | ||
|                 .control-btn {
 | ||
|                     width: 30px;
 | ||
|                     height: 30px;
 | ||
|                     border: none;
 | ||
|                     border-radius: 50%;
 | ||
|                     background: #f0f0f0;
 | ||
|                     cursor: pointer;
 | ||
|                     display: flex;
 | ||
|                     align-items: center;
 | ||
|                     justify-content: center;
 | ||
|                     font-size: 16px;
 | ||
|                     transition: all 0.2s ease;
 | ||
|                 }
 | ||
|                 .control-btn:hover {
 | ||
|                     background: #e0e0e0;
 | ||
|                     transform: scale(1.1);
 | ||
|                 }
 | ||
|                 .control-btn.speaking {
 | ||
|                     background: #4ecdc4;
 | ||
|                     color: white;
 | ||
|                     animation: pulse 1s infinite;
 | ||
|                 }
 | ||
|                 @keyframes pulse {
 | ||
|                     0% { transform: scale(1); }
 | ||
|                     50% { transform: scale(1.1); }
 | ||
|                     100% { transform: scale(1); }
 | ||
|                 }
 | ||
|                 /* 体感交互按钮样式 */
 | ||
|                 .box-btn {
 | ||
|                     position: absolute;
 | ||
|                     bottom: 20px;
 | ||
|                     left: 50%;
 | ||
|                     transform: translateX(-50%);
 | ||
|                     display: flex;
 | ||
|                     align-items: center;
 | ||
|                     gap: 20px;
 | ||
|                     background: rgba(255, 255, 255, 0.9);
 | ||
|                     padding: 15px 30px;
 | ||
|                     border-radius: 50px;
 | ||
|                     box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2);
 | ||
|                     z-index: 1000;
 | ||
|                 }
 | ||
|                 .box-btn-left, .box-btn-right {
 | ||
|                     width: 60px;
 | ||
|                     height: 60px;
 | ||
|                     border: none;
 | ||
|                     border-radius: 50%;
 | ||
|                     background: linear-gradient(135deg, #4ecdc4, #44a08d);
 | ||
|                     color: white;
 | ||
|                     font-size: 18px;
 | ||
|                     font-weight: bold;
 | ||
|                     cursor: pointer;
 | ||
|                     transition: all 0.3s ease;
 | ||
|                     display: flex;
 | ||
|                     align-items: center;
 | ||
|                     justify-content: center;
 | ||
|                 }
 | ||
|                 .box-btn-left:hover, .box-btn-right:hover {
 | ||
|                     transform: scale(1.1);
 | ||
|                     box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
 | ||
|                 }
 | ||
|                 .box-btn-left:active, .box-btn-right:active {
 | ||
|                     transform: scale(0.95);
 | ||
|                 }
 | ||
|                 .box-btn-question {
 | ||
|                     font-size: 16px;
 | ||
|                     color: #333;
 | ||
|                     text-align: center;
 | ||
|                     min-width: 200px;
 | ||
|                     font-weight: 500;
 | ||
|                 }
 | ||
|                 .close-game-btn {
 | ||
|                     position: absolute;
 | ||
|                     top: 20px;
 | ||
|                     right: 20px;
 | ||
|                     background: #ff6b6b;
 | ||
|                     color: white;
 | ||
|                     border: none;
 | ||
|                     border-radius: 50%;
 | ||
|                     width: 40px;
 | ||
|                     height: 40px;
 | ||
|                     font-size: 20px;
 | ||
|                     cursor: pointer;
 | ||
|                     z-index: 10000;
 | ||
|                 }
 | ||
|                 .close-game-btn:hover {
 | ||
|                     background: #ff5252;
 | ||
|                 }
 | ||
|             </style>
 | ||
|             <button class="close-game-btn" onclick="closeAIGame()">×</button>
 | ||
|             <div class="game-container">
 | ||
|                 <div class="score-area">
 | ||
|                     <div>得分: <span id="score">0</span></div>
 | ||
|                     <div>进度: <span id="progress">0</span>/<span id="total">${questions.length}</span></div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <h1>${gameTitle}</h1>
 | ||
| 
 | ||
|                 <div class="progress-bar">
 | ||
|                     <div class="progress-fill" id="progressFill"></div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <div class="question-area">
 | ||
|                     <div class="question" id="questionText">准备开始...</div>
 | ||
|                     <div class="options" id="optionsContainer">
 | ||
|                         <!-- 选项将通过JavaScript动态生成 -->
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <!-- 体感交互按钮容器 -->
 | ||
|                 <div class="box-btn" id="bodyInteractionBtns" style="display: none;">
 | ||
|                     <button class="box-btn-left" onclick="selectBodyAnswer('left')" aria-label="选择左侧选项"></button>
 | ||
|                     <div class="box-btn-question" id="bodyQuestionText">请举起左手或右手选择答案</div>
 | ||
|                     <button class="box-btn-right" onclick="selectBodyAnswer('right')" aria-label="选择右侧选项"></button>
 | ||
|                 </div>
 | ||
| 
 | ||
|                 <!-- 虚拟猫头鹰侧边栏 -->
 | ||
|                 <div class="virtual-teacher-sidebar">
 | ||
|                     <div class="virtual-teacher-avatar" id="virtualTeacherAvatar">🦉</div>
 | ||
|                     <div class="virtual-teacher-status" id="virtualTeacherStatus">准备就绪</div>
 | ||
|                     <div class="virtual-teacher-controls">
 | ||
|                         <button class="control-btn" id="speakBtn" onclick="toggleVirtualTeacher()" title="语音开关">🔊</button>
 | ||
|                         <button class="control-btn" id="muteBtn" onclick="muteVirtualTeacher()" title="静音">🔇</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>
 | ||
|         `;
 | ||
| 
 | ||
|         // 添加到页面
 | ||
|         document.body.appendChild(gameContainer);
 | ||
| 
 | ||
|         // 初始化游戏逻辑
 | ||
|         this.initializeGameLogic(gameConfig, gameTitle, gameIntro);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 初始化游戏逻辑
 | ||
|      */
 | ||
|     initializeGameLogic(gameConfig, gameTitle, gameIntro) {
 | ||
|         const gameId = gameConfig.id;
 | ||
|         const questions = gameConfig.questions;
 | ||
| 
 | ||
|         // DOM元素
 | ||
|         const questionText = document.getElementById("questionText");
 | ||
|         const optionsContainer = document.getElementById("optionsContainer");
 | ||
|         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 currentQuestionIndex = 0;
 | ||
|         let score = 0;
 | ||
|         let correctCount = 0;
 | ||
|         let gameStarted = false;
 | ||
|         let virtualTeacherMuted = false;
 | ||
|         
 | ||
|         // 体感交互元素
 | ||
|         const bodyInteractionBtns = document.getElementById("bodyInteractionBtns");
 | ||
|         const bodyQuestionText = document.getElementById("bodyQuestionText");
 | ||
| 
 | ||
|         // 虚拟猫头鹰控制函数
 | ||
|         function updateVirtualTeacherStatus(status, isSpeaking = false) {
 | ||
|             if (virtualTeacherStatus) {
 | ||
|                 virtualTeacherStatus.textContent = status;
 | ||
|             }
 | ||
|             if (speakBtn) {
 | ||
|                 if (isSpeaking) {
 | ||
|                     speakBtn.classList.add('speaking');
 | ||
|                 } else {
 | ||
|                     speakBtn.classList.remove('speaking');
 | ||
|                 }
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         function toggleVirtualTeacher() {
 | ||
|             virtualTeacherMuted = !virtualTeacherMuted;
 | ||
|             if (virtualTeacherMuted) {
 | ||
|                 updateVirtualTeacherStatus('已静音');
 | ||
|                 if (window.gameVirtualTeacher) {
 | ||
|                     window.gameVirtualTeacher.stopAllSpeech();
 | ||
|                 }
 | ||
|             } else {
 | ||
|                 updateVirtualTeacherStatus('准备就绪');
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         function muteVirtualTeacher() {
 | ||
|             virtualTeacherMuted = true;
 | ||
|             updateVirtualTeacherStatus('已静音');
 | ||
|             if (window.gameVirtualTeacher) {
 | ||
|                 window.gameVirtualTeacher.stopAllSpeech();
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 体感交互控制函数
 | ||
|         function showBodyInteraction() {
 | ||
|             if (bodyInteractionBtns) {
 | ||
|                 bodyInteractionBtns.style.display = 'flex';
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         function hideBodyInteraction() {
 | ||
|             if (bodyInteractionBtns) {
 | ||
|                 bodyInteractionBtns.style.display = 'none';
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         function updateBodyQuestionText(text) {
 | ||
|             if (bodyQuestionText) {
 | ||
|                 bodyQuestionText.textContent = text;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 体感交互选择答案
 | ||
|         function selectBodyAnswer(hand) {
 | ||
|             if (currentQuestionIndex >= questions.length) return;
 | ||
|             
 | ||
|             const question = questions[currentQuestionIndex];
 | ||
|             let selectedIndex = -1;
 | ||
|             
 | ||
|             // 根据左右手选择对应的选项
 | ||
|             if (question.options.length >= 2) {
 | ||
|                 selectedIndex = hand === 'left' ? 0 : 1;
 | ||
|             } else if (question.options.length === 1) {
 | ||
|                 selectedIndex = 0;
 | ||
|             }
 | ||
|             
 | ||
|             if (selectedIndex >= 0) {
 | ||
|                 selectAnswer(selectedIndex, question);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 显示当前题目
 | ||
|         function showCurrentQuestion() {
 | ||
|             if (currentQuestionIndex >= questions.length) {
 | ||
|                 endGame();
 | ||
|                 return;
 | ||
|             }
 | ||
| 
 | ||
|             const question = questions[currentQuestionIndex];
 | ||
|             questionText.textContent = question.question;
 | ||
| 
 | ||
|             // 清空选项容器
 | ||
|             optionsContainer.innerHTML = "";
 | ||
| 
 | ||
|             // 创建选项按钮
 | ||
|             question.options.forEach((option, index) => {
 | ||
|                 const button = document.createElement("button");
 | ||
|                 button.className = "option-btn";
 | ||
|                 button.textContent = option;
 | ||
|                 button.onclick = () => selectAnswer(index, question);
 | ||
|                 optionsContainer.appendChild(button);
 | ||
|             });
 | ||
| 
 | ||
|             // 更新进度
 | ||
|             progressElement.textContent = currentQuestionIndex + 1;
 | ||
|             progressFill.style.width = `${((currentQuestionIndex + 1) / questions.length) * 100}%`;
 | ||
| 
 | ||
|             // 虚拟老师读题目
 | ||
|             if (window.gameVirtualTeacher && !virtualTeacherMuted) {
 | ||
|                 updateVirtualTeacherStatus('正在读题...', true);
 | ||
|                 setTimeout(() => {
 | ||
|                     window.gameVirtualTeacher.readQuestion(question.question);
 | ||
|                     setTimeout(() => {
 | ||
|                         updateVirtualTeacherStatus('准备就绪');
 | ||
|                     }, 2000);
 | ||
|                 }, 500);
 | ||
|             }
 | ||
| 
 | ||
|             // 显示体感交互按钮
 | ||
|             showBodyInteraction();
 | ||
|             
 | ||
|             // 更新体感交互提示文本
 | ||
|             if (question.options.length >= 2) {
 | ||
|                 updateBodyQuestionText(`请举起${question.options[0]}或${question.options[1]}选择答案`);
 | ||
|             } else if (question.options.length === 1) {
 | ||
|                 updateBodyQuestionText(`请举起任意一只手选择:${question.options[0]}`);
 | ||
|             } else {
 | ||
|                 updateBodyQuestionText('请举起左手或右手选择答案');
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 选择答案
 | ||
|         function selectAnswer(selectedIndex, question) {
 | ||
|             if (message.classList.contains("show")) return;
 | ||
|             
 | ||
|             // 隐藏体感交互按钮
 | ||
|             hideBodyInteraction();
 | ||
| 
 | ||
|             const isCorrect = selectedIndex === question.correct;
 | ||
|             const selectedButton = optionsContainer.children[selectedIndex];
 | ||
|             const correctButton = optionsContainer.children[question.correct];
 | ||
| 
 | ||
|             // 显示答案效果
 | ||
|             selectedButton.classList.add(isCorrect ? "correct" : "wrong");
 | ||
|             if (!isCorrect) {
 | ||
|                 correctButton.classList.add("correct");
 | ||
|             }
 | ||
| 
 | ||
|             // 虚拟老师反馈
 | ||
|             if (window.gameVirtualTeacher && !virtualTeacherMuted) {
 | ||
|                 window.gameVirtualTeacher.stopAllSpeech();
 | ||
|                 updateVirtualTeacherStatus(isCorrect ? '答对了!' : '再想想...', true);
 | ||
|                 setTimeout(() => {
 | ||
|                     if (isCorrect) {
 | ||
|                         window.gameVirtualTeacher.recordCorrect();
 | ||
|                     } else {
 | ||
|                         window.gameVirtualTeacher.recordIncorrect();
 | ||
|                     }
 | ||
|                     setTimeout(() => {
 | ||
|                         updateVirtualTeacherStatus('准备就绪');
 | ||
|                     }, 1500);
 | ||
|                 }, 300);
 | ||
|             }
 | ||
| 
 | ||
|             // 更新分数
 | ||
|             if (isCorrect) {
 | ||
|                 correctCount++;
 | ||
|                 score += 10;
 | ||
|                 scoreElement.textContent = score;
 | ||
|             }
 | ||
| 
 | ||
|             // 记录游戏数据
 | ||
|             if (gameStarted && window.gameTracker) {
 | ||
|                 if (isCorrect) {
 | ||
|                     window.gameTracker.recordCorrect(10, {
 | ||
|                         question: question.question,
 | ||
|                         selected: question.options[selectedIndex],
 | ||
|                         correct: question.options[question.correct],
 | ||
|                         questionNumber: currentQuestionIndex + 1,
 | ||
|                     });
 | ||
|                 } else {
 | ||
|                     window.gameTracker.recordIncorrect(0, {
 | ||
|                         question: question.question,
 | ||
|                         selected: question.options[selectedIndex],
 | ||
|                         correct: question.options[question.correct],
 | ||
|                         questionNumber: currentQuestionIndex + 1,
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             // 显示结果消息
 | ||
|             const messageText = isCorrect
 | ||
|                 ? `太棒了!${question.question} 的答案是 ${question.options[question.correct]}`
 | ||
|                 : `再想想!正确答案是 ${question.options[question.correct]}`;
 | ||
| 
 | ||
|             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");
 | ||
| 
 | ||
|             // 自动消失定时器
 | ||
|             const autoHideTimer = setTimeout(() => {
 | ||
|                 nextQuestion();
 | ||
|             }, 3000); // 3秒后自动消失
 | ||
| 
 | ||
|             // 点击消息区域也可以消失
 | ||
|             message.onclick = () => {
 | ||
|                 clearTimeout(autoHideTimer);
 | ||
|                 nextQuestion();
 | ||
|             };
 | ||
|         }
 | ||
| 
 | ||
|         // 创建彩色纸屑效果
 | ||
|         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 / questions.length) * 100;
 | ||
| 
 | ||
|             message.className = "message correct";
 | ||
|             messageTitle.textContent = "游戏完成!";
 | ||
|             messageText.textContent = `恭喜你完成了游戏!\n得分: ${score}\n正确率: ${successRate.toFixed(1)}%`;
 | ||
|             message.classList.add("show");
 | ||
| 
 | ||
|             // 虚拟老师游戏结束
 | ||
|             if (window.gameVirtualTeacher) {
 | ||
|                 updateVirtualTeacherStatus('游戏结束!', true);
 | ||
|                 window.gameVirtualTeacher.gameEnd();
 | ||
|                 setTimeout(() => {
 | ||
|                     updateVirtualTeacherStatus('等待重新开始');
 | ||
|                 }, 2000);
 | ||
|             }
 | ||
| 
 | ||
|             // 记录游戏结果
 | ||
|             if (gameStarted && window.gameTracker) {
 | ||
|                 if (successRate >= 80) {
 | ||
|                     window.gameTracker.recordWin(score, {
 | ||
|                         totalQuestions: questions.length,
 | ||
|                         correctCount: correctCount,
 | ||
|                         successRate: successRate,
 | ||
|                     });
 | ||
|                 } else {
 | ||
|                     window.gameTracker.recordLose(score, {
 | ||
|                         totalQuestions: 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();
 | ||
|         }
 | ||
| 
 | ||
|         // 事件监听
 | ||
|         messageBtn.addEventListener("click", nextQuestion);
 | ||
| 
 | ||
|         // 初始化游戏
 | ||
|         setTimeout(() => {
 | ||
|             // 虚拟老师游戏开始
 | ||
|             if (window.gameVirtualTeacher) {
 | ||
|                 updateVirtualTeacherStatus('游戏开始!', true);
 | ||
|                 window.gameVirtualTeacher.gameStart(gameTitle);
 | ||
|                 setTimeout(() => {
 | ||
|                     if (!virtualTeacherMuted) {
 | ||
|                         window.gameVirtualTeacher.speak(gameIntro);
 | ||
|                         setTimeout(() => {
 | ||
|                             updateVirtualTeacherStatus('准备就绪');
 | ||
|                         }, 3000);
 | ||
|                     }
 | ||
|                 }, 1000);
 | ||
|             }
 | ||
| 
 | ||
|             // 开始游戏跟踪
 | ||
|             if (window.gameTracker) {
 | ||
|                 window.gameTracker.startGame(gameId, {
 | ||
|                     gameType: "ai_generated",
 | ||
|                     difficulty: "adaptive",
 | ||
|                     subject: gameConfig.subject,
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
|             gameStarted = true;
 | ||
|             showCurrentQuestion();
 | ||
|         }, 500);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 关闭AI游戏
 | ||
|      */
 | ||
|     closeAIGame() {
 | ||
|         const gameContainer = document.getElementById('ai-game-container');
 | ||
|         if (gameContainer) {
 | ||
|             gameContainer.remove();
 | ||
|         }
 | ||
|         
 | ||
|         // 停止虚拟老师
 | ||
|         if (window.gameVirtualTeacher) {
 | ||
|             window.gameVirtualTeacher.stopAllSpeech();
 | ||
|         }
 | ||
|         
 | ||
|         console.log('🎮 AI游戏已关闭');
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 创建游戏页面HTML
 | ||
|      */
 | ||
|     createGamePageHTML(gameConfig) {
 | ||
|         const gameId = gameConfig.id;
 | ||
|         const subject = gameConfig.subject;
 | ||
|         const gameType = gameConfig.type;
 | ||
|         const questions = gameConfig.questions;
 | ||
|         const difficulty = gameConfig.difficulty;
 | ||
| 
 | ||
|         // 根据学科确定游戏标题和样式
 | ||
|         let gameTitle, gameIntro, gameStyle;
 | ||
|         
 | ||
|         switch (subject) {
 | ||
|             case 'math':
 | ||
|                 if (gameType === 'quiz') {
 | ||
|                     gameTitle = 'AI数学游戏';
 | ||
|                     gameIntro = '欢迎来到AI数学游戏!我会帮你学习数学知识,准备好了吗?';
 | ||
|                 } else {
 | ||
|                     gameTitle = 'AI数学比大小游戏';
 | ||
|                     gameIntro = '欢迎来到AI数学比大小游戏!我会帮你学习数字比较,准备好了吗?';
 | ||
|                 }
 | ||
|                 gameStyle = this.getMathGameStyle();
 | ||
|                 break;
 | ||
|             case 'language':
 | ||
|                 gameTitle = 'AI语文拼音游戏';
 | ||
|                 gameIntro = '欢迎来到AI语文拼音游戏!我会帮你学习拼音和声调,准备好了吗?';
 | ||
|                 gameStyle = this.getLanguageGameStyle();
 | ||
|                 break;
 | ||
|             case 'life':
 | ||
|                 gameTitle = 'AI生活安全游戏';
 | ||
|                 gameIntro = '欢迎来到AI生活安全游戏!我会帮你学习生活中的安全知识,准备好了吗?';
 | ||
|                 gameStyle = this.getLifeGameStyle();
 | ||
|                 break;
 | ||
|             default:
 | ||
|                 gameTitle = 'AI智能游戏';
 | ||
|                 gameIntro = '欢迎来到AI智能游戏!我会帮你学习知识,准备好了吗?';
 | ||
|                 gameStyle = this.getDefaultGameStyle();
 | ||
|         }
 | ||
| 
 | ||
|         // 生成游戏HTML
 | ||
|         const gameHTML = `
 | ||
| <!DOCTYPE html>
 | ||
| <html lang="zh-CN">
 | ||
| <head>
 | ||
|     <meta charset="UTF-8">
 | ||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | ||
|     <title>${gameTitle}</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>
 | ||
|     
 | ||
|     <style>
 | ||
|         ${gameStyle}
 | ||
|     </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">${questions.length}</span></div>
 | ||
|         </div>
 | ||
| 
 | ||
|         <h1>${gameTitle}</h1>
 | ||
| 
 | ||
|         <div class="progress-bar">
 | ||
|             <div class="progress-fill" id="progressFill"></div>
 | ||
|         </div>
 | ||
| 
 | ||
|         <div class="question-area">
 | ||
|             <div class="question" id="questionText">准备开始...</div>
 | ||
|             <div class="options" id="optionsContainer">
 | ||
|                 <!-- 选项将通过JavaScript动态生成 -->
 | ||
|             </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>
 | ||
|         // 游戏配置
 | ||
|         const gameConfig = ${JSON.stringify(gameConfig)};
 | ||
|         
 | ||
|         // DOM元素
 | ||
|         const questionText = document.getElementById("questionText");
 | ||
|         const optionsContainer = document.getElementById("optionsContainer");
 | ||
|         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 currentQuestionIndex = 0;
 | ||
|         let score = 0;
 | ||
|         let correctCount = 0;
 | ||
|         let gameStarted = false;
 | ||
|         let gameId = "${gameId}";
 | ||
| 
 | ||
|         // 显示当前题目
 | ||
|         function showCurrentQuestion() {
 | ||
|             if (currentQuestionIndex >= gameConfig.questions.length) {
 | ||
|                 endGame();
 | ||
|                 return;
 | ||
|             }
 | ||
| 
 | ||
|             const question = gameConfig.questions[currentQuestionIndex];
 | ||
|             questionText.textContent = question.question;
 | ||
| 
 | ||
|             // 清空选项容器
 | ||
|             optionsContainer.innerHTML = "";
 | ||
| 
 | ||
|             // 创建选项按钮
 | ||
|             question.options.forEach((option, index) => {
 | ||
|                 const button = document.createElement("button");
 | ||
|                 button.className = "option-btn";
 | ||
|                 button.textContent = option;
 | ||
|                 button.onclick = () => selectAnswer(index, question);
 | ||
|                 optionsContainer.appendChild(button);
 | ||
|             });
 | ||
| 
 | ||
|             // 更新进度
 | ||
|             progressElement.textContent = currentQuestionIndex + 1;
 | ||
|             progressFill.style.width = \`\${
 | ||
|                 ((currentQuestionIndex + 1) / gameConfig.questions.length) * 100
 | ||
|             }%\`;
 | ||
|         }
 | ||
| 
 | ||
|         // 选择答案
 | ||
|         function selectAnswer(selectedIndex, question) {
 | ||
|             if (message.classList.contains("show")) return;
 | ||
|             
 | ||
|             // 隐藏体感交互按钮
 | ||
|             hideBodyInteraction();
 | ||
| 
 | ||
|             const isCorrect = selectedIndex === question.correct;
 | ||
|             const selectedButton = optionsContainer.children[selectedIndex];
 | ||
|             const correctButton = optionsContainer.children[question.correct];
 | ||
| 
 | ||
|             // 显示答案效果
 | ||
|             selectedButton.classList.add(isCorrect ? "correct" : "wrong");
 | ||
|             if (!isCorrect) {
 | ||
|                 correctButton.classList.add("correct");
 | ||
|             }
 | ||
| 
 | ||
|             // 虚拟老师反馈
 | ||
|             if (window.gameVirtualTeacher && !virtualTeacherMuted) {
 | ||
|                 window.gameVirtualTeacher.stopAllSpeech();
 | ||
|                 updateVirtualTeacherStatus(isCorrect ? '答对了!' : '再想想...', true);
 | ||
|                 setTimeout(() => {
 | ||
|                     if (isCorrect) {
 | ||
|                         window.gameVirtualTeacher.recordCorrect();
 | ||
|                     } else {
 | ||
|                         window.gameVirtualTeacher.recordIncorrect();
 | ||
|                     }
 | ||
|                     setTimeout(() => {
 | ||
|                         updateVirtualTeacherStatus('准备就绪');
 | ||
|                     }, 1500);
 | ||
|                 }, 300);
 | ||
|             }
 | ||
| 
 | ||
|             // 更新分数
 | ||
|             if (isCorrect) {
 | ||
|                 correctCount++;
 | ||
|                 score += 10;
 | ||
|                 scoreElement.textContent = score;
 | ||
|             }
 | ||
| 
 | ||
|             // 记录游戏数据
 | ||
|             if (gameStarted && window.gameTracker) {
 | ||
|                 if (isCorrect) {
 | ||
|                     window.gameTracker.recordCorrect(10, {
 | ||
|                         question: question.question,
 | ||
|                         selected: question.options[selectedIndex],
 | ||
|                         correct: question.options[question.correct],
 | ||
|                         questionNumber: currentQuestionIndex + 1,
 | ||
|                     });
 | ||
|                 } else {
 | ||
|                     window.gameTracker.recordIncorrect(0, {
 | ||
|                         question: question.question,
 | ||
|                         selected: question.options[selectedIndex],
 | ||
|                         correct: question.options[question.correct],
 | ||
|                         questionNumber: currentQuestionIndex + 1,
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             // 显示结果消息
 | ||
|             const messageText = isCorrect
 | ||
|                 ? \`太棒了!\${question.question} 的答案是 \${question.options[question.correct]}\`
 | ||
|                 : \`再想想!正确答案是 \${question.options[question.correct]}\`;
 | ||
| 
 | ||
|             showMessage(isCorrect, messageText);
 | ||
| 
 | ||
|             if (isCorrect) {
 | ||
|                 createConfetti();
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         // 下一题
 | ||
|         function nextQuestion() {
 | ||
|             message.classList.remove("show");
 | ||
|             currentQuestionIndex++;
 | ||
|             showCurrentQuestion();
 | ||
|         }
 | ||
| 
 | ||
|         // 结束游戏
 | ||
|         function endGame() {
 | ||
|             const successRate = (correctCount / gameConfig.questions.length) * 100;
 | ||
| 
 | ||
|             message.className = "message correct";
 | ||
|             messageTitle.textContent = "游戏完成!";
 | ||
|             messageText.textContent = \`恭喜你完成了游戏!\\n得分: \${score}\\n正确率: \${successRate.toFixed(1)}%\`;
 | ||
|             message.classList.add("show");
 | ||
| 
 | ||
|             // 虚拟老师游戏结束
 | ||
|             if (window.gameVirtualTeacher) {
 | ||
|                 updateVirtualTeacherStatus('游戏结束!', true);
 | ||
|                 window.gameVirtualTeacher.gameEnd();
 | ||
|                 setTimeout(() => {
 | ||
|                     updateVirtualTeacherStatus('等待重新开始');
 | ||
|                 }, 2000);
 | ||
|             }
 | ||
| 
 | ||
|             // 记录游戏结果
 | ||
|             if (gameStarted && window.gameTracker) {
 | ||
|                 if (successRate >= 80) {
 | ||
|                     window.gameTracker.recordWin(score, {
 | ||
|                         totalQuestions: gameConfig.questions.length,
 | ||
|                         correctCount: correctCount,
 | ||
|                         successRate: successRate,
 | ||
|                     });
 | ||
|                 } else {
 | ||
|                     window.gameTracker.recordLose(score, {
 | ||
|                         totalQuestions: gameConfig.questions.length,
 | ||
|                         correctCount: correctCount,
 | ||
|                         successRate: successRate,
 | ||
|                     });
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             messageBtn.textContent = "重新开始";
 | ||
|             messageBtn.onclick = restartGame;
 | ||
| 
 | ||
|             // 游戏结束消息不自动消失,需要用户点击
 | ||
|             // 清除之前的点击事件
 | ||
|             message.onclick = null;
 | ||
|         }
 | ||
| 
 | ||
|         // 重新开始游戏
 | ||
|         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();
 | ||
|         }
 | ||
| 
 | ||
|         // 事件监听
 | ||
|         messageBtn.addEventListener("click", nextQuestion);
 | ||
| 
 | ||
|         // 初始化游戏
 | ||
|         setTimeout(() => {
 | ||
|             // 虚拟老师游戏开始
 | ||
|             if (window.gameVirtualTeacher) {
 | ||
|                 window.gameVirtualTeacher.gameStart("${gameTitle}");
 | ||
|                 setTimeout(() => {
 | ||
|                     window.gameVirtualTeacher.speak("${gameIntro}");
 | ||
|                 }, 1000);
 | ||
|             }
 | ||
| 
 | ||
|             // 开始游戏跟踪
 | ||
|             if (window.gameTracker) {
 | ||
|                 window.gameTracker.startGame(gameId, {
 | ||
|                     gameType: "ai_generated",
 | ||
|                     difficulty: "adaptive",
 | ||
|                     subject: "${subject}",
 | ||
|                 });
 | ||
|             }
 | ||
| 
 | ||
|             gameStarted = true;
 | ||
|             showCurrentQuestion();
 | ||
|         }, 500);
 | ||
|     </script>
 | ||
| </body>
 | ||
| </html>`;
 | ||
| 
 | ||
|         return gameHTML;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取数学游戏样式
 | ||
|      */
 | ||
|     getMathGameStyle() {
 | ||
|         return `
 | ||
|         :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;
 | ||
|         }
 | ||
| 
 | ||
|         .question-area {
 | ||
|             margin: 30px 0;
 | ||
|             padding: 20px;
 | ||
|             background-color: #f0f8ff;
 | ||
|             border-radius: 15px;
 | ||
|             box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
 | ||
|         }
 | ||
| 
 | ||
|         .question {
 | ||
|             font-size: 4rem;
 | ||
|             margin: 20px 0;
 | ||
|             color: #5e5346;
 | ||
|             font-weight: bold;
 | ||
|         }
 | ||
| 
 | ||
|         .options {
 | ||
|             display: grid;
 | ||
|             grid-template-columns: repeat(2, 1fr);
 | ||
|             gap: 20px;
 | ||
|             margin: 30px 0;
 | ||
|         }
 | ||
| 
 | ||
|         .option-btn {
 | ||
|             padding: 20px;
 | ||
|             border-radius: 15px;
 | ||
|             background-color: var(--button);
 | ||
|             color: white;
 | ||
|             border: none;
 | ||
|             font-size: 2.5rem;
 | ||
|             font-weight: bold;
 | ||
|             cursor: pointer;
 | ||
|             box-shadow: 0 5px 0 #4a6baf;
 | ||
|             transition: all 0.2s ease;
 | ||
|             min-height: 80px;
 | ||
|             display: flex;
 | ||
|             justify-content: center;
 | ||
|             align-items: center;
 | ||
|         }
 | ||
| 
 | ||
|         .option-btn:hover {
 | ||
|             background-color: #5d8eff;
 | ||
|             transform: scale(1.05);
 | ||
|         }
 | ||
| 
 | ||
|         .option-btn:active {
 | ||
|             transform: translateY(5px);
 | ||
|             box-shadow: 0 2px 0 #4a6baf;
 | ||
|         }
 | ||
| 
 | ||
|         .option-btn.correct {
 | ||
|             background-color: var(--correct);
 | ||
|             box-shadow: 0 5px 0 #8dd3c7;
 | ||
|         }
 | ||
| 
 | ||
|         .option-btn.wrong {
 | ||
|             background-color: var(--wrong);
 | ||
|             box-shadow: 0 5px 0 #e67e7e;
 | ||
|         }
 | ||
| 
 | ||
|         .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-container {
 | ||
|                 width: 95%;
 | ||
|                 padding: 20px;
 | ||
|             }
 | ||
| 
 | ||
|             h1 {
 | ||
|                 font-size: 2rem;
 | ||
|             }
 | ||
| 
 | ||
|             .question {
 | ||
|                 font-size: 2.5rem;
 | ||
|             }
 | ||
| 
 | ||
|             .options {
 | ||
|                 grid-template-columns: 1fr;
 | ||
|             }
 | ||
| 
 | ||
|             .option-btn {
 | ||
|                 font-size: 2rem;
 | ||
|             }
 | ||
|         }`;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取语文游戏样式
 | ||
|      */
 | ||
|     getLanguageGameStyle() {
 | ||
|         return this.getMathGameStyle().replace('--button: #70a1ff;', '--button: #ff6b9d;');
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取生活游戏样式
 | ||
|      */
 | ||
|     getLifeGameStyle() {
 | ||
|         return this.getMathGameStyle().replace('--button: #70a1ff;', '--button: #4ecdc4;');
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取默认游戏样式
 | ||
|      */
 | ||
|     getDefaultGameStyle() {
 | ||
|         return this.getMathGameStyle();
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 从题目库获取题目
 | ||
|      */
 | ||
|     getQuestionsFromBank(subject, questionCount) {
 | ||
|         const subjectQuestions = this.questionBank.get(subject);
 | ||
|         if (!subjectQuestions) {
 | ||
|             console.warn(`❌ 未找到学科 ${subject} 的题目库`);
 | ||
|             return [];
 | ||
|         }
 | ||
| 
 | ||
|         const allQuestions = [];
 | ||
|         
 | ||
|         // 收集所有题目
 | ||
|         for (const [type, questions] of Object.entries(subjectQuestions)) {
 | ||
|             allQuestions.push(...questions);
 | ||
|         }
 | ||
| 
 | ||
|         // 根据难度筛选题目
 | ||
|         const suitableQuestions = allQuestions.filter(q => 
 | ||
|             q.difficulty <= this.currentDifficulty
 | ||
|         );
 | ||
| 
 | ||
|         if (suitableQuestions.length === 0) {
 | ||
|             console.warn(`❌ 未找到适合难度 ${this.currentDifficulty} 的题目`);
 | ||
|             return [];
 | ||
|         }
 | ||
| 
 | ||
|         // 随机选择题目
 | ||
|         const selectedQuestions = [];
 | ||
|         const shuffled = [...suitableQuestions].sort(() => Math.random() - 0.5);
 | ||
|         
 | ||
|         for (let i = 0; i < Math.min(questionCount, shuffled.length); i++) {
 | ||
|             selectedQuestions.push({
 | ||
|                 ...shuffled[i],
 | ||
|                 id: `q_${Date.now()}_${i}`
 | ||
|             });
 | ||
|         }
 | ||
| 
 | ||
|         return selectedQuestions;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 选择题目类型
 | ||
|      */
 | ||
|     selectQuestionTypes(subject) {
 | ||
|         const availableTypes = Object.keys(this.questionTypes[subject] || {});
 | ||
|         const studentStrengths = this.studentProfile.strengths;
 | ||
|         const studentWeaknesses = this.studentProfile.weaknesses;
 | ||
| 
 | ||
|         // 优先选择学生擅长的类型,但也包含需要练习的类型
 | ||
|         let selectedTypes = [];
 | ||
|         
 | ||
|         // 70%选择擅长的类型
 | ||
|         const strengthCount = Math.ceil(availableTypes.length * 0.7);
 | ||
|         for (let i = 0; i < strengthCount && i < availableTypes.length; i++) {
 | ||
|             selectedTypes.push(availableTypes[i]);
 | ||
|         }
 | ||
|         
 | ||
|         // 30%选择需要练习的类型
 | ||
|         const weaknessCount = availableTypes.length - strengthCount;
 | ||
|         for (let i = 0; i < weaknessCount && i < availableTypes.length; i++) {
 | ||
|             const type = availableTypes[(strengthCount + i) % availableTypes.length];
 | ||
|             if (!selectedTypes.includes(type)) {
 | ||
|                 selectedTypes.push(type);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return selectedTypes;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 生成单个题目
 | ||
|      */
 | ||
|     generateQuestion(subject, questionType) {
 | ||
|         const subjectBank = this.questionBank.get(subject);
 | ||
|         if (!subjectBank || !subjectBank[questionType]) {
 | ||
|             return null;
 | ||
|         }
 | ||
| 
 | ||
|         const questions = subjectBank[questionType];
 | ||
|         const suitableQuestions = questions.filter(q => q.difficulty <= this.currentDifficulty);
 | ||
|         
 | ||
|         if (suitableQuestions.length === 0) {
 | ||
|             return null;
 | ||
|         }
 | ||
| 
 | ||
|         // 随机选择一个题目
 | ||
|         const selectedQuestion = suitableQuestions[Math.floor(Math.random() * suitableQuestions.length)];
 | ||
|         
 | ||
|         // 根据当前难度调整题目
 | ||
|         return this.adjustQuestionDifficulty(selectedQuestion);
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 调整题目难度
 | ||
|      */
 | ||
|     adjustQuestionDifficulty(question) {
 | ||
|         const adjustedQuestion = { ...question };
 | ||
|         
 | ||
|         // 根据当前难度调整选项数量
 | ||
|         if (this.currentDifficulty <= 2) {
 | ||
|             // 简单难度:减少选项数量
 | ||
|             adjustedQuestion.options = adjustedQuestion.options.slice(0, 3);
 | ||
|         } else if (this.currentDifficulty >= 4) {
 | ||
|             // 困难难度:增加干扰选项
 | ||
|             if (adjustedQuestion.options.length < 4) {
 | ||
|                 adjustedQuestion.options.push("不知道");
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return adjustedQuestion;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 个性化游戏配置
 | ||
|      */
 | ||
|     personalizeGame(gameConfig) {
 | ||
|         const profile = this.studentProfile;
 | ||
|         
 | ||
|         // 根据学习风格调整
 | ||
|         if (profile.learningStyle === 'visual') {
 | ||
|             gameConfig.visualAids = true;
 | ||
|             gameConfig.images = true;
 | ||
|         } else if (profile.learningStyle === 'auditory') {
 | ||
|             gameConfig.audioHints = true;
 | ||
|             gameConfig.voiceReading = true;
 | ||
|         } else if (profile.learningStyle === 'kinesthetic') {
 | ||
|             gameConfig.interactiveElements = true;
 | ||
|             gameConfig.handOnActivities = true;
 | ||
|         }
 | ||
| 
 | ||
|         // 根据年级调整
 | ||
|         if (profile.grade <= 1) {
 | ||
|             gameConfig.simpleLanguage = true;
 | ||
|             gameConfig.bigFonts = true;
 | ||
|             gameConfig.moreHints = true;
 | ||
|         } else if (profile.grade >= 3) {
 | ||
|             gameConfig.complexQuestions = true;
 | ||
|             gameConfig.multipleSteps = true;
 | ||
|         }
 | ||
| 
 | ||
|         // 根据正确率调整
 | ||
|         if (profile.correctRate < 0.6) {
 | ||
|             gameConfig.easierQuestions = true;
 | ||
|             gameConfig.moreTime = true;
 | ||
|         } else if (profile.correctRate > 0.8) {
 | ||
|             gameConfig.challengingQuestions = true;
 | ||
|             gameConfig.bonusPoints = true;
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 动态调整难度
 | ||
|      */
 | ||
|     adjustDifficulty(performance) {
 | ||
|         const { correct, total, timeSpent, hintsUsed } = performance;
 | ||
|         const successRate = correct / total;
 | ||
|         const avgTimePerQuestion = timeSpent / total;
 | ||
|         
 | ||
|         // 记录性能历史
 | ||
|         this.performanceHistory.push({
 | ||
|             timestamp: Date.now(),
 | ||
|             successRate,
 | ||
|             avgTimePerQuestion,
 | ||
|             hintsUsed,
 | ||
|             difficulty: this.currentDifficulty
 | ||
|         });
 | ||
| 
 | ||
|         // 根据成功率调整难度
 | ||
|         if (successRate >= 0.8 && this.currentDifficulty < 5) {
 | ||
|             this.currentDifficulty++;
 | ||
|             console.log(`📈 难度提升到 ${this.currentDifficulty}`);
 | ||
|         } else if (successRate < 0.6 && this.currentDifficulty > 1) {
 | ||
|             this.currentDifficulty--;
 | ||
|             console.log(`📉 难度降低到 ${this.currentDifficulty}`);
 | ||
|         }
 | ||
| 
 | ||
|         // 根据答题速度调整
 | ||
|         const expectedTime = this.difficultyParams[this.currentDifficulty].timeLimit;
 | ||
|         if (avgTimePerQuestion < expectedTime * 0.5) {
 | ||
|             // 答题太快,可能太简单
 | ||
|             if (this.currentDifficulty < 5) {
 | ||
|                 this.currentDifficulty++;
 | ||
|                 console.log(`⚡ 答题速度过快,难度提升到 ${this.currentDifficulty}`);
 | ||
|             }
 | ||
|         } else if (avgTimePerQuestion > expectedTime * 1.5) {
 | ||
|             // 答题太慢,可能太难
 | ||
|             if (this.currentDifficulty > 1) {
 | ||
|                 this.currentDifficulty--;
 | ||
|                 console.log(`🐌 答题速度过慢,难度降低到 ${this.currentDifficulty}`);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         return this.currentDifficulty;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 生成游戏ID
 | ||
|      */
 | ||
|     generateGameId() {
 | ||
|         return `ai_game_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 获取游戏统计
 | ||
|      */
 | ||
|     getGameStats() {
 | ||
|         return {
 | ||
|             currentDifficulty: this.currentDifficulty,
 | ||
|             totalGames: this.performanceHistory.length,
 | ||
|             averageSuccessRate: this.performanceHistory.reduce((sum, p) => sum + p.successRate, 0) / this.performanceHistory.length,
 | ||
|             difficultyHistory: this.difficultyHistory,
 | ||
|             performanceHistory: this.performanceHistory
 | ||
|         };
 | ||
|     }
 | ||
| 
 | ||
|     /**
 | ||
|      * 重置游戏生成器
 | ||
|      */
 | ||
|     reset() {
 | ||
|         this.currentDifficulty = 1;
 | ||
|         this.difficultyHistory = [];
 | ||
|         this.performanceHistory = [];
 | ||
|         console.log('🔄 AI游戏生成器已重置');
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| // 创建全局实例
 | ||
| window.aiGameGenerator = new AIGameGenerator();
 | ||
| 
 | ||
| // 全局关闭函数
 | ||
| window.closeAIGame = function() {
 | ||
|     const gameContainer = document.getElementById('ai-game-container');
 | ||
|     if (gameContainer) {
 | ||
|         gameContainer.remove();
 | ||
|     }
 | ||
|     
 | ||
|     // 停止虚拟老师
 | ||
|     if (window.gameVirtualTeacher) {
 | ||
|         window.gameVirtualTeacher.stopAllSpeech();
 | ||
|     }
 | ||
|     
 | ||
|     console.log('🎮 AI游戏已关闭');
 | ||
| };
 | ||
| 
 | ||
| // 全局虚拟猫头鹰控制函数
 | ||
| window.toggleVirtualTeacher = function() {
 | ||
|     // 这个函数会在游戏内部被定义
 | ||
|     if (typeof toggleVirtualTeacher === 'function') {
 | ||
|         toggleVirtualTeacher();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| window.muteVirtualTeacher = function() {
 | ||
|     // 这个函数会在游戏内部被定义
 | ||
|     if (typeof muteVirtualTeacher === 'function') {
 | ||
|         muteVirtualTeacher();
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| // 全局体感交互函数
 | ||
| window.selectBodyAnswer = function(hand) {
 | ||
|     // 这个函数会在游戏内部被定义
 | ||
|     if (typeof selectBodyAnswer === 'function') {
 | ||
|         selectBodyAnswer(hand);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| // 导出类
 | ||
| if (typeof module !== 'undefined' && module.exports) {
 | ||
|     module.exports = AIGameGenerator;
 | ||
| }
 |