首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从游戏到数据:用 Python 解析炉石传说盒子本地数据,构建个人对局分析看板

从游戏到数据:用 Python 解析炉石传说盒子本地数据,构建个人对局分析看板

原创
作者头像
PC电脑医生
发布2026-06-24 11:09:49
发布2026-06-24 11:09:49
920
举报

摘要:

炉石传说盒子不仅是记牌工具,更在本地悄悄沉淀了大量结构化对局数据。本文从开发者视角出发,定位盒子的本地存储目录,用 Python 解析其中的 JSON 战绩文件、配置文件与日志记录,并对结构化后的数据做清洗、聚合与可视化,最终输出一份完全自定义的个人胜率分析看板。适合想用代码读懂自己游戏数据的玩家。


一、为什么盒子自带的统计面板不够用

炉石传说盒子内置了战绩统计功能:总胜率、各职业胜率、近期对局列表,一目了然。但用过一段时间就会发现三个问题——

第一,数据不互通。盒子里的对局记录无法导出,想和天梯插件(如 HDT)的数据做交叉分析,或者把数据扔进 Excel 做透视表,都无从下手。

第二,维度过粗。官方面板只给你「过去 N 场的胜率」,但如果你想知道「周五晚上的快攻卡组胜率是不是比周一低」「某张新卡替换前后胜率变化多少」,内置统计就回答不了。

第三,历史数据有边界。盒子滚动保留的记录数量有限,有些对局会被覆盖,长期趋势分析天然受限。

解决办法很直接:找到盒子的本地数据目录,用 Python 把这些文件读出来,清洗、入库,然后想怎么算就怎么算。


二、定位盒子本地数据目录

炉石传说盒子(网易版)的核心数据存储在 Windows 用户目录下的 AppData 路径中:

数据目录:%APPDATA%\HSAng\

在资源管理器地址栏直接输入上述路径即可打开。该目录下值得关注的文件和子目录:

  • hsa.config:盒子的主配置文件,纯文本键值对格式,记录游戏路径、窗口设置等参数。
  • *.json:卡组配置与用户数据,JSON 格式存储,盒子的许多功能模块依赖这里的结构化数据。
  • Logs\ 目录:盒子自身运行日志,以及被同步过来的游戏客户端通讯日志,记录每一场对局的详细事件流。

此外,如果你同时使用国际版的 Hearthstone Deck Tracker(HDT),它的数据在 %APPDATA%\HearthstoneDeckTracker\ 下,包含 History.xml(历史记录)、DeckStats.xml(卡组统计)等 XML 文件,也是不错的数据源。


三、用 Python 解析本地数据文件

下面按文件类型分别处理,代码均在 Python 3.9+ 环境下可运行。

