using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Kill.Managers; using Kill.UI.Pages; using UnityEngine; using UnityEngine.UI; public class SafetylearningTestPage : MonoBehaviour { public Transform questionContainer; public GameObject questionPrefab; public Button nextButton; public Button submitButton; public GameObject answerPrefab; public List sonObjs; // 题库(所有未答对2次的题目) private List questionBank = new List(); // 答题队列(当前答题顺序) public List questionQueue = new List(); // 答题记录(记录每道题答对次数) private Dictionary correctCountMap = new Dictionary(); private int currentQuestionIndex = 0; private int totalAnsweredCount = 0; private SafetylearningQuestion currentQuestion; private GameObject currentAnswerObj; public void Init(List questions) { // 初始化题库 questionBank = new List(questions); correctCountMap.Clear(); totalAnsweredCount = 0; // 初始化答题队列(按顺序) InitializeQueue(); // 显示第一题 ShowQuestion(0); } /// /// 初始化答题队列(按顺序) /// private void InitializeQueue() { questionQueue.Clear(); // 按顺序将题库中所有题目加入队列 foreach (var question in questionBank) { questionQueue.Add(question); } currentQuestionIndex = 0; Debug.Log($"初始化答题队列,共 {questionQueue.Count} 道题"); } /// /// 重新生成队列(答错时调用) /// 清空队列,将题库中所有题目打乱顺序生成新队列 /// private void RegenerateQueue() { questionQueue.Clear(); // 将题库中所有题目加入队列 foreach (var question in questionBank) { questionQueue.Add(question); } // 打乱队列 ShuffleList(questionQueue); currentQuestionIndex = 0; Debug.Log($"重新生成答题队列,共 {questionQueue.Count} 道题"); } /// /// 从题库中移除题目(答对2次时调用) /// private void RemoveFromBank(int questionId) { var question = questionBank.Find(q => q.id == questionId); if (question != null) { questionBank.Remove(question); Debug.Log($"题目 {questionId} 已从题库中移除"); } } /// /// Fisher-Yates 洗牌算法 /// private void ShuffleList(List list) { System.Random rng = new System.Random(); int n = list.Count; while (n > 1) { n--; int k = rng.Next(n + 1); T value = list[k]; list[k] = list[n]; list[n] = value; } } /// /// 显示指定题目 /// private void ShowQuestion(int index) { // 检查队列是否为空,为空则通过 if (questionQueue.Count == 0) { Debug.Log("答题队列已空,通过!"); // 显示完成页面 SafetylearningPageCtrl.Instance?.ShowFinishPage(); return; } // 清除旧题目和解析 ClearCurrentQuestion(); currentQuestionIndex = index; // 如果超出范围,从第一题开始 if (currentQuestionIndex >= questionQueue.Count) { currentQuestionIndex = 0; } // 创建新题目 GameObject questionObj = Instantiate(questionPrefab, questionContainer); sonObjs.Add(questionObj); currentQuestion = questionObj.GetComponent(); // 使用总答题序号作为题号(累加) totalAnsweredCount++; currentQuestion.Init(totalAnsweredCount, questionQueue[currentQuestionIndex]); // 订阅选项选择事件 currentQuestion.OnOptionSelected += OnOptionSelected; // 初始状态:隐藏提交和下一题按钮 submitButton.gameObject.SetActive(false); nextButton.gameObject.SetActive(false); // 绑定按钮事件 submitButton.onClick.RemoveAllListeners(); submitButton.onClick.AddListener(OnSubmitClick); nextButton.onClick.RemoveAllListeners(); nextButton.onClick.AddListener(OnNextClick); } /// /// 选项被选择 /// private void OnOptionSelected() { // 有选择时显示提交按钮 if (currentQuestion != null && currentQuestion.HasSelectedAnswer()) { submitButton.gameObject.SetActive(true); } } /// /// 提交答案 /// private void OnSubmitClick() { if (currentQuestion == null) return; // 禁用选项交互 currentQuestion.DisableAllOptions(); submitButton.gameObject.SetActive(false); // 显示答案判断 currentQuestion.CheckAnswer(); // 判断是否正确 string userAnswer = currentQuestion.GetUserAnswer(); string correctAnswer = questionQueue[currentQuestionIndex].correctAnswer; bool isCorrect = userAnswer == correctAnswer; // 获取当前题目ID int currentQuestionId = questionQueue[currentQuestionIndex].id; if (isCorrect) { // 更新答对次数 if (!correctCountMap.ContainsKey(currentQuestionId)) { correctCountMap[currentQuestionId] = 0; } correctCountMap[currentQuestionId]++; // 检查是否答对2次 if (correctCountMap[currentQuestionId] >= 2) { // 从题库中移除 RemoveFromBank(currentQuestionId); } // 从队列中移除当前题目 questionQueue.RemoveAt(currentQuestionIndex); // 索引保持不变,因为移除后后面的题目会前移 // 2秒后自动下一题 StartCoroutine(DelayNextQuestion()); } else { // 答错:清空队列,重新生成 RegenerateQueue(); // 显示解析和下一题按钮 CreateAnswerExplanation(); nextButton.gameObject.SetActive(true); // 重置索引,确保点击下一题从第一题开始 currentQuestionIndex = -1; } } /// /// 延迟下一题 /// private IEnumerator DelayNextQuestion() { yield return new WaitForSeconds(2f); ShowQuestion(currentQuestionIndex); } /// /// 创建答案解析 /// private void CreateAnswerExplanation() { if (answerPrefab == null) return; currentAnswerObj = Instantiate(answerPrefab, questionContainer); sonObjs.Add(currentAnswerObj); currentAnswerObj.GetComponent().Init( questionQueue[currentQuestionIndex].options, questionQueue[currentQuestionIndex].videoUrl ); } /// /// 下一题 /// private void OnNextClick() { currentQuestionIndex++; ShowQuestion(currentQuestionIndex); } /// /// 清除当前题目和解析 /// private void ClearCurrentQuestion() { // 取消订阅事件 if (currentQuestion != null) { currentQuestion.OnOptionSelected -= OnOptionSelected; } // 销毁所有子对象 foreach (var obj in sonObjs) { if (obj != null) Destroy(obj); } sonObjs.Clear(); currentQuestion = null; currentAnswerObj = null; } void OnDestroy() { submitButton?.onClick.RemoveAllListeners(); nextButton?.onClick.RemoveAllListeners(); if (currentQuestion != null) { currentQuestion.OnOptionSelected -= OnOptionSelected; } } }