128 lines
5.2 KiB
Python
128 lines
5.2 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
"""Verify term_*.xlsx contains expected post-merge values."""
|
|
import sys, io, os
|
|
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
|
from openpyxl import load_workbook
|
|
|
|
TERM_DIR = r'C:\TH1\TH1\Tools\术语表'
|
|
|
|
# Format: (ZH, EN_expected, JP_expected, KR_expected) — None means don't check
|
|
EXPECTED = [
|
|
# E1
|
|
('绝不再把你留在阿斯佩恩',
|
|
'Never leave you in Aspern again',
|
|
'二度とアスペルンに置いていかない',
|
|
'다시는 널 아스페른에 두고 가지 않을게'),
|
|
# E2
|
|
('御住古战场', 'Onbashira Ancient Battlefield', '御柱古戦場', '온바시라 고대 전장'),
|
|
# E3
|
|
('英雄神像[后]', 'Hero Statue [Queen]', '英雄神像[后]', '영웅 신상 [후]'),
|
|
('英雄神像[相]', 'Hero Statue [Bishop]', None, None),
|
|
('英雄神像[王]', 'Hero Statue [King]', None, None),
|
|
# E4
|
|
('赤口大人的作祟',
|
|
"Lord Mishaguji's Curse",
|
|
'ミシャグチ様の祟り',
|
|
'미샤구지님의 저주'),
|
|
('交给赤口大人吧!',
|
|
'Leave it to Lord Mishaguji!',
|
|
'ミシャグチ様に任せて!',
|
|
'미샤구지님께 맡겨!'),
|
|
# E5
|
|
('召唤御射宫司大人', 'Summon Lord Mishaguji', '御射宮司様を召喚', '미샤구지님 소환'),
|
|
# E7
|
|
('挖掘', 'Mine', '発掘', '발굴'),
|
|
# §二 sync
|
|
('国士无双之药', 'Peerless Elixir of the Realm', None, None),
|
|
('完美女仆', 'Perfect & Elegant Maid', None, None),
|
|
('红色不夜城', 'Scarlet Sleepless Castle', None, None),
|
|
('红叶传令', 'Crimson Leaf Herald', None, None),
|
|
# §C1
|
|
('建造英雄神像[相]', 'Build Hero Statue [Bishop]', '英雄神像[相]', '영웅 신상 [상] 건설'),
|
|
('建造英雄神像[王]', 'Build Hero Statue [King]', None, '영웅 신상 [왕] 건설'),
|
|
# §C2 红雾 KR
|
|
('清除红雾', None, None, '주홍 안개 제거'),
|
|
('红雾攻击', None, None, '주홍 안개 공격'),
|
|
# §C3 风祝 KR
|
|
('铁血风祝', None, None, '철혈의 바람 무녀'),
|
|
('风祝', None, None, '바람 무녀'),
|
|
# §C4
|
|
('大团长的将棋时间', "Grand Master's Shogi Time", None, None),
|
|
# §D3
|
|
('土豆大王与核能尊神', None, '芋大王と核エネルギーの尊神', '감자 대왕과 핵 에너지 존신'),
|
|
# §D5
|
|
('地毯、咖啡与香料', None, '絨毯・コーヒー・香辛料', None),
|
|
# §D7
|
|
('未遇见', None, None, '만난 적 없음'),
|
|
('未相遇的玩家', None, None, '만난 적 없는 플레이어'),
|
|
# §D10
|
|
('召唤竹林狼', None, None, '대나무 숲 늑대 소환'),
|
|
# §D11
|
|
('简体中文', None, None, '간체 중국어'),
|
|
# §D12
|
|
('我要看到血流成河!', 'I want to see rivers of blood!', None, None),
|
|
('无聊!我要看到血流成河!', 'Boring! I want to see rivers of blood!', None, None),
|
|
]
|
|
|
|
# AI-merge spot checks — these come from Multilingual-ai backup + AI_FIXES
|
|
AI_SPOT = [
|
|
# ZH, EN, JP, KR (post-edit values)
|
|
('正法', 'Dharma', None, '정법'),
|
|
('因缘身', 'Karana-sharira', '原因身', '원인신'),
|
|
('摩诃毗陀罗', 'Maha-Vetala', 'マハー・ヴェターラ', '마하베탈라'),
|
|
('后之雕像', 'Statue of the Queen', '后の彫像', None),
|
|
('Chinese', None, None, '중국어'),
|
|
('伐楼舰', None, None, '바루나함'),
|
|
('[能力:就交给赤口大人吧!]',
|
|
'[Ability: Leave it to Lord Mishaguji!]',
|
|
'[能力:ミシャグチ様に任せて!]',
|
|
'[능력: 미샤구지님께 맡겨!]'),
|
|
]
|
|
|
|
LANG_FILE = {'EN': 'term_en.xlsx', 'JP': 'term_jp.xlsx', 'KR': 'term_kr.xlsx'}
|
|
LANG_IDX = {'EN': 0, 'JP': 1, 'KR': 2}
|
|
|
|
def load_term(path):
|
|
wb = load_workbook(path, read_only=True)
|
|
ws = wb.active
|
|
d = {}
|
|
for row in ws.iter_rows(min_row=2, values_only=True):
|
|
if row[0]:
|
|
d[row[0]] = row[1]
|
|
wb.close()
|
|
return d
|
|
|
|
dict_en = load_term(os.path.join(TERM_DIR, 'term_en.xlsx'))
|
|
dict_jp = load_term(os.path.join(TERM_DIR, 'term_jp.xlsx'))
|
|
dict_kr = load_term(os.path.join(TERM_DIR, 'term_kr.xlsx'))
|
|
DICTS = {'EN': dict_en, 'JP': dict_jp, 'KR': dict_kr}
|
|
|
|
print(f'Row counts: EN={len(dict_en)} JP={len(dict_jp)} KR={len(dict_kr)}')
|
|
print()
|
|
|
|
def check(label, cases):
|
|
pass_n = fail_n = 0
|
|
for case in cases:
|
|
zh, en, jp, kr = case
|
|
for lang, exp in (('EN', en), ('JP', jp), ('KR', kr)):
|
|
if exp is None:
|
|
continue
|
|
actual = DICTS[lang].get(zh, '<MISSING>')
|
|
if actual == exp:
|
|
pass_n += 1
|
|
else:
|
|
fail_n += 1
|
|
print(f' [FAIL] {lang} ZH={zh!r}')
|
|
print(f' expected: {exp!r}')
|
|
print(f' actual : {actual!r}')
|
|
print(f'{label}: {pass_n} pass, {fail_n} fail\n')
|
|
return fail_n
|
|
|
|
f1 = check('term-review fixes', EXPECTED)
|
|
f2 = check('AI merge spot-checks', AI_SPOT)
|
|
total_fail = f1 + f2
|
|
print('=' * 50)
|
|
print(f'TOTAL FAIL: {total_fail}')
|
|
sys.exit(0 if total_fail == 0 else 1)
|