猜成语:还没做更新拼音的功能,即将加入。

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-09 21:38:59 +08:00
parent 0cc59d212b
commit 5fd6fc88b2
7 changed files with 272662 additions and 5682 deletions
@@ -13,6 +13,7 @@ from nonebot.utils import run_sync
from nonebot.permission import SUPERUSER
import json
from pypinyin import Style, pinyin
require("nonebot_plugin_alconna")
require("nonebot_plugin_session")
@@ -38,12 +39,12 @@ from .config import Config, handle_config
from .data_source import GuessResult, Handle
from .utils import (
random_idiom,
HANDLE_ANSWER_PHRASES,
HANDLE_HARD_ANSWER_PHRASES,
HANDLE_COMMON_PHRASES,
HANDLE_LEGAL_PHRASES,
handle_answer_hard_path,
HANDLE_ANSWER_PHRASES,
handle_common_idiom_path,
handle_all_idiom_path,
handle_answer_path,
handle_idiom_path,
)
__plugin_meta__ = PluginMetadata(
@@ -177,7 +178,7 @@ async def _(
set_timeout(matcher, user_id)
msg = Text(
f"你有{game.times}次机会猜一个四字成语,"
"你有{}次机会猜一个四字成语,".format(game.times)
+ ("发送有效成语以参与游戏。" if is_strict else "发送任意四字词语以参与游戏。")
) + Image(raw=await run_sync(game.draw)())
await msg.send()
@@ -221,7 +222,7 @@ async def _(matcher: Matcher, user_id: UserId, matched: Dict[str, Any] = RegexDi
if result == GuessResult.WIN
else "很遗憾,没有人猜出来呢"
)
+ f"\n{game.result}"
+ "\n{}".format(game.result)
) + Image(raw=await run_sync(game.draw)())
await msg.send()
@@ -229,7 +230,7 @@ async def _(matcher: Matcher, user_id: UserId, matched: Dict[str, Any] = RegexDi
await matcher.finish("你已经猜过这个成语了呢")
elif result == GuessResult.ILLEGAL:
await matcher.finish(f"你确定“{idiom}”是个成语吗?")
await matcher.finish("你确定“{}”是个成语吗?".format(idiom))
else:
await UniMessage.image(raw=await run_sync(game.draw)()).send()
@@ -285,39 +286,40 @@ async def _(
HANDLE_LEGAL_PHRASES.append(idiom)
json.dump(
HANDLE_LEGAL_PHRASES,
handle_idiom_path.open("w", encoding="utf-8"),
handle_all_idiom_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
if not hard:
HANDLE_COMMON_PHRASES.append(idiom)
json.dump(
HANDLE_COMMON_PHRASES,
handle_common_idiom_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
if explanation:
if hard:
HANDLE_HARD_ANSWER_PHRASES.append(
{"word": idiom, "explanation": explanation}
)
json.dump(
HANDLE_HARD_ANSWER_PHRASES,
handle_answer_hard_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
else:
HANDLE_ANSWER_PHRASES.append({"word": idiom, "explanation": explanation})
json.dump(
HANDLE_ANSWER_PHRASES,
handle_answer_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
HANDLE_ANSWER_PHRASES[idiom] = {
"explanation": explanation,
"pinyin": [
j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i
],
}
json.dump(
HANDLE_ANSWER_PHRASES,
handle_answer_path.open("w", encoding="utf-8"),
ensure_ascii=False,
indent=4,
sort_keys=True,
)
await handle_update_idiom.finish(
"新增成功,当前词库总数:{}\n可用普通模式成语:{}\n可用困难模式成语:{}".format(
"新增成功,当前词库总数:{}\n可用普通模式成语:{}".format(
len(HANDLE_LEGAL_PHRASES),
len(HANDLE_ANSWER_PHRASES),
len(HANDLE_HARD_ANSWER_PHRASES),
len(HANDLE_COMMON_PHRASES),
)
)
@@ -47,7 +47,7 @@ class Handle:
self.idiom: str = idiom # 成语
self.explanation: str = explanation # 释义
self.strict: bool = strict # 是否判断输入词语为成语
self.result = f"【成语】:{idiom}\n【释义】:{explanation}"
self.result = "【成语】:{}\n【释义】:{}".format(self.idiom, self.explanation)
self.pinyin: List[Tuple[str, str, str]] = get_pinyin(idiom) # 拼音
self.length = 4
self.times: int = 10 # 可猜次数
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2,7 +2,7 @@ import json
import random
from io import BytesIO
from pathlib import Path
from typing import Dict, List, Tuple
from typing import Dict, List, Tuple, Union, Literal, TypedDict
# from watchdog.observers import Observer
# from watchdog.events import FileSystemEventHandler, FileModifiedEvent
@@ -15,20 +15,29 @@ from pypinyin import Style, pinyin
resource_dir = Path(__file__).parent / "resources"
fonts_dir = resource_dir / "fonts"
data_dir = resource_dir / "data"
handle_idiom_path = data_dir / "idioms.json"
handle_common_idiom_path = data_dir / "common_idioms.json"
handle_all_idiom_path = data_dir / "idioms.json"
handle_answer_path = data_dir / "answers.json"
handle_answer_hard_path = data_dir / "answers_hard.json"
class IdiomEntry(TypedDict):
"""
成语答案类型
"""
explanation: str
pinyin: List[str]
HANDLE_COMMON_PHRASES: List[str] = json.load(
handle_common_idiom_path.open("r", encoding="utf-8")
)
HANDLE_LEGAL_PHRASES: List[str] = json.load(
handle_idiom_path.open("r", encoding="utf-8")
handle_all_idiom_path.open("r", encoding="utf-8")
)
HANDLE_ANSWER_PHRASES: List[Dict[str, str]] = json.load(
HANDLE_ANSWER_PHRASES: Dict[str, IdiomEntry] = json.load(
handle_answer_path.open("r", encoding="utf-8")
)
HANDLE_HARD_ANSWER_PHRASES: List[Dict[str, str]] = json.load(
handle_answer_hard_path.open("r", encoding="utf-8")
)
# class LegalPhrasesModifiedHandler(FileSystemEventHandler):
# """
@@ -57,16 +66,17 @@ HANDLE_HARD_ANSWER_PHRASES: List[Dict[str, str]] = json.load(
# event_filter=FileModifiedEvent,
# )
# 答案转换器
# json.dump({ i["word"]:{"explanation":i["explanation"], "pinyin":(lambda x : [i for j in pinyin(x, style=Style.TONE3, v_to_u=True) for i in j])(i["word"])} for i in json.load(open("answers_hard-old.json",encoding="utf-8"))},open("answers.json", "w",encoding="utf-8"), ensure_ascii=False, indent=4)
def legal_idiom(word: str) -> bool:
return word in HANDLE_LEGAL_PHRASES
def random_idiom(is_hard: bool = False) -> Tuple[str, str]:
answer = random.choice(
HANDLE_HARD_ANSWER_PHRASES if is_hard else HANDLE_ANSWER_PHRASES
)
return answer["word"], answer["explanation"]
answer = random.choice(HANDLE_LEGAL_PHRASES if is_hard else HANDLE_COMMON_PHRASES)
return answer, HANDLE_ANSWER_PHRASES[answer]["explanation"]
# fmt: off
@@ -85,28 +95,53 @@ FINALS = [
# fmt: on
def get_pinyin(idiom: str) -> List[Tuple[str, str, str]]:
pys = pinyin(idiom, style=Style.TONE3, v_to_u=True)
results = []
for p in pys:
py = p[0]
if py[-1].isdigit():
tone = py[-1]
py = py[:-1]
else:
tone = ""
initial = ""
for i in INITIALS:
if py.startswith(i):
initial = i
break
final = ""
for f in FINALS:
if py.endswith(f):
final = f
break
results.append((initial, final, tone)) # 声母,韵母,声调
return results
def split_pinyin(py: str) -> Tuple[str, str, str]:
"""
py: 输入的拼音
return: 返回一个三元组,分别表示该拼音的声母,韵母,声调
"""
if py[-1].isdigit():
tone = py[-1]
py = py[:-1]
else:
tone = ""
initial = ""
for i in INITIALS:
if py.startswith(i):
initial = i
break
final = ""
for f in FINALS:
if py.endswith(f):
final = f
break
return initial, final, tone
def get_pinyin(
idiom: str,
) -> List[Tuple[str, str, str]]:
"""
idiom: 输入的汉字
return: 返回一个元组,每个元素是一个三元组,分别表示该汉字的声母,韵母,声调
"""
if idiom_entry := HANDLE_ANSWER_PHRASES.get(idiom):
pinyin_per_char = idiom_entry["pinyin"]
if not pinyin_per_char:
pinyin_per_char = [
j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i
]
idiom_entry["pinyin"] = pinyin_per_char.copy()
handle_answer_path.open("w", encoding="utf-8").write(
json.dumps(HANDLE_ANSWER_PHRASES, ensure_ascii=False, indent=4)
)
else:
pinyin_per_char = [
j for i in pinyin(idiom, style=Style.TONE3, v_to_u=True) for j in i
]
return [split_pinyin(py) for py in pinyin_per_char]
def save_jpg(frame: IMG) -> BytesIO: