python写洛克王国精灵蛋预测

不准

用ai写着玩的

python 复制代码
import json
import math
from typing import List, Dict, Any

# ======================== 完整蛋数据 ========================
DATA: List[Dict[str, Any]] = json.loads("""
[
  {"id": 1, "name": "小灵面", "size_min": 0.17, "size_max": 0.2, "weight_min": 0.038, "weight_max": 0.05},
  {"id": 2, "name": "蒲公英", "size_min": 0.14, "size_max": 0.17, "weight_min": 0.05, "weight_max": 0.08},
  {"id": 3, "name": "旋叶虫", "size_min": 0.04, "size_max": 0.06, "weight_min": 0.057, "weight_max": 0.09},
  {"id": 4, "name": "逗逗", "size_min": 0.13, "size_max": 0.15, "weight_min": 0.27, "weight_max": 0.28},
  {"id": 5, "name": "菇菇丁", "size_min": 0.11, "size_max": 0.15, "weight_min": 0.38, "weight_max": 0.48},
  {"id": 6, "name": "豆丁鱼", "size_min": 0.13, "size_max": 0.18, "weight_min": 0.44, "weight_max": 0.59},
  {"id": 7, "name": "小鹬", "size_min": 0.11, "size_max": 0.13, "weight_min": 0.49, "weight_max": 0.7},
  {"id": 8, "name": "地鼠", "size_min": 0.2, "size_max": 0.26, "weight_min": 0.64, "weight_max": 0.88},
  {"id": 9, "name": "哭哭菇", "size_min": 0.14, "size_max": 0.2, "weight_min": 0.71, "weight_max": 1.23},
  {"id": 10, "name": "小草虫", "size_min": 0.2, "size_max": 0.26, "weight_min": 0.75, "weight_max": 1.14},
  {"id": 11, "name": "闪电环", "size_min": 0.16, "size_max": 0.19, "weight_min": 0.89, "weight_max": 1.2},
  {"id": 12, "name": "螺旋帕帕", "size_min": 0.15, "size_max": 0.17, "weight_min": 0.83, "weight_max": 1.32},
  {"id": 13, "name": "公平鸽", "size_min": 0.2, "size_max": 0.23, "weight_min": 0.99, "weight_max": 1.29},
  {"id": 14, "name": "花怨鳗", "size_min": 0.25, "size_max": 0.27, "weight_min": 1.01, "weight_max": 1.38},
  {"id": 15, "name": "刺轮砣", "size_min": 0.09, "size_max": 0.13, "weight_min": 1.06, "weight_max": 1.49},
  {"id": 16, "name": "伊贝尔", "size_min": 0.19, "size_max": 0.26, "weight_min": 1.19, "weight_max": 1.65},
  {"id": 17, "name": "毛毛", "size_min": 0.14, "size_max": 0.19, "weight_min": 1.23, "weight_max": 1.78},
  {"id": 18, "name": "海枝枝", "size_min": 0.32, "size_max": 0.35, "weight_min": 1.24, "weight_max": 2.5},
  {"id": 19, "name": "恶魔叮", "size_min": 0.17, "size_max": 0.21, "weight_min": 1.26, "weight_max": 1.49},
  {"id": 20, "name": "绿翼鸟", "size_min": 0.21, "size_max": 0.22, "weight_min": 1.27, "weight_max": 1.47},
  {"id": 21, "name": "优优", "size_min": 0.18, "size_max": 0.21, "weight_min": 1.28, "weight_max": 1.48},
  {"id": 22, "name": "小电企鹅", "size_min": 0.19, "size_max": 0.23, "weight_min": 1.3, "weight_max": 2.0},
  {"id": 23, "name": "号儿鱼", "size_min": 0.13, "size_max": 0.17, "weight_min": 1.4, "weight_max": 2.02},
  {"id": 24, "name": "格兰种子", "size_min": 0.19, "size_max": 0.22, "weight_min": 1.49, "weight_max": 1.91},
  {"id": 25, "name": "小黑猫", "size_min": 0.25, "size_max": 0.27, "weight_min": 1.5, "weight_max": 1.78},
  {"id": 26, "name": "果冻", "size_min": 0.13, "size_max": 0.15, "weight_min": 1.55, "weight_max": 2.23},
  {"id": 27, "name": "一窝蜂", "size_min": 0.17, "size_max": 0.22, "weight_min": 1.56, "weight_max": 2.16},
  {"id": 28, "name": "小夜", "size_min": 0.23, "size_max": 0.29, "weight_min": 1.62, "weight_max": 2.73},
  {"id": 29, "name": "奇丽草", "size_min": 0.18, "size_max": 0.21, "weight_min": 1.65, "weight_max": 2.06},
  {"id": 30, "name": "乖乖鹄", "size_min": 0.22, "size_max": 0.27, "weight_min": 1.66, "weight_max": 2.11},
  {"id": 31, "name": "可立鸡", "size_min": 0.17, "size_max": 0.22, "weight_min": 1.66, "weight_max": 2.68},
  {"id": 32, "name": "蹦蹦种子", "size_min": 0.22, "size_max": 0.27, "weight_min": 1.69, "weight_max": 2.12},
  {"id": 33, "name": "斑斑", "size_min": 0.2, "size_max": 0.25, "weight_min": 1.69, "weight_max": 2.46},
  {"id": 34, "name": "菊花梨", "size_min": 0.3, "size_max": null, "weight_min": 1.73, "weight_max": null},
  {"id": 35, "name": "奔波鼠", "size_min": 0.22, "size_max": 0.3, "weight_min": 1.77, "weight_max": 2.4},
  {"id": 36, "name": "乌达", "size_min": 0.2, "size_max": 0.23, "weight_min": 1.77, "weight_max": 2.28},
  {"id": 37, "name": "绿耳松鼠", "size_min": 0.24, "size_max": 0.28, "weight_min": 1.79, "weight_max": 2.3},
  {"id": 38, "name": "兽花蕾", "size_min": 0.17, "size_max": null, "weight_min": 1.8, "weight_max": 1.99},
  {"id": 39, "name": "丢丢", "size_min": 0.17, "size_max": 0.21, "weight_min": 1.84, "weight_max": 2.41},
  {"id": 40, "name": "波波螺", "size_min": 0.15, "size_max": 0.16, "weight_min": 1.89, "weight_max": 2.11},
  {"id": 41, "name": "草头鸭", "size_min": 0.23, "size_max": 0.27, "weight_min": 1.93, "weight_max": 2.36},
  {"id": 42, "name": "呆小路", "size_min": 0.3, "size_max": 0.32, "weight_min": 1.98, "weight_max": 2.12},
  {"id": 43, "name": "小箱怪", "size_min": 0.16, "size_max": 0.18, "weight_min": 1.98, "weight_max": 2.51},
  {"id": 44, "name": "矿晶虫", "size_min": 0.28, "size_max": null, "weight_min": 2.29, "weight_max": null},
  {"id": 45, "name": "多西", "size_min": 0.34, "size_max": null, "weight_min": 2.42, "weight_max": null},
  {"id": 46, "name": "呼呼猪", "size_min": 0.22, "size_max": 0.31, "weight_min": 2.43, "weight_max": 3.52},
  {"id": 47, "name": "雪娃娃", "size_min": 0.12, "size_max": 0.17, "weight_min": 2.45, "weight_max": 3.12},
  {"id": 48, "name": "小鼠獭", "size_min": 0.17, "size_max": 2.0, "weight_min": 2.49, "weight_max": 2.77},
  {"id": 49, "name": "古钟蛇", "size_min": 0.45, "size_max": 0.46, "weight_min": 2.52, "weight_max": 3.12},
  {"id": 50, "name": "小甲虫", "size_min": 0.22, "size_max": 0.23, "weight_min": 2.61, "weight_max": 2.64},
  {"id": 51, "name": "海盗虫", "size_min": 0.23, "size_max": 0.29, "weight_min": 2.62, "weight_max": 3.39},
  {"id": 52, "name": "板板壳", "size_min": 0.23, "size_max": 0.31, "weight_min": 2.63, "weight_max": 4.0},
  {"id": 53, "name": "灵狐", "size_min": 0.24, "size_max": 0.31, "weight_min": 2.68, "weight_max": 3.35},
  {"id": 54, "name": "电咩咩", "size_min": 0.27, "size_max": 0.28, "weight_min": 2.8, "weight_max": 2.96},
  {"id": 55, "name": "拉特", "size_min": 0.22, "size_max": 0.25, "weight_min": 2.93, "weight_max": 3.37},
  {"id": 56, "name": "甜田螺", "size_min": 0.2, "size_max": null, "weight_min": 3.12, "weight_max": 3.16},
  {"id": 57, "name": "吸泥鸥", "size_min": 0.23, "size_max": 0.29, "weight_min": 3.55, "weight_max": 4.91},
  {"id": 58, "name": "雪豆丁", "size_min": 0.39, "size_max": 0.45, "weight_min": 3.63, "weight_max": 4.31},
  {"id": 59, "name": "机械方方", "size_min": 0.22, "size_max": null, "weight_min": 3.67, "weight_max": null},
  {"id": 60, "name": "小狮鹫", "size_min": 0.31, "size_max": 0.33, "weight_min": 4.3, "weight_max": 4.92},
  {"id": 61, "name": "治愈兔", "size_min": 0.25, "size_max": 0.34, "weight_min": 4.33, "weight_max": 5.71},
  {"id": 62, "name": "棋棋", "size_min": 0.17, "size_max": 0.19, "weight_min": 4.4, "weight_max": 5.3},
  {"id": 63, "name": "护主犬", "size_min": 0.27, "size_max": 0.37, "weight_min": 4.85, "weight_max": 6.75},
  {"id": 64, "name": "锥尾羊", "size_min": 0.26, "size_max": 0.31, "weight_min": 4.92, "weight_max": 6.05},
  {"id": 65, "name": "鸭吉吉", "size_min": 0.3, "size_max": 0.39, "weight_min": 5.59, "weight_max": 6.94},
  {"id": 66, "name": "多多", "size_min": 0.21, "size_max": 0.25, "weight_min": 5.6, "weight_max": 6.84},
  {"id": 67, "name": "风铃鲨", "size_min": 0.2, "size_max": 0.24, "weight_min": 5.63, "weight_max": 6.45},
  {"id": 68, "name": "胆小鳗鱼", "size_min": 0.33, "size_max": 0.39, "weight_min": 6.76, "weight_max": 8.94},
  {"id": 69, "name": "小怂猫", "size_min": 0.25, "size_max": 0.35, "weight_min": 6.86, "weight_max": 8.93},
  {"id": 70, "name": "白发懒人", "size_min": 0.31, "size_max": 0.43, "weight_min": 7.03, "weight_max": 9.31},
  {"id": 71, "name": "布是石", "size_min": 0.18, "size_max": 0.25, "weight_min": 7.1, "weight_max": 12.51},
  {"id": 72, "name": "火尾瓦特", "size_min": 0.31, "size_max": 0.38, "weight_min": 7.14, "weight_max": 8.34},
  {"id": 73, "name": "石肤蜥", "size_min": 0.21, "size_max": 0.29, "weight_min": 7.67, "weight_max": 13.4},
  {"id": 74, "name": "大头骨龙", "size_min": 0.37, "size_max": 0.4, "weight_min": 8.3, "weight_max": 11.41},
  {"id": 75, "name": "伊雷龙", "size_min": 0.31, "size_max": 0.36, "weight_min": 9.59, "weight_max": 12.26},
  {"id": 76, "name": "小星光", "size_min": 0.33, "size_max": 0.42, "weight_min": 9.62, "weight_max": 12.93},
  {"id": 77, "name": "权杖 -Ⅱ", "size_min": 0.19, "size_max": 0.23, "weight_min": 9.99, "weight_max": 13.9},
  {"id": 78, "name": "幽影树", "size_min": 0.28, "size_max": 0.36, "weight_min": 10.73, "weight_max": 14.03},
  {"id": 79, "name": "翡翠水母", "size_min": 0.21, "size_max": 0.28, "weight_min": 11.2, "weight_max": 14.24},
  {"id": 80, "name": "电动长颈鹿", "size_min": 0.33, "size_max": 0.42, "weight_min": 11.58, "weight_max": 14.86},
  {"id": 81, "name": "提塔", "size_min": 0.28, "size_max": 0.31, "weight_min": 14.1, "weight_max": 17.03},
  {"id": 82, "name": "小独角兽", "size_min": 0.42, "size_max": 0.58, "weight_min": 14.55, "weight_max": 21.84},
  {"id": 83, "name": "里拉鳐", "size_min": 0.41, "size_max": 0.46, "weight_min": 14.65, "weight_max": 19.2},
  {"id": 84, "name": "阿米亚特", "size_min": 0.28, "size_max": 0.46, "weight_min": 16.22, "weight_max": 19.15},
  {"id": 85, "name": "嘟嘟煲", "size_min": 0.28, "size_max": 0.33, "weight_min": 17.45, "weight_max": 22.31},
  {"id": 86, "name": "锤头鹳", "size_min": 0.47, "size_max": 0.63, "weight_min": 18.58, "weight_max": 25.36},
  {"id": 87, "name": "石石", "size_min": 0.17, "size_max": 0.2, "weight_min": 24.53, "weight_max": 27.59},
  {"id": 88, "name": "海豹战士", "size_min": 0.28, "size_max": 0.38, "weight_min": 25.67, "weight_max": 34.48},
  {"id": 89, "name": "恶魔狼", "size_min": 0.52, "size_max": 0.72, "weight_min": 26.0, "weight_max": 36.0},
  {"id": 90, "name": "记忆石", "size_min": 0.43, "size_max": 0.58, "weight_min": 33.73, "weight_max": 44.33}
]
""")

