| """Night diary line picker from fixed pool (not NLG).""" | |
| from __future__ import annotations | |
| import json | |
| import random | |
| from pathlib import Path | |
| from typing import List, Optional, Sequence | |
| class DiaryPool: | |
| def __init__(self, lines: List[dict], rng: Optional[random.Random] = None): | |
| self.lines = lines | |
| self.rng = rng or random.Random() | |
| def load(cls, path: Path, rng: Optional[random.Random] = None) -> "DiaryPool": | |
| data = json.loads(path.read_text(encoding="utf-8")) | |
| return cls(list(data.get("lines") or []), rng=rng) | |
| def pick(self, tags: Sequence[str]) -> str: | |
| tagset = set(tags) | |
| scored = [] | |
| for line in self.lines: | |
| lt = set(line.get("tags") or []) | |
| score = len(lt & tagset) | |
| if "default" in lt: | |
| score = max(score, 0) | |
| scored.append((score, line.get("text", ""))) | |
| scored.sort(key=lambda x: x[0], reverse=True) | |
| best = scored[0][0] if scored else 0 | |
| top = [t for s, t in scored if s == best and t] | |
| if not top: | |
| return "巷子很安静。店也是。" | |
| return self.rng.choice(top) | |