You've already forked HeurAMS-Legacy
85 lines
3.2 KiB
Python
85 lines
3.2 KiB
Python
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() |