3.1 读取配置文件(hsa.config

配置文件通常是键值对形式,可用标准库直接解析:

代码语言:python
复制
import os

def parse_hsa_config():
    config_path = os.path.join(os.getenv('APPDATA'), 'HSAng', 'hsa.config')
    config = {}
    try:
        with open(config_path, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#') and '=' in line:
                    key, _, value = line.partition('=')
                    config[key.strip()] = value.strip()
    except FileNotFoundError:
        print(f"配置文件未找到: {config_path}")
    return config

cfg = parse_hsa_config()
print(cfg)

3.2 解析 JSON 卡组与战绩数据

盒子本地缓存的卡组信息和对局记录很可能以 JSON 格式落盘。遍历目录找出所有 JSON 文件并逐个解析:

代码语言:python
复制
import json
import glob

def load_all_json(data_dir):
    records = []
    for filepath in glob.glob(os.path.join(data_dir, '*.json')):
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                data = json.load(f)
                if isinstance(data, list):
                    records.extend(data)
                elif isinstance(data, dict):
                    records.append(data)
        except (json.JSONDecodeError, UnicodeDecodeError):
            print(f"跳过无法解析的文件: {filepath}")
    return records

base_dir = os.path.join(os.getenv('APPDATA'), 'HSAng')
all_records = load_all_json(base_dir)
print(f"共加载 {len(all_records)} 条记录")

拿到数据后,可以用 Pandas 快速做结构化:

代码语言:python
复制
import pandas as pd

df = pd.DataFrame(all_records)
# 根据实际字段做筛选与重命名,以下为常见字段示例
if not df.empty:
    df = df.rename(columns={
        'hero': '使用职业',
        'opponent': '对手职业',
        'result': '胜负',
        'timestamp': '对局时间'
    })
    print(df[['对局时间', '使用职业', '对手职业', '胜负']].head(10))

3.3 解析游戏客户端日志(POWER.log

游戏客户端的 POWER.log 记录了每场对局完整的卡牌流转事件(ZONE_CHANGEPLAY_CARD 等),盒子正是通过监听这类日志来实现实时记牌。我们可以用正则表达式提取关键事件:

代码语言:python
复制
import re
from datetime import datetime

def parse_power_log(log_path):
    events = []
    zone_change_pattern = re.compile(
        r'(?P<timestamp>\d{2}:\d{2}:\d{2}\.\d+)\s+'
        r'ZoneChangeList\.ProcessChanges\(\)\s*-\s*'
        r'id=(?P<card_id>\d+).*'
        r'from\s*(?P<from_zone>\w+)\s*->\s*(?P<to_zone>\w+)'
    )
    try:
        with open(log_path, 'r', encoding='utf-8', errors='ignore') as f:
            for line in f:
                m = zone_change_pattern.search(line)
                if m:
                    events.append(m.groupdict())
    except FileNotFoundError:
        pass
    return events

log_dir = os.path.join(os.getenv('LOCALAPPDATA'), 'Blizzard', 'Hearthstone', 'Logs')
power_log = os.path.join(log_dir, 'Power.log')
zone_events = parse_power_log(power_log)
print(f"解析到 {len(zone_events)} 条卡牌转移事件")

注意:日志解析依赖游戏客户端启用了详细日志输出。如果文件夹中找不到 Power.log,需在战网客户端设置中追加启动参数 -log 以开启日志记录。


四、清洗与结构化数据

原始数据拿到后,距离可分析还有一步:清洗。主要做三件事——

  1. 统一时间格式:JSON 中的时间戳可能为 Unix 毫秒、ISO 字符串或自定义格式,统一转为 datetime 对象。
  2. 修复脏数据:断线、闪退等异常对局可能缺少结果字段,标记并过滤。
  3. 补全职业映射:职业编号到中文名称的映射表(例如 7 → 术士、8 → 法师),方便后续分组。
代码语言:python
复制
df['对局时间'] = pd.to_datetime(df['对局时间'], unit='ms', errors='coerce')
df = df.dropna(subset=['胜负'])
df = df[df['胜负'].isin(['win', 'lose'])]

profession_map = {
    1: '德鲁伊', 2: '猎人', 3: '法师', 4: '圣骑士',
    5: '牧师',  6: '潜行者', 7: '萨满', 8: '术士',
    9: '战士', 10: '恶魔猎手', 11: '死亡骑士'
}
df['使用职业名'] = df['使用职业'].map(profession_map)
df['对手职业名'] = df['对手职业'].map(profession_map)

五、构建个人胜率可视化看板

数据入库后,用 Matplotlib 生成几张关键图表。

5.1 各职业胜率柱状图

代码语言:python
复制
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 中文显示
stats = df.groupby('使用职业名')['胜负'].apply(
    lambda x: (x == 'win').sum() / len(x)
).sort_values(ascending=False)

plt.figure(figsize=(10, 5))
stats.plot(kind='bar', color='#4CAF50')
plt.title('各职业胜率对比')
plt.ylabel('胜率')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('winrate_by_class.png', dpi=150)

5.2 对局热力图:按天×职业看胜率分布

代码语言:python
复制
df['日期'] = df['对局时间'].dt.date
pivot = df.pivot_table(
    values='胜负', index='使用职业名', columns='日期',
    aggfunc=lambda x: (x == 'win').sum() / len(x)
)
plt.figure(figsize=(12, 6))
plt.imshow(pivot, cmap='RdYlGn', aspect='auto')
plt.colorbar(label='胜率')
plt.xticks(range(len(pivot.columns)), pivot.columns, rotation=45)
plt.yticks(range(len(pivot.index)), pivot.index)
plt.title('每日各职业胜率热力图')
plt.tight_layout()
plt.savefig('heatmap.png', dpi=150)

几行代码,就拿到了一份完全自定义的分析看板,维度想要多细就多细。


六、进阶方向与合规提醒

以上只是基础框架,几个值得继续挖的方向:

  • 定时任务自动更新:用 Windows 任务计划或 Cron 定时跑解析脚本,每次打开电脑自动刷新最新对局数据。
  • 云备份:将清洗后的 DataFrame 定期导出为 CSV 或 SQLite,同步到云盘,换电脑也不丢。
  • 卡牌粒度分析:结合 Power.log 的卡牌转移事件,可以精确追踪每一张关键卡的上手率、打出时机和胜率贡献,远比盒子面板的「卡组胜率」细。

最后提醒一句:本文所有操作仅读取本地文件,不涉及修改游戏客户端或网络数据包,符合暴雪与网易的用户协议。数据分析的边界是读本地、不篡改——守住这条线,炉石传说盒子就是你手上最好的个人教练。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、为什么盒子自带的统计面板不够用
  • 二、定位盒子本地数据目录
  • 三、用 Python 解析本地数据文件
    • 3.1 读取配置文件(hsa.config)
    • 3.2 解析 JSON 卡组与战绩数据
    • 3.3 解析游戏客户端日志(POWER.log)
  • 四、清洗与结构化数据
  • 五、构建个人胜率可视化看板
    • 5.1 各职业胜率柱状图
    • 5.2 对局热力图:按天×职业看胜率分布
  • 六、进阶方向与合规提醒
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档