from textual.widgets import ( Label, Button, ) from textual.widget import Widget 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 class ClozePuzzle(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) self.inputlist = list() self.hashtable = {} self.alia = alia self._work() def _work(self): cfg = self.atom.registry["orbital"]["puzzles"][self.alia] self.puzzle = pz.ClozePuzzle(text=cfg["content"], delimiter=cfg["delimiter"], min_denominator=cfg["min_denominator"]) self.puzzle.refresh() self.ans = copy.copy(self.puzzle.answer) random.shuffle(self.ans) class RatingChanged(Message): def __init__(self, atom: pt.Atom, rating: int, is_correct: bool) -> None: self.atom = atom self.rating = rating # 评分 self.is_correct = is_correct # 是否正确 super().__init__() class InputChanged(Message): """输入变化消息""" def __init__(self, current_input: list, max_length: int) -> None: self.current_input = current_input # 当前输入 self.max_length = max_length # 最大长度 self.progress = len(current_input) / max_length # 进度 super().__init__() def compose(self): yield Label(self.puzzle.wording, id="sentence") yield Label(f"当前输入: {self.inputlist}", id="inputpreview") for i in self.ans: self.hashtable[str(hash(i))] = i yield Button(i, id=f"{hash(i)}") yield Button("退格", id="delete") def update_preview(self): preview = self.query_one("#inputpreview") preview.update(f"当前输入: {self.inputlist}") # type: ignore self.post_message(self.InputChanged( current_input=self.inputlist.copy(), max_length=len(self.puzzle.answer) )) 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.update_preview() else: answer_text = self.hashtable[button_id] self.inputlist.append(answer_text) self.update_preview() 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.RatingChanged( atom=self.atom, rating=rating, is_correct=is_correct )) if not is_correct: self.inputlist = [] self.update_preview()