Commit c8746b10 authored by EN1AK's avatar EN1AK Committed by GitHub

Add files via upload

parent 8fcf3768
...@@ -9,33 +9,7 @@ db = None ...@@ -9,33 +9,7 @@ db = None
target_row = None target_row = None
app.secret_key = "你自己的随机 Secret Key" app.secret_key = "你自己的随机 Secret Key"
# --- 与原 CLI 版本相同的配置 --- from map import SETNAME_MAP,RACE_MAP,TYPE_MAP,CATEGORY_TAGS,TYPE_LINK,LINK_MARKERS,SETNAME_MAP ,ATTR_MAP
ATTR_MAP = {
0x01: "地", 0x02: "水", 0x04: "炎", 0x08: "风",
0x10: "光", 0x20: "暗", 0x40: "神"
}
RACE_MAP = {
0x1: "战士", 0x2: "魔法师", 0x4: "天使", 0x8: "恶魔", 0x10: "不死", 0x20: "机械",
0x40: "水", 0x80: "炎", 0x100: "岩石", 0x200: "鸟兽", 0x400: "植物", 0x800: "昆虫",
0x1000: "雷", 0x2000: "龙", 0x4000: "兽", 0x8000: "兽战士", 0x10000: "恐龙",
0x20000: "鱼", 0x40000: "海龙", 0x80000: "爬虫", 0x100000: "念动力", 0x200000: "幻神兽",
0x400000: "创造神", 0x800000: "幻龙", 0x1000000: "电子界", 0x2000000: "幻想魔",
}
TYPE_MAP = {
0x1: "怪兽", 0x2: "魔法", 0x4: "陷阱", 0x10: "通常", 0x20: "效果", 0x40: "融合", 0x80: "仪式",
0x100: "陷阱怪兽", 0x200: "灵魂", 0x400: "同盟", 0x800: "二重", 0x1000: "调整", 0x2000: "同调",
0x4000: "衍生物", 0x10000: "速攻", 0x20000: "永续", 0x40000: "装备", 0x80000: "场地",
0x100000: "反击", 0x200000: "翻转", 0x400000: "卡通", 0x800000: "超量",
0x1000000: "灵摆", 0x2000000: "特殊召唤", 0x4000000: "连接"
}
CATEGORY_TAGS = {
1100: '魔陷破坏', 1101: '怪兽破坏', 1102: '卡片除外', 1103: '送去墓地', 1104: '返回手卡', 1105: '返回卡组',
1106: '手卡破坏', 1107: '卡组破坏', 1108: '抽卡辅助', 1109: '卡组检索', 1110: '卡片回收', 1111: '表示形式',
1112: '控制权', 1113: '攻守变化', 1114: '穿刺伤害', 1115: '多次攻击', 1116: '攻击限制', 1117: '直接攻击',
1118: '特殊召唤', 1119: '衍生物', 1120: '种族相关', 1121: '属性相关', 1122: 'LP伤害', 1123: 'LP回复',
1124: '破坏耐性', 1125: '效果耐性', 1126: '指示物', 1127: '幸运', 1128: '融合相关', 1129: '同调相关',
1130: '超量相关', 1131: '效果无效'
}
def parse_flags(value, mapping): def parse_flags(value, mapping):
return [name for bit, name in mapping.items() if value & bit] return [name for bit, name in mapping.items() if value & bit]
...@@ -43,11 +17,38 @@ def parse_flags(value, mapping): ...@@ -43,11 +17,38 @@ def parse_flags(value, mapping):
def parse_category(cat): def parse_category(cat):
return [CATEGORY_TAGS[1100 + i] for i in range(64) if (cat >> i) & 1 and (1100 + i) in CATEGORY_TAGS] return [CATEGORY_TAGS[1100 + i] for i in range(64) if (cat >> i) & 1 and (1100 + i) in CATEGORY_TAGS]
def parse_setcode(setcode, name_map):
# 1. 转成大写十六进制字符串
hex_str = f"{setcode:X}"
# 2. 左侧补零,使长度成为 4 的倍数
pad_len = (-len(hex_str)) % 4
if pad_len:
hex_str = hex_str.zfill(len(hex_str) + pad_len)
# 3. 每 4 位一组
names = []
for i in range(0, len(hex_str), 4):
segment = hex_str[i:i+4]
# 全 0 的段跳过
if segment == "0000":
continue
code = int(segment, 16)
if code in name_map:
names.append(name_map[code])
return names
def extract_arrows(def_value):
"""
从 link_marker 的整数值中提取出 所有 生效的箭头符号,返回一个列表。
"""
return [sym for bit, sym in LINK_MARKERS.items() if def_value & bit]
def load_card_database(path): def load_card_database(path):
conn = sqlite3.connect(path) conn = sqlite3.connect(path)
# 先把两个表读进 DataFrame # 先把两个表读进 DataFrame
datas = pd.read_sql_query( datas = pd.read_sql_query(
"SELECT id, type, atk, def, level, race, attribute, category ,hot FROM datas", "SELECT id, type, atk, def, level, race, attribute, category ,hot,setcode FROM datas",
conn, index_col="id" conn, index_col="id"
) )
texts = pd.read_sql_query( texts = pd.read_sql_query(
...@@ -64,20 +65,44 @@ def load_card_database(path): ...@@ -64,20 +65,44 @@ def load_card_database(path):
return df return df
def card_to_tags(row): def card_to_tags(row):
is_link = bool(row["type"] & TYPE_LINK)
# 链接怪兽的“守备”清空
defense = "" if is_link else row["def"]
# 如果是链接怪兽,从 link_marker 提取箭头
arrows = extract_arrows(row["def"]) if is_link else []
return { return {
"卡名": row["name"], "卡名": row["name"],
"攻击": row["atk"], "攻击": row["atk"],
"守备": row["def"], "守备": defense,
"等级": row["level"] & 0xFF, "等级": row["level"] & 0xFF,
"箭头": arrows,
"刻度": (row["level"] >> 24) & 0xFF, "刻度": (row["level"] >> 24) & 0xFF,
"类型": parse_flags(row["type"], TYPE_MAP), "类型": parse_flags(row["type"], TYPE_MAP),
"属性": ATTR_MAP.get(row["attribute"], f"0x{row['attribute']:X}"), "属性": ATTR_MAP.get(row["attribute"], f"0x{row['attribute']:X}"),
"种族": RACE_MAP.get(row["race"], f"0x{row['race']:X}"), "种族": RACE_MAP.get(row["race"], f"0x{row['race']:X}"),
"效果标签": parse_category(row["category"]) "效果标签": parse_category(row["category"]),
"系列": parse_setcode(row["setcode"], SETNAME_MAP),
} }
def compare_tags(guess_tags, answer_tags): def compare_tags(guess_tags, answer_tags):
def cmp(key, val1, val2): def cmp(key, val1, val2):
if val1 is None or val1 == "" or val2 is None or val2 == "":
# 要么是用户没猜,要么目标也无该字段,都算“未猜”
return '<span class="partial">—</span>'
if key == "箭头":
pills = []
# 对八个方向都展示一个小标签
for bit, sym in LINK_MARKERS.items():
if sym in val1:
# 猜的里有
cls = "tag-green" if sym in val2 else "tag-red"
else:
# 猜的里没有
cls = "tag-gray"
pills.append(f'<span class="tag {cls}">{sym}</span>')
return " ".join(pills)
# 数值型字段:攻击、守备、等级、刻度 # 数值型字段:攻击、守备、等级、刻度
if isinstance(val1, numbers.Number): if isinstance(val1, numbers.Number):
diff = abs(val1 - val2) diff = abs(val1 - val2)
...@@ -106,13 +131,13 @@ def compare_tags(guess_tags, answer_tags): ...@@ -106,13 +131,13 @@ def compare_tags(guess_tags, answer_tags):
pills = [] pills = []
for t in val1: for t in val1:
# 猜的 tag 在目标里才 green,否则 red # 猜的 tag 在目标里才 green,否则 red
cls = "tag-green" if t in val2 else "tag-red" cls = "tag-green" if t in val2 else "tag-gray"
pills.append(f'<span class="tag {cls}">{t}</span>') pills.append(f'<span class="tag {cls}">{t}</span>')
return " ".join(pills) or '<span class="tag tag-gray">—</span>' return " ".join(pills) or '<span class="tag tag-gray">—</span>'
# 其它(字符串等)完全匹配才 green,否则 gray # 其它(字符串等)完全匹配才 green,否则 gray
else: else:
cls = "tag-green" if val1 == val2 else "tag-gray" cls = "tag-green" if val1 == val2 else "tag-gray "
return f'<span class="tag {cls}">{val1}</span>' return f'<span class="tag {cls}">{val1}</span>'
return { return {
...@@ -150,6 +175,7 @@ def start(): ...@@ -150,6 +175,7 @@ def start():
# 随机选一个 target_id # 随机选一个 target_id
pool = filter_db(mode) pool = filter_db(mode)
session['target_id'] = int(pool.sample(1).index[0]) session['target_id'] = int(pool.sample(1).index[0])
#session['target_id'] = 71818935
# 重置本局提示相关状态 # 重置本局提示相关状态
session['guess_count'] = 0 session['guess_count'] = 0
session['hints_shown'] = [] session['hints_shown'] = []
...@@ -160,9 +186,16 @@ def start(): ...@@ -160,9 +186,16 @@ def start():
def game(): def game():
feedback = None feedback = None
mode = session.get('mode') mode = session.get('mode')
if not mode or 'target_id' not in session: if not mode :
return redirect(url_for("start")) return redirect(url_for("start"))
if 'target_id' not in session:
pool = filter_db(mode)
session['target_id'] = int(pool.sample(1).index[0])
session['history'] = []
session['hints'] = []
session['hinted_chars'] = []
filtered = filter_db(mode) filtered = filter_db(mode)
target = db.loc[session['target_id']] target = db.loc[session['target_id']]
...@@ -174,6 +207,13 @@ def game(): ...@@ -174,6 +207,13 @@ def game():
if request.method == "POST": if request.method == "POST":
action = request.form.get("action", "guess") action = request.form.get("action", "guess")
if action == "change_mode":
new_mode = request.form.get("mode")
session['mode'] = new_mode
# 直接把上一行 target_id 删掉,触发上面自动重置
session.pop('target_id', None)
return redirect(url_for("game"))
if action == "surrender": if action == "surrender":
# 认输 # 认输
feedback = {"giveup": True, "answer": target["name"], "hints": hints} feedback = {"giveup": True, "answer": target["name"], "hints": hints}
...@@ -189,7 +229,7 @@ def game(): ...@@ -189,7 +229,7 @@ def game():
session.pop('history', None) session.pop('history', None)
session.pop('hints', None) session.pop('hints', None)
session.pop('hinted_chars', None) session.pop('hinted_chars', None)
return redirect(url_for("start")) return redirect(url_for("game"))
else: else:
# 普通猜测 # 普通猜测
...@@ -202,9 +242,17 @@ def game(): ...@@ -202,9 +242,17 @@ def game():
else: else:
guess = match.iloc[0] guess = match.iloc[0]
if guess.name == target.name: if guess.name == target.name:
# 猜中 # 1. 先做一次对比
compare = compare_tags(card_to_tags(guess), card_to_tags(target))
# 2. 把这条全绿记录追加到本局历史
history.append({
"guess_name": guess['name'],
"compare": compare
})
# 3. 带上 compare 和 hints 给模板渲染
feedback = { feedback = {
"success": f"🎉 恭喜你猜中了!答案就是【{guess['name']}】", "success": f"🎉 恭喜你猜中了!答案就是【{guess['name']}】",
"compare": compare,
"hints": hints "hints": hints
} }
# 清理本局 session # 清理本局 session
...@@ -258,7 +306,8 @@ def game(): ...@@ -258,7 +306,8 @@ def game():
return render_template("index.html", return render_template("index.html",
feedback=feedback, feedback=feedback,
history=history, history=history,
hints=hints) hints=hints,
mode=mode)
@app.route("/suggest") @app.route("/suggest")
def suggest(): def suggest():
......
ATTR_MAP = {
0x01: "地", 0x02: "水", 0x04: "炎", 0x08: "风",
0x10: "光", 0x20: "暗", 0x40: "神"
}
RACE_MAP = {
0x1: "战士", 0x2: "魔法师", 0x4: "天使", 0x8: "恶魔", 0x10: "不死", 0x20: "机械",
0x40: "水", 0x80: "炎", 0x100: "岩石", 0x200: "鸟兽", 0x400: "植物", 0x800: "昆虫",
0x1000: "雷", 0x2000: "龙", 0x4000: "兽", 0x8000: "兽战士", 0x10000: "恐龙",
0x20000: "鱼", 0x40000: "海龙", 0x80000: "爬虫", 0x100000: "念动力", 0x200000: "幻神兽",
0x400000: "创造神", 0x800000: "幻龙", 0x1000000: "电子界", 0x2000000: "幻想魔",
}
TYPE_MAP = {
0x1: "怪兽", 0x2: "魔法", 0x4: "陷阱", 0x10: "通常", 0x20: "效果", 0x40: "融合", 0x80: "仪式",
0x100: "陷阱怪兽", 0x200: "灵魂", 0x400: "同盟", 0x800: "二重", 0x1000: "调整", 0x2000: "同调",
0x4000: "衍生物", 0x10000: "速攻", 0x20000: "永续", 0x40000: "装备", 0x80000: "场地",
0x100000: "反击", 0x200000: "翻转", 0x400000: "卡通", 0x800000: "超量",
0x1000000: "灵摆", 0x2000000: "特殊召唤", 0x4000000: "连接"
}
CATEGORY_TAGS = {
1100: '魔陷破坏', 1101: '怪兽破坏', 1102: '卡片除外', 1103: '送去墓地', 1104: '返回手卡', 1105: '返回卡组',
1106: '手卡破坏', 1107: '卡组破坏', 1108: '抽卡辅助', 1109: '卡组检索', 1110: '卡片回收', 1111: '表示形式',
1112: '控制权', 1113: '攻守变化', 1114: '穿刺伤害', 1115: '多次攻击', 1116: '攻击限制', 1117: '直接攻击',
1118: '特殊召唤', 1119: '衍生物', 1120: '种族相关', 1121: '属性相关', 1122: 'LP伤害', 1123: 'LP回复',
1124: '破坏耐性', 1125: '效果耐性', 1126: '指示物', 1127: '幸运', 1128: '融合相关', 1129: '同调相关',
1130: '超量相关', 1131: '效果无效'
}
TYPE_LINK = 0x4000000
LINK_MARKERS = {
0x040: "↖", # TOP_LEFT
0x080: "↑", # TOP
0x100: "↗", # TOP_RIGHT
0x008: "←", # LEFT
0x020: "→", # RIGHT
0x001: "↙", # BOTTOM_LEFT
0x002: "↓", # BOTTOM
0x004: "↘", # BOTTOM_RIGHT
}
SETNAME_MAP = {
0x1: "正义盟军",
0x2: "次世代",
0x1002: "真次世代",
0x3: "魅惑的女王",
0x4: "亚马逊",
0x5: "秘仪之力",
0x6: "暗黑界",
0x7: "古代的机械",
0x8: "英雄",
0x3008: "元素英雄",
0x5008: "幻影英雄",
0x6008: "邪心英雄",
0xa008: "假面英雄",
0xc008: "命运英雄",
0x9: "新宇",
0xa: "入魔",
0x100a: "侵入魔鬼",
0xb: "永火",
0xc: "外星",
0xd: "剑士",
0x100d: "X-剑士",
0x400d: "元素灵剑士",
0xe: "电气",
0xf: "扰乱",
0x10: "薰风",
0x11: "机巧",
0x12: "青蛙",
0x13: "机皇",
0x3013: "机皇帝",
0x5013: "机皇神",
0x6013: "机皇兵",
0x15: "巨大战舰",
0x16: "机人",
0x1016: "交通机人",
0x2016: "疾行机人",
0x17: "同调",
0x1017: "同调士",
0x2017: "同调龙",
0x18: "云魔物",
0x19: "剑斗",
0x1019: "剑斗兽",
0x1a: "黑蝎",
0x1b: "幻兽",
0x101b: "幻兽机",
0x1c: "死之信息",
0x1d: "核成",
0x1e: "茧状体",
0x1f: "新空间侠",
0x20: "紫炎",
0x21: "地缚",
0x1021: "地缚神",
0x22: "朱罗纪",
0x23: "罪",
0x24: "废铁",
0x25: "链",
0x26: "变形斗士",
0x27: "科技属",
0x28: "电池人",
0x29: "龙骑兵团",
0x2a: "自然",
0x2b: "忍者",
0x2c: "炎狱",
0x2e: "守墓",
0x2f: "冰结界",
0x30: "大日",
0x31: "命运女郎",
0x32: "火山",
0x33: "黑羽",
0x1033: "强袭黑羽",
0x34: "宝玉",
0x1034: "宝玉兽",
0x2034: "究极宝玉神",
0x5034: "高等宝玉兽",
0x35: "魔轰神",
0x36: "机甲",
0x37: "霞之谷",
0x38: "光道",
0x39: "熔岩",
0x3a: "遗式",
0x3b: "真红眼",
0x3c: "爬虫妖",
0x103d: "六武众",
0x203d: "六武式",
0x903d: "影六武众",
0x3e: "异虫",
0x3f: "救世",
0x40: "被封印",
0x41: "LV",
0x42: "极星",
0x3042: "极星天",
0x5042: "极星宝",
0x6042: "极星兽",
0xa042: "极星灵",
0x43: "废品",
0x44: "代行者",
0x45: "恶魔",
0x1045: "红莲魔",
0x46: "融合",
0x1046: "融合龙",
0x47: "宝石",
0x1047: "宝石骑士",
0x48: "No.",
0x1048: "混沌No.",
0x49: "铳士",
0x4a: "时械神",
0x4b: "极神",
0x4c: "落穴",
0x304e: "进化虫",
0x504e: "进化帝",
0x604e: "进化龙",
0x104f: "爆裂体",
0x50: "蛇毒",
0x1050: "凶饿毒",
0x51: "零件",
0x52: "守护者",
0x1052: "门之守护神",
0x2052: "法理守护者",
0x53: "星圣",
0x54: "我我我",
0x55: "光子",
0x56: "甲虫装机",
0x57: "共鸣者",
0x58: "发条",
0x59: "隆隆隆",
0x5a: "企鹅",
0x5b: "番茄小子",
0x5c: "斯芬克斯",
0x60: "竹光",
0x61: "忍法",
0x62: "卡通",
0x63: "反应机",
0x64: "鹰身",
0x65: "侵略的",
0x66: "战士",
0x1066: "音响战士",
0x2066: "磁石战士",
0x69: "圣刻",
0x6a: "幻蝶刺客",
0x6b: "保镖",
0x6d: "魔人",
0x6e: "魔导",
0x106e: "魔导书",
0x6f: "英豪",
0x106f: "英豪挑战者",
0x70: "先史遗产",
0x71: "魔偶甜点",
0x72: "齿轮齿轮",
0x1072: "齿轮齿轮人",
0x73: "超量",
0x1073: "混沌超量",
0x2073: "超量龙",
0x4073: "铠装超量",
0x74: "水精鳞",
0x75: "深渊",
0x76: "纹章兽",
0x77: "海皇",
0x78: "迅捷",
0x79: "炎星",
0x107a: "圣骑士",
0x207a: "圣剑",
0x507a: "焰圣骑士",
0x607a: "焰圣剑",
0x7b: "银河",
0x107b: "银河眼",
0x307b: "银河眼时空龙",
0x7c: "炎舞",
0x7d: "阳炎",
0x107d: "阳炎兽",
0x7e: "异热同心",
0x107e: "异热同心武器",
0x207e: "异热同心从者",
0x7f: "霍普",
0x107f: "希望皇 霍普",
0x207f: "未来皇 霍普",
0x80: "尘妖",
0x81: "炎王",
0x1081: "炎王兽",
0x82: "怒怒怒",
0x83: "人偶",
0x1083: "机关傀儡",
0x1084: "燃烧拳击手",
0x85: "超级防卫机器人",
0x86: "光天使",
0x87: "阴影",
0x88: "武神",
0x89: "洞",
0x108a: "虫惑魔",
0x8b: "食恶",
0x8d: "鬼计",
0x8e: "吸血鬼",
0x8f: "刷拉拉",
0x90: "森罗",
0x91: "王家长眠之谷",
0x92: "纹章",
0x93: "电子",
0x1093: "电子龙",
0x2093: "电子化天使",
0x4093: "电子暗黑",
0x94: "电子科技",
0x95: "升阶魔法",
0x96: "电子鱼人",
0x97: "古遗物",
0x98: "魔术师",
0x99: "异色眼",
0x10a2: "黑魔术",
0x20a2: "魔术少女",
0x30a2: "黑魔术少女",
0xa3: "星尘",
0xa4: "栗子球",
0x10a4: "羽翼栗子球",
0xa5: "变化",
0xa6: "幼芽",
0xa7: "阿托利斯",
0xa8: "兰斯洛特",
0xa9: "毛绒动物",
0xaa: "机壳",
0x10aa: "隐藏的机壳",
0xab: "文具电子人",
0xac: "哥布林",
0x10ac: "哥布林骑手",
0xad: "魔玩具",
0xae: "契约书",
0xaf: "DD",
0x10af: "DDD",
0xb0: "加特姆士",
0xb1: "彼岸",
0xb2: "超级运动员",
0xb3: "妖仙兽",
0xb4: "影灵衣",
0xb5: "灵兽",
0x10b5: "灵兽使",
0x20b5: "精灵兽",
0x40b5: "圣灵兽骑",
0xb6: "外神",
0xb7: "旧神",
0xb8: "古神",
0xb9: "烈焰加农炮",
0xba: "急袭猛禽",
0xbb: "狱火机",
0xbc: "人造人",
0xbd: "暗黑骑士 盖亚",
0xbe: "帝王",
0xbf: "灵使",
0xc0: "凭依",
0x10c0: "凭依装着",
0xc1: "PSY骨架",
0x10c1: "PSY骨架装备",
0xc2: "动力工具",
0xc3: "锋利小鬼",
0xc4: "神数",
0xc5: "炼狱",
0xc6: "娱乐法师",
0xc7: "龙剑士",
0xc8: "点火骑士",
0xc9: "芳香",
0xca: "魔装战士",
0xcb: "以太神兵龙",
0xcc: "占术姬",
0xcd: "水伶女",
0xce: "水族馆",
0xcf: "混沌",
0x10cf: "混沌战士",
0xd0: "威风妖怪",
0xd1: "灰篮",
0xd2: "星际仙踪",
0xd3: "坏兽",
0xd4: "伯吉斯异兽",
0xd5: "但丁",
0xd6: "破坏剑",
0xd7: "破坏之剑士",
0xd8: "雾动机龙",
0xd9: "不知火",
0x10d9: "妖刀-不知火",
0xda: "龙魔王",
0xdb: "幻影",
0x10db: "幻影骑士团",
0xdc: "超级量子",
0x10dc: "超级量子战士",
0x20dc: "超级量子机兽",
0xdd: "青眼",
0xde: "艾克佐迪亚",
0xdf: "月光",
0xe0: "无形噬体",
0xe1: "炼装",
0xe2: "三形金字塔",
0xe3: "方界",
0xe4: "精灵剑士",
0xe5: "光波",
0x10e5: "光波龙",
0xe6: "花札卫",
0xe7: "沉默剑士",
0xe8: "沉默魔术师",
0xe9: "磁石战士",
0xea: "水晶机巧",
0xeb: "化合兽",
0x10ec: "魔界剧团",
0x20ec: "魔界台本",
0xed: "地中族",
0x10ed: "地中族邪界",
0xee: "秘旋谍",
0x10ee: "秘旋谍装备",
0x20ee: "秘旋谍任务",
0xef: "堕天使",
0xf0: "风魔女",
0xf1: "十二兽",
0xf2: "灵摆",
0x10f2: "灵摆龙",
0x20f2: "灵摆读阵",
0xf3: "捕食",
0x10f3: "捕食植物",
0xf4: "召唤兽",
0xf5: "甘多拉",
0xf6: "摩天楼",
0xf7: "抒情歌鸲",
0xf8: "霸王门",
0x10f8: "霸王门",
0x20f8: "霸王眷龙",
0xf9: "真龙",
0xfa: "幻煌龙",
0xfb: "淘气仙星",
0xfc: "刚鬼",
0xfd: "星杯",
0xfe: "星遗物",
0xff: "幻透翼",
0x100: "化学结合",
0x101: "码语者",
0x102: "弹丸",
0x103: "幻变骚灵",
0x104: "机怪虫",
0x105: "玄化",
0x106: "复仇死者",
0x107: "方程式运动员",
0x108: "魔弹",
0x109: "天气",
0x10a: "珀耳修斯",
0x10b: "廷达魔三角",
0x10c: "机界骑士",
0x10d: "魔导兽",
0x10e: "进化药",
0x10f: "枪管",
0x110: "纳祭",
0x1110: "眼纳祭神",
0x111: "武装龙",
0x112: "幻崩",
0x113: "灵神",
0x114: "空牙团",
0x115: "闪刀",
0x1115: "闪刀姬",
0x116: "圣像骑士",
0x117: "魔神仪",
0x118: "电脑网",
0x119: "转生炎兽",
0x11a: "恐龙摔跤手",
0x11b: "自奏圣乐",
0x11c: "雷龙",
0x11d: "禁忌的",
0x11e: "未界域",
0x11f: "奈芙提斯",
0x120: "调皮宝贝",
0x121: "魔妖",
0x122: "女武神",
0x123: "蔷薇",
0x1123:"蔷薇龙",
0x124: "机械天使",
0x125: "笑容",
0x126: "时间潜行者",
0x127: "无限起动",
0x128: "魔女术",
0x129: "咒眼",
0x12a: "恩底弥翁",
0x12b: "海晶少女",
0x12c: "天威",
0x12d: "斯摩夫",
0x12e: "占卜魔女",
0x12f: "蜂军",
0x130: "破械",
0x1130:"破械神",
0x131: "梦魔镜",
0x132: "斩机",
0x133: "半龙女仆",
0x134: "王战",
0x135: "@火灵天星",
0x136: "“艾”",
0x137: "战华",
0x138: "巨石遗物",
0x139: "守护神官",
0x13a: "拟声",
0x13b: "叛逆",
0x13c: "代码破坏者",
0x13d: "星义",
0x13e: "巴巴罗斯",
0x13f: "海造贼",
0x140: "魔救",
0x141: "六花",
0x142: "黄金国巫妖",
0x2142: "黄金国永生药",
0x143: "黄金乡",
0x144: "幻魔",
0x145: "教导",
0x146: "童话动物",
0x147: "波波",
0x148: "罗兰",
0x149: "化石",
0x14a: "源数",
0x114a: "源数之门",
0x14b: "机块",
0x314c: "地灵术",
0x514c: "水灵术",
0x614c: "火灵术",
0x914c: "风灵术",
0x14d: "铁兽",
0x14e: "电脑堺",
0x114e: "电脑堺门",
0x14f: "双天",
0x150: "大贤者",
0x1151: "直播☆双子",
0x2151: "邪恶★双子",
0x152: "姬丝基勒",
0x153: "璃拉",
0x154: "龙辉巧",
0x155: "护宝炮妖",
0x156: "治安战警队",
0x157: "秘异三变",
0x158: "圣蔓",
0x2158: "圣天树",
0x4158: "圣种",
0x159: "圣夜骑士",
0x15a: "人偶怪兽",
0x15b: "惊乐",
0x15c: "游乐设施",
0x15d: "烙印",
0x15e: "降阶魔法",
0x15f: "战吼",
0x160: "原质炉",
0x161: "溟界",
0x162: "七音服",
0x1162: "大钢琴之七音服",
0x163: "北极天熊",
0x164: "死狱乡",
0x165: "魔键",
0x166: "军贯",
0x1167: "森之圣兽",
0x2167: "森之圣灵",
0x168: "隐形水母怪",
0x169: "原数天灵",
0x16a: "编号系",
0x16b: "相剑",
0x16c: "冰水",
0x16d: "随风旅鸟",
0x16e: "拓扑",
0x16f: "许珀里翁",
0x170: "骑甲虫",
0x171: "朋克",
0x172: "救祓少女",
0x173: "恐啡肽狂龙",
0x174: "恶魔娘",
0x175: "七皇",
0x176: "异晶人的",
0x177: "海龙神",
0x178: "潜海",
0x179: "兽带斗神",
0x17a: "恐吓爪牙族",
0x17b: "野蛮人",
0x17c: "书灵师",
0x17d: "群豪",
0x17e: "拉比林斯迷宫",
0x117e: "拉比林斯迷宫欢迎",
0x17f: "神碑",
0x180: "卫星闪灵",
0x181: "珠泪哀歌族",
0x182: "春化精",
0x183: "悠悠",
0x184: "翼侠",
0x1185: "涂鸦兽",
0x2185: "涂鸦本",
0x186: "G石人",
0x187: "桥梁",
0x188: "深渊之兽",
0x189: "俱舍怒威族",
0x18a: "魊影",
0x18b: "救援ACE队",
0x18c: "纯爱妖精",
0x18d: "御巫",
0x18e: "仪水镜",
0x18f: "防火",
0x190: "末那愚子族",
0x191: "妮穆蕾莉娅",
0x192: "黄金荣耀",
0x193: "迷宫壁",
0x194: "至爱",
0x195: "征服斗魂",
0x196: "新式魔厨",
0x197: "食谱",
0x198: "维萨斯",
0x199: "反击",
0x19a: "吠陀",
0x19b: "迪亚贝尔",
0x119b: "迪亚贝尔斯塔尔",
0x19c: "蛇眼",
0x19d: "荷鲁斯",
0x119d: "荷鲁斯之黑炎龙",
0x19e: "罪宝",
0x19f: "圣菓使",
0x1a0: "哈特",
0x1a1: "莫忘",
0x1a2: "百夫长骑士",
0x1a3: "异响鸣",
0x1a4: "提斯蒂娜",
0x1a5: "于贝尔",
0x1a6: "肃声",
0x1a7: "白斗气",
0x1a8: "玩具",
0x1a9: "灿幻",
0x1aa: "天杯龙",
0x1ab: "蕾禍",
0x1ac: "飞龙炎",
0x1ad: "灰灭",
0x1ae: "千年",
0x1af: "艾格佐德",
0x1b0: "刻魔",
0x1b1: "白森林",
0x1b2: "欢聚友伴",
0x1b3: "徽记",
0x1b4: "时空",
0x1b5: "蓝泪",
0x1b6: "石版",
0x1b7: "拟箱掳尸",
0x1b8: "鲨",
0x11b8: "鲨龙兽",
0x1b9: "原石",
0x1ba: "金属化",
0x1bb: "魔瞳",
0x1bc: "蓟花",
0x1bd: "祝台",
0x1be: "雷火沸动",
0x1bf: "码丽丝",
0x1c0: "龙华",
0x1c1: "阿尔戈☆群星",
0x1c2: "喷水引擎",
0x1c3: "御剑",
0x1c4: "征龙",
0x1c5: "再世",
0x1c6: "统王",
0x1c7: "塞勒凯特",
0x1c8: "阿匹卜",
0x1c9: "星辰",
0x1ca: "味美喵",
0x1cb: "K9",
}
...@@ -34,20 +34,85 @@ ...@@ -34,20 +34,85 @@
.partial { background-color: #fff9c4; } .partial { background-color: #fff9c4; }
.mismatch { background-color: #ffcdd2; } .mismatch { background-color: #ffcdd2; }
button { margin-left: 8px; } button { margin-left: 8px; }
.hint-box {
margin: 1em 0;
padding: 0.5em;
background: #fff3cd;
border: 1px solid #ffeeba;
border-radius: 4px;
color: #856404;
}
.arrow-grid {
display: grid;
grid-template-rows: repeat(3, 1.5em);
grid-template-columns: repeat(3, 1.5em);
gap: 2px;
}
.arrow-cell {
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2em;
border: 1px solid #ccc;
border-radius: 4px;
}
.arrow-cell.empty {
border: none;
background: transparent;
}
.arrow-cell.cell-green { background: #c8e6c9; }
.arrow-cell.cell-red { background: #ffcdd2; }
.arrow-cell.cell-black { background: #eeeeee; }
.tag {
display: inline-block;
padding: 2px 6px;
margin: 1px;
border-radius: 4px;
font-size: 0.9em;
}
.tag-green { background: #c8e6c9; }
.tag-yellow { background: #fff9c4; }
.tag-gray { background: #eee; }
.tag-red { background: #ffcdd2; }
</style> </style>
</head> </head>
<body> <body>
<h1>🎴 游戏王CCB</h1> <h1>🎴 游戏王CCB</h1>
<form method="POST" style="margin-bottom:1em;">
<label>题库:
<select name="mode">
<option value="monster" {% if mode =='monster' %}selected{% endif %}>
怪兽卡(无通常)
</option>
<option value="spell" {% if mode =='spell' %}selected{% endif %}>
魔法卡
</option>
<option value="trap" {% if mode =='trap' %}selected{% endif %}>
陷阱卡
</option>
<option value="hot" {% if mode =='hot' %}selected{% endif %}>
热门卡
</option>
<option value="all" {% if mode =='all' %}selected{% endif %}>
所有卡
</option>
</select>
</label>
<button type="submit" name="action" value="change_mode">切换题库</button>
</form>
<!-- 历史猜测 --> <!-- 历史猜测 -->
{% if history %} {% if history %}
<h2>历史猜测</h2> <h2>历史猜测</h2>
<table> <table>
<thead> <thead>
<tr> <tr>
<th>卡名</th><th>攻击</th><th>守备</th><th>等级</th><th>刻度</th> <th>卡名</th><th>攻击</th><th>守备</th><th>等级</th><th>刻度</th><th>箭头</th>
<th>类型</th><th>属性</th><th>种族</th><th>效果标签</th> <th>类型</th><th>属性</th><th>种族</th><th>效果标签</th><th>系列</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
...@@ -58,10 +123,12 @@ ...@@ -58,10 +123,12 @@
<td>{{ entry.compare['守备']|safe }}</td> <td>{{ entry.compare['守备']|safe }}</td>
<td>{{ entry.compare['等级']|safe }}</td> <td>{{ entry.compare['等级']|safe }}</td>
<td>{{ entry.compare['刻度']|safe }}</td> <td>{{ entry.compare['刻度']|safe }}</td>
<td>{{ entry.compare['箭头']|safe }}</td>
<td style="white-space: nowrap;">{{ entry.compare['类型']|safe }}</td> <td style="white-space: nowrap;">{{ entry.compare['类型']|safe }}</td>
<td style="white-space: nowrap;">{{ entry.compare['属性']|safe }}</td> <td style="white-space: nowrap;">{{ entry.compare['属性']|safe }}</td>
<td style="white-space: nowrap;">{{ entry.compare['种族']|safe }}</td> <td style="white-space: nowrap;">{{ entry.compare['种族']|safe }}</td>
<td style="white-space: nowrap;">{{ entry.compare['效果标签']|safe }}</td> <td style="white-space: nowrap;">{{ entry.compare['效果标签']|safe }}</td>
<td style="white-space: nowrap;">{{ entry.compare['系列']|safe }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
...@@ -78,6 +145,14 @@ ...@@ -78,6 +145,14 @@
<ul id="suggestions" hidden></ul> <ul id="suggestions" hidden></ul>
</form> </form>
{% if hints %}
<div class="hint-box">
{% for h in hints %}
<p>{{ h }}</p>
{% endfor %}
</div>
{% endif %}
<!-- 本次反馈 --> <!-- 本次反馈 -->
{% if feedback %} {% if feedback %}
{% if feedback.error %} {% if feedback.error %}
...@@ -87,9 +162,6 @@ ...@@ -87,9 +162,6 @@
{% elif feedback.giveup %} {% elif feedback.giveup %}
<p style="color:blue; font-weight:bold;">💡 放弃了!正确答案是:{{ feedback.answer }}</p> <p style="color:blue; font-weight:bold;">💡 放弃了!正确答案是:{{ feedback.answer }}</p>
{% elif feedback.compare %} {% elif feedback.compare %}
{% if feedback.hint %}
<p style="color:blue;">💡 提示:卡名中包含 “{{ feedback.hint }}” 这个字</p>
{% endif %}
<h3>你猜的是:<strong>{{ feedback.guess_name }}</strong></h3> <h3>你猜的是:<strong>{{ feedback.guess_name }}</strong></h3>
<table> <table>
<thead><tr><th>属性</th><th>结果</th></tr></thead> <thead><tr><th>属性</th><th>结果</th></tr></thead>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment