| import re |
| from typing import Dict, Optional |
|
|
| from agent_build_sdk.model.werewolf_model import ( |
| AgentReq, |
| STATUS_DAY, |
| STATUS_HUNTER, |
| STATUS_HUNTER_RESULT, |
| STATUS_NIGHT, |
| STATUS_NIGHT_INFO, |
| STATUS_RESULT, |
| STATUS_SHERIFF_ELECTION, |
| STATUS_SHERIFF_PK, |
| STATUS_SHERIFF_SPEECH, |
| STATUS_SHERIFF_SPEECH_ORDER, |
| STATUS_SHERIFF_VOTE, |
| STATUS_SKILL_RESULT, |
| STATUS_VOTE, |
| STATUS_VOTE_RESULT, |
| STATUS_SHERIFF, |
| ) |
|
|
| from core import ruleset |
|
|
|
|
| def _extract_sheriff_from_text(text: str) -> Optional[str]: |
| s = (text or "").strip() |
| if not s: |
| return None |
| if ruleset.SHERIFF_TEAR in s: |
| return None |
|
|
| patterns = [ |
| r"警徽归属[::]?\s*([^\s,,。;;]+)", |
| r"警徽(?:移交|交给|传递|传给|给)[::]?\s*([^\s,,。;;]+)", |
| r"移交(?:警徽)?给[::]?\s*([^\s,,。;;]+)", |
| r"警长[::]\s*([^\s,,。;;]+)", |
| ] |
|
|
| matches: list[tuple[int, str]] = [] |
| for pat in patterns: |
| for m in re.finditer(pat, s): |
| matches.append((m.start(), (m.group(1) or "").strip())) |
|
|
| if not matches: |
| return None |
|
|
| _, name = sorted(matches, key=lambda x: x[0])[-1] |
| name = name.strip().strip("[]【】()()\"'“”‘’`").strip(",,。;;::") |
| if not name or name == ruleset.SHERIFF_TEAR: |
| return None |
| return name |
|
|
|
|
| def parse_event(req: AgentReq) -> Dict[str, str]: |
| return { |
| "status": req.status or "", |
| "name": req.name or "", |
| "message": req.message or "", |
| "round": str(req.round) if req.round is not None else "", |
| "role": req.role or "", |
| } |
|
|
|
|
| def event_to_fact(req: AgentReq) -> Optional[Dict[str, str]]: |
| status = req.status or "" |
| round_no = str(req.round) if req.round is not None else "" |
| if status == STATUS_VOTE: |
| return { |
| "type": "vote", |
| "round": round_no, |
| "voter": req.name or "", |
| "target": req.message or "", |
| } |
| if status == STATUS_VOTE_RESULT: |
| return { |
| "type": "vote_result", |
| "round": round_no, |
| "out": (req.name or req.message or ""), |
| } |
| if status == STATUS_NIGHT_INFO: |
| return { |
| "type": "night_info", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_NIGHT: |
| return { |
| "type": "night", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_DAY: |
| return { |
| "type": "day", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_SKILL_RESULT: |
| return { |
| "type": "skill_result", |
| "round": round_no, |
| "name": req.name or "", |
| "message": req.message or "", |
| } |
| if status == STATUS_HUNTER: |
| return { |
| "type": "hunter", |
| "round": round_no, |
| "name": req.name or "", |
| "message": req.message or "", |
| } |
| if status == STATUS_HUNTER_RESULT: |
| return { |
| "type": "hunter_result", |
| "round": round_no, |
| "name": req.name or "", |
| "target": req.message or "", |
| } |
| if status == STATUS_RESULT: |
| return { |
| "type": "result", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_SHERIFF_ELECTION: |
| return { |
| "type": "sheriff_election", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_SHERIFF_SPEECH: |
| return { |
| "type": "sheriff_speech", |
| "round": round_no, |
| "name": req.name or "", |
| "message": req.message or "", |
| } |
| if status == STATUS_SHERIFF_PK: |
| return { |
| "type": "sheriff_pk", |
| "round": round_no, |
| "name": req.name or "", |
| "message": req.message or "", |
| } |
| if status == STATUS_SHERIFF_VOTE: |
| return { |
| "type": "sheriff_vote", |
| "round": round_no, |
| "name": req.name or "", |
| "target": req.message or "", |
| } |
| if status == STATUS_SHERIFF_SPEECH_ORDER: |
| return { |
| "type": "sheriff_speech_order", |
| "round": round_no, |
| "message": req.message or "", |
| } |
| if status == STATUS_SHERIFF: |
| sheriff_name = req.name or _extract_sheriff_from_text(req.message or "") |
| if not sheriff_name: |
| return None |
| return { |
| "type": "sheriff", |
| "round": round_no, |
| "name": sheriff_name, |
| } |
| return None |
|
|