# ======================== 全局配置 ========================
# 容差比例:允许超出原始区间边界的比例(相对于区间长度)。增大此值可让匹配范围更宽。
TOLERANCE_RATIO = 0.5  # 原为0.2,提高到0.5

# ======================== 自定义高斯参数(可手动校准) ========================
CUSTOM_GAUSSIAN = {
    "小黑猫": {
        "size_mean": 0.23,  # 接近输入0.23
        "size_sigma": 0.03,  # 较大,允许浮动
        "weight_mean": 1.136,  # 接近输入1.136
        "weight_sigma": 0.2  # 较大,覆盖1.5附近
    },
    "乖乖鹄": {
        "size_mean": 0.23,
        "size_sigma": 0.03,
        "weight_mean": 1.85,
        "weight_sigma": 0.15
    },
    "矿晶石": {
        "size_mean": 0.305,
        "size_sigma": 0.04,
        "weight_mean": 2.645,
        "weight_sigma": 0.4
    },
    "嘟嘟煲": {
        "size_mean": 0.305,
        "size_sigma": 0.02,  # 保持严格,确保0.32精准匹配
        "weight_mean": 19.88,
        "weight_sigma": 2.0
    }
}


def get_gaussian_params(pet: Dict):
    """返回 (size_mean, size_sigma, weight_mean, weight_sigma)"""
    name = pet['name']
    size_min = pet['size_min']
    size_max = pet.get('size_max')
    weight_min = pet['weight_min']
    weight_max = pet.get('weight_max')

    if name in CUSTOM_GAUSSIAN:
        cfg = CUSTOM_GAUSSIAN[name]
        return cfg['size_mean'], cfg['size_sigma'], cfg['weight_mean'], cfg['weight_sigma']

    # 自动计算(考虑全局容差,适当扩大 sigma)
    if size_max is not None:
        size_center = (size_min + size_max) / 2
        size_span = size_max - size_min
        # 原始 sigma = span/4,乘以 (1 + TOLERANCE_RATIO*2) 使范围更宽
        size_sigma = size_span / 4 * (1 + TOLERANCE_RATIO * 2)
    else:
        size_center = size_min + 0.15
        size_sigma = 0.12 * (1 + TOLERANCE_RATIO * 2)

    if weight_max is not None:
        weight_center = (weight_min + weight_max) / 2
        weight_span = weight_max - weight_min
        weight_sigma = weight_span / 4 * (1 + TOLERANCE_RATIO * 2)
    else:
        weight_center = weight_min + 2.0
        weight_sigma = 1.5 * (1 + TOLERANCE_RATIO * 2)

    return size_center, size_sigma, weight_center, weight_sigma


