Starward项目中祈愿系统抽数统计机制的技术解析
【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 项目地址: https://gitcode.com/gh_mirrors/st/Starward
引言:米家游戏玩家的祈愿数据分析痛点
作为米哈游游戏玩家,你是否曾经为以下问题困扰:
- 记不清自己在某个卡池已经抽了多少发
- 不确定距离保底还有多少次抽卡
- 想要统计各个稀有度物品的出货概率
- 希望分析自己的抽卡历史数据来优化后续抽卡策略
Starward项目的祈愿系统抽数统计机制正是为了解决这些痛点而生。本文将深入解析这一机制的技术实现细节,帮助开发者理解其设计理念和实现方式。
系统架构概览
Starward的祈愿系统采用分层架构设计,主要分为三个层次:
核心数据模型解析
GachaLogItem:基础抽卡记录实体
public class GachaLogItem
{
public long Uid { get; set; } // 用户ID
public long Id { get; set; } // 记录唯一ID
public int GachaType { get; set; } // 祈愿类型
public string Name { get; set; } // 物品名称
public string ItemType { get; set; } // 物品类型
public int RankType { get; set; } // 稀有度(3/4/5星)
public DateTime Time { get; set; } // 抽卡时间
public int ItemId { get; set; } // 物品ID
public int Count { get; set; } // 数量
public string Lang { get; set; } // 语言
}
GachaLogItemEx:扩展统计模型
public partial class GachaLogItemEx : GachaLogItem
{
public int Index { get; set; } // 在保底池中的顺序
public int Pity { get; set; } // 当前保底计数
public double Progress { get; set; } // 保底进度百分比
public int ItemCount { get; set; } // 相同物品数量统计
public bool IsUp { get; set; } // 是否为UP物品
public bool HasUpItem { get; set; } // 卡池是否有UP物品
}
抽数统计核心算法
保底计数计算机制
// 在GetGachaLogItemEx方法中的保底计算逻辑
foreach (IGachaType type in QueryGachaTypes)
{
var l = GetGachaLogItemsByQueryType(list, type);
int index = 0;
int pity = 0;
foreach (var item in l)
{
item.Index = ++index; // 顺序编号
item.Pity = ++pity; // 保底计数递增
if (item.RankType == 5) // 如果抽到5星
{
pity = 0; // 重置保底计数
}
}
}
统计数据分析算法
public virtual (List<GachaTypeStats> GachaStats, List<GachaLogItemEx> ItemStats) GetGachaTypeStats(long uid)
{
var statsList = new List<GachaTypeStats>();
var allItems = GetGachaLogItemEx(uid);
foreach (IGachaType type in QueryGachaTypes)
{
var list = GetGachaLogItemsByQueryType(allItems, type);
if (list.Count == 0) continue;
var stats = new GachaTypeStats
{
GachaType = type.Value,
Count = list.Count,
Count_5_Up = list.Count(x => x.RankType == 5 && x.IsUp),
Count_5 = list.Count(x => x.RankType == 5),
Count_4 = list.Count(x => x.RankType == 4),
Count_3 = list.Count(x => x.RankType == 3),
// ... 其他统计字段
};
// 概率计算
stats.Ratio_5 = (double)stats.Count_5 / stats.Count;
stats.Ratio_4 = (double)stats.Count_4 / stats.Count;
stats.Ratio_3 = (double)stats.Count_3 / stats.Count;
// 平均抽数计算
stats.Average_5 = (double)(stats.Count - stats.Pity_5) / stats.Count_5;
if (stats.Count_5_Up > 0)
{
stats.Average_5_Up = (double)(stats.Count - stats.Pity_5) / stats.Count_5_Up;
}
}
return (statsList, groupStats);
}
数据结构设计详解
GachaTypeStats 统计数据结构
| 字段名 | 类型 | 描述 | 计算公式 |
|---|---|---|---|
| Count | int | 总抽数 | - |
| Count_5 | int | 5星物品数量 | Count(x => x.RankType == 5) |
| Count_5_Up | int | UP的5星数量 | Count(x => x.RankType == 5 && x.IsUp) |
| Count_4 | int | 4星物品数量 | Count(x => x.RankType == 4) |
| Count_3 | int | 3星物品数量 | Count(x => x.RankType == 3) |
| Ratio_5 | double | 5星出货率 | Count_5 / Count |
| Ratio_4 | double | 4星出货率 | Count_4 / Count |
| Ratio_3 | double | 3星出货率 | Count_3 / Count |
| Average_5 | double | 平均5星抽数 | (Count - Pity_5) / Count_5 |
| Average_5_Up | double | 平均UP5星抽数 | (Count - Pity_5) / Count_5_Up |
| Pity_5 | int | 当前5星保底计数 | 最后5星后的抽数 |
| Pity_4 | int | 当前4星保底计数 | 最后4星后的抽数 |
游戏特定保底规则处理
// 武器池和光锥池的特殊保底规则
public double Progress => (double)Pity / ((GachaType is GenshinGachaType.WeaponEventWish
or StarRailGachaType.LightConeEventWarp
or ZZZGachaType.WEngineChannel) ? 80 : 90) * 100;
数据存储与查询优化
SQLite数据库表结构
-- 抽卡记录表结构
CREATE TABLE GachaLog (
Uid INTEGER, -- 用户ID
Id INTEGER, -- 记录ID
GachaType INTEGER,-- 祈愿类型
Name TEXT, -- 物品名称
ItemType TEXT, -- 物品类型
RankType INTEGER, -- 稀有度
Time DATETIME, -- 抽卡时间
ItemId INTEGER, -- 物品ID
Count INTEGER, -- 数量
Lang TEXT -- 语言
);
-- 祈愿URL缓存表
CREATE TABLE GachaLogUrl (
GameBiz TEXT, -- 游戏业务标识
Uid INTEGER, -- 用户ID
Url TEXT, -- 祈愿URL
Time DATETIME -- 缓存时间
);
查询性能优化策略
- 索引优化:在Uid、GachaType、Time字段上建立索引
- 分批处理:支持分页获取抽卡记录,避免一次性加载大量数据
- 内存缓存:对统计结果进行缓存,减少重复计算
- 异步操作:所有数据库操作都采用异步方式,避免UI阻塞
多游戏支持架构
Starward支持米哈游多款游戏的祈愿系统,通过抽象接口实现统一处理:
// 祈愿类型接口
public interface IGachaType
{
int Value { get; }
string ToLocalization();
}
// 游戏特定实现
public class GenshinGachaType : IGachaType { /* 原神实现 */ }
public class StarRailGachaType : IGachaType { /* 星穹铁道实现 */ }
public class ZZZGachaType : IGachaType { /* 绝区零实现 */ }
实战应用示例
抽卡记录分析流程
统计信息展示示例
假设用户有以下抽卡数据:
- 角色祈愿池:300抽,5个5星,其中3个UP
- 武器祈愿池:150抽,2个5星,其中1个UP
系统将自动计算并显示:
- 角色池5星出货率:1.67%
- 角色池平均5星抽数:60抽
- 角色池UP5星平均抽数:100抽
- 当前保底计数:45抽(距离保底还有45抽)
技术亮点与创新
- 统一的跨游戏架构:一套代码支持多款米哈游游戏
- 实时保底计算:动态计算当前保底状态和进度
- 智能数据去重:避免重复导入相同抽卡记录
- 多维度统计分析:提供全面的抽卡数据洞察
- 离线数据支持:所有数据本地存储,支持离线分析
总结
Starward项目的祈愿系统抽数统计机制通过精心的架构设计和算法实现,为米哈游游戏玩家提供了强大的抽卡数据分析能力。其核心技术包括:
- 基于ORM的数据持久化层
- 多游戏统一的抽象接口设计
- 实时保底计数和概率统计算法
- 高性能的数据查询和缓存机制
- 丰富的统计维度和可视化展示
这一机制不仅解决了玩家的实际需求,也为开发者提供了可扩展、可维护的技术架构范例。通过深入理解这一机制,开发者可以更好地进行二次开发或类似系统的构建。
【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 项目地址: https://gitcode.com/gh_mirrors/st/Starward
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



