You've already forked HeurAMS-Legacy
style: 代码格式化
This commit is contained in:
@@ -1,137 +1,119 @@
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.events import Event
|
||||
from textual.widgets import (
|
||||
Collapsible,
|
||||
Header,
|
||||
Footer,
|
||||
Markdown,
|
||||
ListView,
|
||||
ListItem,
|
||||
Label,
|
||||
Static,
|
||||
Button,
|
||||
)
|
||||
from textual.containers import Container, Horizontal, Center
|
||||
from textual.screen import Screen
|
||||
from textual.widget import Widget
|
||||
from typing import Tuple, Dict
|
||||
import heurams.kernel.particles as pt
|
||||
import heurams.kernel.puzzles as pz
|
||||
from .base_puzzle_widget import BasePuzzleWidget
|
||||
import copy
|
||||
import random
|
||||
from textual.message import Message
|
||||
from typing import TypedDict
|
||||
|
||||
|
||||
class Setting(TypedDict):
|
||||
__origin__: str
|
||||
__hint__: str
|
||||
primary: str # 显示的提示文本
|
||||
mapping: dict # 谜题到答案的映射
|
||||
jammer: list # 干扰项
|
||||
max_riddles_num: int # 最大谜题数量
|
||||
prefix: str # 提示词前缀
|
||||
|
||||
|
||||
class MCQPuzzle(BasePuzzleWidget):
|
||||
def __init__(self, *children: Widget, atom: pt.Atom, alia: str = "", name: str | None = None, id: str | None = None, classes: str | None = None, disabled: bool = False, markup: bool = True) -> None:
|
||||
super().__init__(*children, atom=atom, name=name, id=id, classes=classes, disabled=disabled, markup=markup)
|
||||
def __init__(
|
||||
self,
|
||||
*children: Widget,
|
||||
atom: pt.Atom,
|
||||
alia: str = "",
|
||||
name: str | None = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
disabled: bool = False,
|
||||
markup: bool = True,
|
||||
) -> None:
|
||||
super().__init__(
|
||||
*children,
|
||||
atom=atom,
|
||||
name=name,
|
||||
id=id,
|
||||
classes=classes,
|
||||
disabled=disabled,
|
||||
markup=markup,
|
||||
)
|
||||
self.inputlist = []
|
||||
self.alia = alia
|
||||
self.hashtable = {}
|
||||
self._work()
|
||||
self._load()
|
||||
|
||||
def _work(self):
|
||||
def _load(self):
|
||||
cfg = self.atom.registry["orbital"]["puzzles"][self.alia]
|
||||
self.puzzle = pz.MCQPuzzle(cfg["mapping"], cfg["jammer"], cfg["max_riddles_num"], cfg['prefix'])
|
||||
self.puzzle = pz.MCQPuzzle(
|
||||
cfg["mapping"], cfg["jammer"], cfg["max_riddles_num"], cfg["prefix"]
|
||||
)
|
||||
self.puzzle.refresh()
|
||||
|
||||
class PuzzleCompleted(Message):
|
||||
"""选择题完成消息"""
|
||||
def __init__(self, atom: pt.Atom, rating: int, is_correct: bool, user_answers: list, correct_answers: list) -> None:
|
||||
self.atom = atom
|
||||
self.rating = rating # 评分
|
||||
self.is_correct = is_correct # 是否正确
|
||||
self.user_answers = user_answers # 用户答案
|
||||
self.correct_answers = correct_answers # 正确答案
|
||||
super().__init__()
|
||||
|
||||
class InputChanged(Message):
|
||||
"""输入变化消息"""
|
||||
def __init__(self, current_input: list, current_question: int, total_questions: int, current_question_text: str) -> None:
|
||||
self.current_input = current_input # 当前输入
|
||||
self.current_question = current_question # 当前题号
|
||||
self.total_questions = total_questions # 总题数
|
||||
self.current_question_text = current_question_text # 当前问题文本
|
||||
self.progress = current_question / total_questions # 进度
|
||||
super().__init__()
|
||||
|
||||
class QuestionAdvanced(Message):
|
||||
"""题目切换消息"""
|
||||
def __init__(self, question_index: int, question_text: str, options: list) -> None:
|
||||
self.question_index = question_index # 题目索引
|
||||
self.question_text = question_text
|
||||
self.options = options # 选项列表
|
||||
super().__init__()
|
||||
|
||||
def compose(self):
|
||||
yield Label(self.atom[1].content.replace("/",""), id="sentence")
|
||||
setting: Setting = self.atom.registry["nucleon"].metadata["orbital"]["puzzle"][
|
||||
self.alia
|
||||
]
|
||||
yield Label(setting["primary"], id="sentence")
|
||||
yield Label(self.puzzle.wording[len(self.inputlist)], id="puzzle")
|
||||
yield Label(f"当前输入: {self.inputlist}", id="inputpreview")
|
||||
|
||||
|
||||
# 渲染当前问题的选项
|
||||
current_options = self.puzzle.options[len(self.inputlist)]
|
||||
for i in current_options:
|
||||
self.hashtable[str(hash(i))] = i
|
||||
yield Button(i, id=f"select{hash(i)}")
|
||||
|
||||
|
||||
yield Button("退格", id="delete")
|
||||
|
||||
def update_display(self):
|
||||
# 更新预览标签
|
||||
preview = self.query_one("#inputpreview")
|
||||
preview.update(f"当前输入: {self.inputlist}") # type: ignore
|
||||
|
||||
preview.update(f"当前输入: {self.inputlist}") # type: ignore
|
||||
|
||||
# 更新问题标签
|
||||
puzzle_label = self.query_one("#puzzle")
|
||||
current_question_index = len(self.inputlist)
|
||||
if current_question_index < len(self.puzzle.wording):
|
||||
puzzle_label.update(self.puzzle.wording[current_question_index]) # type: ignore
|
||||
|
||||
puzzle_label.update(self.puzzle.wording[current_question_index]) # type: ignore
|
||||
|
||||
# 发送输入变化消息
|
||||
self.post_message(self.InputChanged(
|
||||
current_input=self.inputlist.copy(),
|
||||
current_question=current_question_index,
|
||||
total_questions=len(self.puzzle.answer),
|
||||
current_question_text=self.puzzle.wording[current_question_index] if current_question_index < len(self.puzzle.wording) else ""
|
||||
))
|
||||
|
||||
|
||||
# 如果还有下一题,发送题目切换消息
|
||||
if current_question_index < len(self.puzzle.options):
|
||||
self.post_message(self.QuestionAdvanced(
|
||||
question_index=current_question_index,
|
||||
question_text=self.puzzle.wording[current_question_index],
|
||||
options=self.puzzle.options[current_question_index]
|
||||
))
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""处理按钮点击事件"""
|
||||
button_id = event.button.id
|
||||
|
||||
|
||||
if button_id == "delete":
|
||||
# 退格处理
|
||||
if len(self.inputlist) > 0:
|
||||
self.inputlist.pop()
|
||||
self.refresh_buttons()
|
||||
self.update_display()
|
||||
elif button_id.startswith("select"): # type: ignore
|
||||
elif button_id.startswith("select"): # type: ignore
|
||||
# 选项选择处理
|
||||
answer_text = self.hashtable[button_id[6:]] # type: ignore
|
||||
answer_text = self.hashtable[button_id[6:]] # type: ignore
|
||||
self.inputlist.append(answer_text)
|
||||
|
||||
|
||||
# 检查是否完成所有题目
|
||||
if len(self.inputlist) >= len(self.puzzle.answer):
|
||||
is_correct = self.inputlist == self.puzzle.answer
|
||||
rating = 4 if is_correct else 2
|
||||
|
||||
|
||||
# 发送完成消息
|
||||
self.post_message(self.PuzzleCompleted(
|
||||
atom=self.atom,
|
||||
rating=rating,
|
||||
is_correct=is_correct,
|
||||
user_answers=self.inputlist.copy(),
|
||||
correct_answers=self.puzzle.answer.copy()
|
||||
))
|
||||
|
||||
self.post_message(
|
||||
self.PuzzleCompleted(
|
||||
atom=self.atom,
|
||||
rating=rating,
|
||||
is_correct=is_correct,
|
||||
user_answers=self.inputlist.copy(),
|
||||
correct_answers=self.puzzle.answer.copy(),
|
||||
)
|
||||
)
|
||||
|
||||
# 重置输入(如果回答错误)
|
||||
if not is_correct:
|
||||
self.inputlist = []
|
||||
@@ -145,10 +127,14 @@ class MCQPuzzle(BasePuzzleWidget):
|
||||
def refresh_buttons(self):
|
||||
"""刷新按钮显示(用于题目切换)"""
|
||||
# 移除所有选项按钮
|
||||
buttons_to_remove = [child for child in self.children if hasattr(child, 'id') and child.id and child.id.startswith('select')]
|
||||
buttons_to_remove = [
|
||||
child
|
||||
for child in self.children
|
||||
if hasattr(child, "id") and child.id and child.id.startswith("select")
|
||||
]
|
||||
for button in buttons_to_remove:
|
||||
self.remove_child(button) # type: ignore
|
||||
|
||||
self.remove_child(button) # type: ignore
|
||||
|
||||
# 添加当前题目的选项按钮
|
||||
current_question_index = len(self.inputlist)
|
||||
if current_question_index < len(self.puzzle.options):
|
||||
|
||||
Reference in New Issue
Block a user