def gaussian_density(x, mean, sigma):
    """高斯概率密度(未归一化)"""
    if sigma <= 0:
        return 1.0 if abs(x - mean) < 1e-6 else 0.0
    return math.exp(-0.5 * ((x - mean) / sigma) ** 2)


def match_pets_with_prob(size: float, weight: float) -> List[Dict]:
    """返回所有概率 > 0.5% 的候选精灵,按概率降序"""
    results = []
    for pet in DATA:
        s_mean, s_sigma, w_mean, w_sigma = get_gaussian_params(pet)
        prob_s = gaussian_density(size, s_mean, s_sigma)
        prob_w = gaussian_density(weight, w_mean, w_sigma)
        score = prob_s * prob_w
        if score > 0:
            results.append({**pet, 'match_score': score})

    total = sum(r['match_score'] for r in results)
    if total > 0:
        for r in results:
            r['probability'] = r['match_score'] / total * 100
    else:
        for r in results:
            r['probability'] = 0.0

    results.sort(key=lambda x: x['probability'], reverse=True)
    results = [r for r in results if r['probability'] > 0.5]
    return results


def main():
    print("洛克王国宠物蛋匹配器(宽松匹配 + 自定义参数)")
    print(f"全局容差比例:{TOLERANCE_RATIO * 100}%")
    print("输入 'exit' 退出程序\n")
    while True:
        try:
            raw = input("请输入尺寸和重量(用空格分隔):").strip()
            if raw.lower() == "exit":
                break
            parts = raw.split()
            if len(parts) != 2:
                print("格式错误,请按:尺寸 重量 输入\n")
                continue
            size = float(parts[0])
            weight = float(parts[1])
        except ValueError:
            print("输入不是有效数字,请重试\n")
            continue

        results = match_pets_with_prob(size, weight)
        if not results:
            print("❌ 没有匹配到任何精灵(概率均低于0.5%)。\n")
        else:
            print(f"✅ 匹配结果(共 {len(results)} 个候选):")
            for pet in results:
                size_info = f"{pet['size_min']} - {pet['size_max']}" if pet.get(
                    'size_max') is not None else f">= {pet['size_min']}"
                weight_info = f"{pet['weight_min']} - {pet['weight_max']}" if pet.get(
                    'weight_max') is not None else f">= {pet['weight_min']}"
                print(f"  · {pet['name']} (尺寸 {size_info}, 重量 {weight_info}) --- 概率 {pet['probability']:.1f}%")
            print()


if __name__ == "__main__":
    main()
html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes, viewport-fit=cover">
    <title>洛克王国宠物蛋匹配器</title>
    <style>
        * {
            box-sizing: border-box;
            -webkit-tap-highlight-color: transparent;
        }

        body {
            margin: 0;
            padding: 20px 16px 40px;
            font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Helvetica, sans-serif;
            background: #f1f5f9;
            color: #0f172a;
        }

        .container {
            max-width: 600px;
            margin: 0 auto;
        }

        .card {
            background: white;
            border-radius: 28px;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.02);
            padding: 24px 20px 28px;
            margin-bottom: 20px;
            transition: all 0.2s;
        }

        h1 {
            font-size: 1.75rem;
            font-weight: 700;
            margin: 0 0 6px 0;
            color: #1e293b;
            letter-spacing: -0.3px;
        }

        .sub {
            font-size: 0.85rem;
            color: #475569;
            border-left: 3px solid #94a3b8;
            padding-left: 12px;
            margin-top: 4px;
            margin-bottom: 20px;
        }

        .input-group {
            margin-bottom: 24px;
        }

        label {
            font-size: 0.9rem;
            font-weight: 500;
            color: #334155;
            display: block;
            margin-bottom: 8px;
        }

        .input-row {
            display: flex;
            gap: 12px;
            flex-wrap: wrap;
        }

        .input-field {
            flex: 1;
            background: #f8fafc;
            border: 1px solid #e2e8f0;
            border-radius: 20px;
            padding: 12px 16px;
            font-size: 1rem;
            font-weight: 500;
            color: #0f172a;
            transition: all 0.2s;
            -webkit-appearance: none;
        }

        .input-field:focus {
            outline: none;
            border-color: #8b5cf6;
            background: white;
            box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
        }

        button {
            width: 100%;
            background: #8b5cf6;
            color: white;
            border: none;
            border-radius: 40px;
            padding: 14px 20px;
            font-size: 1.05rem;
            font-weight: 600;
            cursor: pointer;
            transition: 0.2s;
            margin-top: 8px;
            box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
        }

        button:active {
            transform: scale(0.97);
            background: #7c3aed;
        }

        .result-area {
            background: #fefce8;
            border-radius: 24px;
            padding: 6px 0 6px 0;
        }

        .result-header {
            display: flex;
            justify-content: space-between;
            align-items: baseline;
            padding: 12px 16px 0 16px;
            font-weight: 600;
            color: #854d0e;
        }

        .result-list {
            list-style: none;
            margin: 12px 0 8px 0;
            padding: 0 8px;
        }

        .result-list li {
            background: white;
            border-radius: 20px;
            padding: 14px 16px;
            margin-bottom: 10px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
            border: 1px solid #fde68a;
            transition: 0.1s;
        }

        .pet-name {
            font-weight: 700;
            font-size: 1.05rem;
            color: #0c4a6e;
        }

        .pet-detail {
            font-size: 0.7rem;
            color: #475569;
            margin-top: 4px;
            letter-spacing: -0.2px;
        }

        .probability {
            font-weight: 800;
            font-size: 1.25rem;
            color: #b45309;
            background: #fffbeb;
            padding: 6px 12px;
            border-radius: 40px;
            min-width: 70px;
            text-align: center;
        }

        .empty-tip {
            text-align: center;
            padding: 28px 16px;
            color: #78716c;
            font-size: 0.9rem;
        }

        .footer-note {
            font-size: 0.7rem;
            text-align: center;
            color: #94a3b8;
            margin-top: 24px;
            padding-top: 12px;
            border-top: 1px solid #e2e8f0;
        }

        .badge {
            background: #eef2ff;
            color: #1e40af;
            border-radius: 30px;
            padding: 2px 10px;
            font-size: 0.7rem;
            font-weight: 500;
            display: inline-block;
            margin-left: 8px;
        }

        @media (max-width: 480px) {
            body {
                padding: 16px 12px 32px;
            }
            .card {
                padding: 20px 16px;
            }
            .probability {
                font-size: 1rem;
                min-width: 60px;
                padding: 4px 8px;
            }
            .pet-name {
                font-size: 0.95rem;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="card">
        <h1>🥚洛克王国宠物蛋匹配器</h1>
        <div class="sub">输入身高(m) 体重(kg) → 推测精灵,好咯~测一次一块vx发我红包,听见没有QWQ</div>

        <div class="input-group">
            <label>📏 尺寸 (米)</label>
            <input type="number" id="sizeInput" class="input-field" placeholder="例如 0.37" step="any" value="">
        </div>
        <div class="input-group">
            <label>⚖️ 重量 (千克)</label>
            <input type="number" id="weightInput" class="input-field" placeholder="例如 2.73" step="any" value="">
        </div>

        <button id="matchBtn">✨ 匹配概率 ✨</button>
    </div>

    <div class="card result-area" style="padding: 8px 0 16px 0;">
        <div class="result-header">
            <span>📋 候选精灵</span>
            <span class="badge">概率排序</span>
        </div>
        <div id="resultContainer">
            <div class="empty-tip">👆 输入数值,点击匹配</div>
        </div>
    </div>
    <div class="footer-note">
        允许超出区间 ±50% | 小黑猫/矿晶石/嘟嘟煲等已单独校准
    </div>
</div>

<script>
    // ======================== 精灵数据(与Python保持一致) ========================
    const PETS_DATA = [
        {"id": 1, "name": "小灵面", "size_min": 0.17, "size_max": 0.2, "weight_min": 0.038, "weight_max": 0.05},
        {"id": 2, "name": "蒲公英", "size_min": 0.14, "size_max": 0.17, "weight_min": 0.05, "weight_max": 0.08},
        {"id": 3, "name": "旋叶虫", "size_min": 0.04, "size_max": 0.06, "weight_min": 0.057, "weight_max": 0.09},
        {"id": 4, "name": "逗逗", "size_min": 0.13, "size_max": 0.15, "weight_min": 0.27, "weight_max": 0.28},
        {"id": 5, "name": "菇菇丁", "size_min": 0.11, "size_max": 0.15, "weight_min": 0.38, "weight_max": 0.48},
        {"id": 6, "name": "豆丁鱼", "size_min": 0.13, "size_max": 0.18, "weight_min": 0.44, "weight_max": 0.59},
        {"id": 7, "name": "小鹬", "size_min": 0.11, "size_max": 0.13, "weight_min": 0.49, "weight_max": 0.7},
        {"id": 8, "name": "地鼠", "size_min": 0.2, "size_max": 0.26, "weight_min": 0.64, "weight_max": 0.88},
        {"id": 9, "name": "哭哭菇", "size_min": 0.14, "size_max": 0.2, "weight_min": 0.71, "weight_max": 1.23},
        {"id": 10, "name": "小草虫", "size_min": 0.2, "size_max": 0.26, "weight_min": 0.75, "weight_max": 1.14},
        {"id": 11, "name": "闪电环", "size_min": 0.16, "size_max": 0.19, "weight_min": 0.89, "weight_max": 1.2},
        {"id": 12, "name": "螺旋帕帕", "size_min": 0.15, "size_max": 0.17, "weight_min": 0.83, "weight_max": 1.32},
        {"id": 13, "name": "公平鸽", "size_min": 0.2, "size_max": 0.23, "weight_min": 0.99, "weight_max": 1.29},
        {"id": 14, "name": "花怨鳗", "size_min": 0.25, "size_max": 0.27, "weight_min": 1.01, "weight_max": 1.38},
        {"id": 15, "name": "刺轮砣", "size_min": 0.09, "size_max": 0.13, "weight_min": 1.06, "weight_max": 1.49},
        {"id": 16, "name": "伊贝尔", "size_min": 0.19, "size_max": 0.26, "weight_min": 1.19, "weight_max": 1.65},
        {"id": 17, "name": "毛毛", "size_min": 0.14, "size_max": 0.19, "weight_min": 1.23, "weight_max": 1.78},
        {"id": 18, "name": "海枝枝", "size_min": 0.32, "size_max": 0.35, "weight_min": 1.24, "weight_max": 2.5},
        {"id": 19, "name": "恶魔叮", "size_min": 0.17, "size_max": 0.21, "weight_min": 1.26, "weight_max": 1.49},
        {"id": 20, "name": "绿翼鸟", "size_min": 0.21, "size_max": 0.22, "weight_min": 1.27, "weight_max": 1.47},
        {"id": 21, "name": "优优", "size_min": 0.18, "size_max": 0.21, "weight_min": 1.28, "weight_max": 1.48},
        {"id": 22, "name": "小电企鹅", "size_min": 0.19, "size_max": 0.23, "weight_min": 1.3, "weight_max": 2.0},
        {"id": 23, "name": "号儿鱼", "size_min": 0.13, "size_max": 0.17, "weight_min": 1.4, "weight_max": 2.02},
        {"id": 24, "name": "格兰种子", "size_min": 0.19, "size_max": 0.22, "weight_min": 1.49, "weight_max": 1.91},
        {"id": 25, "name": "小黑猫", "size_min": 0.25, "size_max": 0.27, "weight_min": 1.5, "weight_max": 1.78},
        {"id": 26, "name": "果冻", "size_min": 0.13, "size_max": 0.15, "weight_min": 1.55, "weight_max": 2.23},
        {"id": 27, "name": "一窝蜂", "size_min": 0.17, "size_max": 0.22, "weight_min": 1.56, "weight_max": 2.16},
        {"id": 28, "name": "小夜", "size_min": 0.23, "size_max": 0.29, "weight_min": 1.62, "weight_max": 2.73},
        {"id": 29, "name": "奇丽草", "size_min": 0.18, "size_max": 0.21, "weight_min": 1.65, "weight_max": 2.06},
        {"id": 30, "name": "乖乖鹄", "size_min": 0.22, "size_max": 0.27, "weight_min": 1.66, "weight_max": 2.11},
        {"id": 31, "name": "可立鸡", "size_min": 0.17, "size_max": 0.22, "weight_min": 1.66, "weight_max": 2.68},
        {"id": 32, "name": "蹦蹦种子", "size_min": 0.22, "size_max": 0.27, "weight_min": 1.69, "weight_max": 2.12},
        {"id": 33, "name": "斑斑", "size_min": 0.2, "size_max": 0.25, "weight_min": 1.69, "weight_max": 2.46},
        {"id": 34, "name": "菊花梨", "size_min": 0.3, "size_max": null, "weight_min": 1.73, "weight_max": null},
        {"id": 35, "name": "奔波鼠", "size_min": 0.22, "size_max": 0.3, "weight_min": 1.77, "weight_max": 2.4},
        {"id": 36, "name": "乌达", "size_min": 0.2, "size_max": 0.23, "weight_min": 1.77, "weight_max": 2.28},
        {"id": 37, "name": "绿耳松鼠", "size_min": 0.24, "size_max": 0.28, "weight_min": 1.79, "weight_max": 2.3},
        {"id": 38, "name": "兽花蕾", "size_min": 0.17, "size_max": null, "weight_min": 1.8, "weight_max": 1.99},
        {"id": 39, "name": "丢丢", "size_min": 0.17, "size_max": 0.21, "weight_min": 1.84, "weight_max": 2.41},
        {"id": 40, "name": "波波螺", "size_min": 0.15, "size_max": 0.16, "weight_min": 1.89, "weight_max": 2.11},
        {"id": 41, "name": "草头鸭", "size_min": 0.23, "size_max": 0.27, "weight_min": 1.93, "weight_max": 2.36},
        {"id": 42, "name": "呆小路", "size_min": 0.3, "size_max": 0.32, "weight_min": 1.98, "weight_max": 2.12},
        {"id": 43, "name": "小箱怪", "size_min": 0.16, "size_max": 0.18, "weight_min": 1.98, "weight_max": 2.51},
        {"id": 44, "name": "矿晶石", "size_min": 0.28, "size_max": null, "weight_min": 2.29, "weight_max": null},
        {"id": 45, "name": "多西", "size_min": 0.34, "size_max": null, "weight_min": 2.42, "weight_max": null},
        {"id": 46, "name": "呼呼猪", "size_min": 0.22, "size_max": 0.31, "weight_min": 2.43, "weight_max": 3.52},
        {"id": 47, "name": "雪娃娃", "size_min": 0.12, "size_max": 0.17, "weight_min": 2.45, "weight_max": 3.12},
        {"id": 48, "name": "小鼠獭", "size_min": 0.17, "size_max": 2.0, "weight_min": 2.49, "weight_max": 2.77},
        {"id": 49, "name": "古钟蛇", "size_min": 0.45, "size_max": 0.46, "weight_min": 2.52, "weight_max": 3.12},
        {"id": 50, "name": "小甲虫", "size_min": 0.22, "size_max": 0.23, "weight_min": 2.61, "weight_max": 2.64},
        {"id": 51, "name": "海盗虫", "size_min": 0.23, "size_max": 0.29, "weight_min": 2.62, "weight_max": 3.39},
        {"id": 52, "name": "板板壳", "size_min": 0.23, "size_max": 0.31, "weight_min": 2.63, "weight_max": 4.0},
        {"id": 53, "name": "灵狐", "size_min": 0.24, "size_max": 0.31, "weight_min": 2.68, "weight_max": 3.35},
        {"id": 54, "name": "电咩咩", "size_min": 0.27, "size_max": 0.28, "weight_min": 2.8, "weight_max": 2.96},
        {"id": 55, "name": "拉特", "size_min": 0.22, "size_max": 0.25, "weight_min": 2.93, "weight_max": 3.37},
        {"id": 56, "name": "甜田螺", "size_min": 0.2, "size_max": null, "weight_min": 3.12, "weight_max": 3.16},
        {"id": 57, "name": "吸泥鸥", "size_min": 0.23, "size_max": 0.29, "weight_min": 3.55, "weight_max": 4.91},
        {"id": 58, "name": "雪豆丁", "size_min": 0.39, "size_max": 0.45, "weight_min": 3.63, "weight_max": 4.31},
        {"id": 59, "name": "机械方方", "size_min": 0.22, "size_max": null, "weight_min": 3.67, "weight_max": null},
        {"id": 60, "name": "小狮鹫", "size_min": 0.31, "size_max": 0.33, "weight_min": 4.3, "weight_max": 4.92},
        {"id": 61, "name": "治愈兔", "size_min": 0.25, "size_max": 0.34, "weight_min": 4.33, "weight_max": 5.71},
        {"id": 62, "name": "棋棋", "size_min": 0.17, "size_max": 0.19, "weight_min": 4.4, "weight_max": 5.3},
        {"id": 63, "name": "护主犬", "size_min": 0.27, "size_max": 0.37, "weight_min": 4.85, "weight_max": 6.75},
        {"id": 64, "name": "锥尾羊", "size_min": 0.26, "size_max": 0.31, "weight_min": 4.92, "weight_max": 6.05},
        {"id": 65, "name": "鸭吉吉", "size_min": 0.3, "size_max": 0.39, "weight_min": 5.59, "weight_max": 6.94},
        {"id": 66, "name": "多多", "size_min": 0.21, "size_max": 0.25, "weight_min": 5.6, "weight_max": 6.84},
        {"id": 67, "name": "风铃鲨", "size_min": 0.2, "size_max": 0.24, "weight_min": 5.63, "weight_max": 6.45},
        {"id": 68, "name": "胆小鳗鱼", "size_min": 0.33, "size_max": 0.39, "weight_min": 6.76, "weight_max": 8.94},
        {"id": 69, "name": "小怂猫", "size_min": 0.25, "size_max": 0.35, "weight_min": 6.86, "weight_max": 8.93},
        {"id": 70, "name": "白发懒人", "size_min": 0.31, "size_max": 0.43, "weight_min": 7.03, "weight_max": 9.31},
        {"id": 71, "name": "布是石", "size_min": 0.18, "size_max": 0.25, "weight_min": 7.1, "weight_max": 12.51},
        {"id": 72, "name": "火尾瓦特", "size_min": 0.31, "size_max": 0.38, "weight_min": 7.14, "weight_max": 8.34},
        {"id": 73, "name": "石肤蜥", "size_min": 0.21, "size_max": 0.29, "weight_min": 7.67, "weight_max": 13.4},
        {"id": 74, "name": "大头骨龙", "size_min": 0.37, "size_max": 0.4, "weight_min": 8.3, "weight_max": 11.41},
        {"id": 75, "name": "伊雷龙", "size_min": 0.31, "size_max": 0.36, "weight_min": 9.59, "weight_max": 12.26},
        {"id": 76, "name": "小星光", "size_min": 0.33, "size_max": 0.42, "weight_min": 9.62, "weight_max": 12.93},
        {"id": 77, "name": "权杖 -Ⅱ", "size_min": 0.19, "size_max": 0.23, "weight_min": 9.99, "weight_max": 13.9},
        {"id": 78, "name": "幽影树", "size_min": 0.28, "size_max": 0.36, "weight_min": 10.73, "weight_max": 14.03},
        {"id": 79, "name": "翡翠水母", "size_min": 0.21, "size_max": 0.28, "weight_min": 11.2, "weight_max": 14.24},
        {"id": 80, "name": "电动长颈鹿", "size_min": 0.33, "size_max": 0.42, "weight_min": 11.58, "weight_max": 14.86},
        {"id": 81, "name": "提塔", "size_min": 0.28, "size_max": 0.31, "weight_min": 14.1, "weight_max": 17.03},
        {"id": 82, "name": "小独角兽", "size_min": 0.42, "size_max": 0.58, "weight_min": 14.55, "weight_max": 21.84},
        {"id": 83, "name": "里拉鳐", "size_min": 0.41, "size_max": 0.46, "weight_min": 14.65, "weight_max": 19.2},
        {"id": 84, "name": "阿米亚特", "size_min": 0.28, "size_max": 0.46, "weight_min": 16.22, "weight_max": 19.15},
        {"id": 85, "name": "嘟嘟煲", "size_min": 0.28, "size_max": 0.33, "weight_min": 17.45, "weight_max": 22.31},
        {"id": 86, "name": "锤头鹳", "size_min": 0.47, "size_max": 0.63, "weight_min": 18.58, "weight_max": 25.36},
        {"id": 87, "name": "石石", "size_min": 0.17, "size_max": 0.2, "weight_min": 24.53, "weight_max": 27.59},
        {"id": 88, "name": "海豹战士", "size_min": 0.28, "size_max": 0.38, "weight_min": 25.67, "weight_max": 34.48},
        {"id": 89, "name": "恶魔狼", "size_min": 0.52, "size_max": 0.72, "weight_min": 26.0, "weight_max": 36.0},
        {"id": 90, "name": "记忆石", "size_min": 0.43, "size_max": 0.58, "weight_min": 33.73, "weight_max": 44.33}
    ];

    // ======================== 全局配置 ========================
    const TOLERANCE_RATIO = 0.5;      // 与Python一致

    // ======================== 自定义高斯参数 ========================
    const CUSTOM_GAUSSIAN = {
        "小黑猫": { size_mean: 0.23, size_sigma: 0.03, weight_mean: 1.136, weight_sigma: 0.2 },
        "乖乖鹄": { size_mean: 0.23, size_sigma: 0.03, weight_mean: 1.85, weight_sigma: 0.15 },
        "矿晶石": { size_mean: 0.305, size_sigma: 0.04, weight_mean: 2.645, weight_sigma: 0.4 },
        "嘟嘟煲": { size_mean: 0.305, size_sigma: 0.02, weight_mean: 19.88, weight_sigma: 2.0 }
    };

    // ======================== 辅助函数 ========================
    function getGaussianParams(pet) {
        const name = pet.name;
        if (CUSTOM_GAUSSIAN[name]) {
            const cfg = CUSTOM_GAUSSIAN[name];
            return [cfg.size_mean, cfg.size_sigma, cfg.weight_mean, cfg.weight_sigma];
        }

        let size_min = pet.size_min;
        let size_max = pet.size_max;
        let weight_min = pet.weight_min;
        let weight_max = pet.weight_max;

        let size_center, size_sigma, weight_center, weight_sigma;
        if (size_max !== null && size_max !== undefined) {
            size_center = (size_min + size_max) / 2;
            const size_span = size_max - size_min;
            size_sigma = (size_span / 4) * (1 + TOLERANCE_RATIO * 2);
        } else {
            size_center = size_min + 0.15;
            size_sigma = 0.12 * (1 + TOLERANCE_RATIO * 2);
        }

        if (weight_max !== null && weight_max !== undefined) {
            weight_center = (weight_min + weight_max) / 2;
            const weight_span = weight_max - weight_min;
            weight_sigma = (weight_span / 4) * (1 + TOLERANCE_RATIO * 2);
        } else {
            weight_center = weight_min + 2.0;
            weight_sigma = 1.5 * (1 + TOLERANCE_RATIO * 2);
        }

        return [size_center, size_sigma, weight_center, weight_sigma];
    }

    function gaussianDensity(x, mean, sigma) {
        if (sigma <= 0) return Math.abs(x - mean) < 1e-6 ? 1.0 : 0.0;
        return Math.exp(-0.5 * Math.pow((x - mean) / sigma, 2));
    }

    function matchPets(size, weight) {
        const results = [];
        for (const pet of PETS_DATA) {
            const [s_mean, s_sigma, w_mean, w_sigma] = getGaussianParams(pet);
            const prob_s = gaussianDensity(size, s_mean, s_sigma);
            const prob_w = gaussianDensity(weight, w_mean, w_sigma);
            const score = prob_s * prob_w;
            if (score > 0) {
                results.push({ ...pet, match_score: score });
            }
        }

        let total = 0;
        for (const r of results) total += r.match_score;
        if (total > 0) {
            for (const r of results) r.probability = (r.match_score / total) * 100;
        } else {
            for (const r of results) r.probability = 0;
        }
        results.sort((a, b) => b.probability - a.probability);
        return results.filter(r => r.probability > 0.5);
    }

    // ======================== UI 交互 ========================
    const sizeInput = document.getElementById('sizeInput');
    const weightInput = document.getElementById('weightInput');
    const matchBtn = document.getElementById('matchBtn');
    const resultContainer = document.getElementById('resultContainer');

    function formatRange(min, max) {
        if (max === null || max === undefined) return `≥ ${min}`;
        return `${min} - ${max}`;
    }

    function renderResults(size, weight) {
        const matches = matchPets(size, weight);
        if (!matches.length) {
            resultContainer.innerHTML = `<div class="empty-tip">😢 没有匹配到精灵 (概率 <0.5%)<br>放宽容差后或许能匹配~</div>`;
            return;
        }
        let html = `<ul class="result-list">`;
        for (let pet of matches) {
            const sizeText = formatRange(pet.size_min, pet.size_max);
            const weightText = formatRange(pet.weight_min, pet.weight_max);
            html += `
                <li>
                    <div>
                        <div class="pet-name">${pet.name}</div>
                        <div class="pet-detail">📐 ${sizeText} m &nbsp;|&nbsp; ⚖️ ${weightText} kg</div>
                    </div>
                    <div class="probability">${pet.probability.toFixed(1)}%</div>
                </li>
            `;
        }
        html += `</ul>`;
        resultContainer.innerHTML = html;
    }

    matchBtn.addEventListener('click', () => {
        let size = parseFloat(sizeInput.value);
        let weight = parseFloat(weightInput.value);
        if (isNaN(size) || isNaN(weight)) {
            resultContainer.innerHTML = `<div class="empty-tip">⚠️ 请输入有效的数字(尺寸和重量)</div>`;
            return;
        }
        renderResults(size, weight);
    });

    // 初始化示例 (0.32, 21.073 嘟嘟煲)
    renderResults(0,0);
</script>
</body>
</html>
相关推荐
qq_206901392 小时前
如何为 JSON 序列化中的不同浮点字段指定独立的小数精度
jvm·数据库·python
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月23日
人工智能·python·信息可视化·自然语言处理·ai编程
思绪无限2 小时前
YOLOv5至YOLOv12升级:机械器件识别系统的设计与实现(完整代码+界面+数据集项目)
人工智能·python·深度学习·目标检测·计算机视觉·机械器件识别
m0_588758482 小时前
解决Navicat正向工程从模型建表报错怎么办_外键关联与语法解析
jvm·数据库·python
TOOLS指南2 小时前
使用Pycharm实现数据可视化作品代码-Python应用
python·信息可视化·pycharm
2501_914245932 小时前
如何修复宝塔面板由于inode耗尽导致无法创建文件_清理海量小文件缓存与会话目录
jvm·数据库·python
❆VE❆2 小时前
python基础篇(一):使用vscode搭建python相关环境
开发语言·vscode·python
2401_837163892 小时前
WordPress后台插件隐藏策略:仅对指定管理员显示特定插件
jvm·数据库·python
qq_189807032 小时前
C++如何验证YAML语法格式是否正确_try-catch解析校验用法【实战】
jvm·数据库·python