Starward项目中实现UP角色平均抽数统计的技术方案
【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 项目地址: https://gitcode.com/gh_mirrors/st/Starward
引言:抽卡数据分析的核心痛点
在米哈游系列游戏中,抽卡(Gacha)系统是玩家获取角色和武器的主要方式。对于追求特定UP角色的玩家来说,了解自己的抽卡历史数据至关重要。然而,官方提供的抽卡记录功能相对基础,无法提供深入的统计分析。Starward项目通过实现UP角色平均抽数统计功能,解决了这一核心痛点,让玩家能够清晰了解自己的抽卡效率和欧非程度。
技术架构概览
Starward的抽卡统计系统采用分层架构设计,主要包含以下核心组件:
核心算法实现
UP角色识别机制
Starward通过GachaNoUp类维护了一个详尽的非UP角色数据库,支持多游戏、多卡池类型的UP状态判断:
public class GachaNoUp
{
public GameBiz Game { get; set; }
public int GachaType { get; set; }
public Dictionary<int, GachaNoUpItem> Items { get; set; } = new();
public static Dictionary<string, GachaNoUp> Dictionary { get; } = new();
// 判断指定角色在特定时间是否为UP状态
public bool IsUpItem(int itemId, DateTime time)
{
if (Items.TryGetValue(itemId, out var item))
{
return !item.NoUpTimes.Any(period => time >= period.Start && time <= period.End);
}
return true; // 不在非UP列表中的角色默认为UP
}
}
平均抽数计算算法
在GachaLogService.GetGachaTypeStats方法中,UP角色平均抽数的计算逻辑如下:
// 获取当前卡池的所有抽卡记录
var list = GetGachaLogItemsByQueryType(allItems, type);
// 统计UP五星角色数量
stats.Count_5_Up = list.Count(x => x.RankType == 5 && x.IsUp);
// 计算平均抽数
if (stats.Count_5_Up > 0)
{
int totalPulls = stats.Count - stats.Pity_5;
stats.Average_5_Up = (double)totalPulls / stats.Count_5_Up;
}
保底计数与索引构建
系统通过遍历抽卡记录构建保底计数和索引:
int index = 0;
int pity = 0;
foreach (var item in list)
{
item.Index = ++index; // 当前卡池中的顺序
item.Pity = ++pity; // 距离上次五星的抽数
if (item.RankType == 5)
{
pity = 0; // 重置保底计数
}
}
数据结构设计
GachaTypeStats 统计数据结构
public class GachaTypeStats
{
public int GachaType { get; set; } // 卡池类型
public string GachaTypeText { get; set; } // 卡池名称
public int Count { get; set; } // 总抽数
public int Count_5_Up { get; set; } // UP五星数量
public double Average_5_Up { get; set; } // UP五星平均抽数
public List<GachaLogItemEx> List_5 { get; set; } // 五星记录列表
// 格式化显示文本
public string Avarage_5_Up_Text => Count_5_Up == 0 ? "" : $" / {Average_5_Up:F2} ({Count_5_Up})";
}
GachaLogItemEx 扩展数据结构
public partial class GachaLogItemEx : GachaLogItem
{
public int Index { get; set; } // 卡池内序号
public int Pity { get; set; } // 保底计数
public bool IsUp { get; set; } // 是否为UP角色
public double Progress => (double)Pity / 90 * 100; // 保底进度百分比
}
多游戏支持实现
Starward支持米哈游旗下多款游戏的抽卡统计,通过抽象层实现统一接口:
| 游戏 | 卡池类型 | 保底机制 | UP判断规则 |
|---|---|---|---|
| 原神 | 301-角色活动 | 90抽保底 | 常驻五星非UP |
| 星穹铁道 | 11-角色活动 | 90抽保底 | 常驻五星非UP |
| 绝区零 | 2-专属频道 | 90抽保底 | 常驻五星非UP |
protected abstract GameBiz CurrentGameBiz { get; }
protected abstract string GachaTableName { get; }
protected abstract List<GachaLogItemEx> GetGachaLogItemsByQueryType(
IEnumerable<GachaLogItemEx> items, IGachaType type);
性能优化策略
数据库查询优化
使用Dapper进行高效的数据库操作,减少不必要的全表扫描:
using var dapper = DatabaseService.CreateConnection();
var allItems = dapper.Query<GachaLogItemEx>(
$"SELECT * FROM {GachaTableName} WHERE Uid = @uid ORDER BY Id;",
new { uid }).ToList();
内存计算优化
在内存中进行统计计算,避免频繁的数据库交互:
// 一次性获取所有数据后在内存中处理
var statsList = new List<GachaTypeStats>();
foreach (IGachaType type in QueryGachaTypes)
{
var list = GetGachaLogItemsByQueryType(allItems, type);
// 内存中计算统计信息
CalculateStatsInMemory(list, stats);
}
实际应用效果
通过Starward的UP角色平均抽数统计功能,玩家可以获得以下关键洞察:
- 抽卡效率评估:了解获取UP角色的平均成本
- 欧非程度分析:对比官方概率与实际抽数差异
- 抽卡策略优化:基于历史数据制定更合理的抽卡计划
- 多账号对比:比较不同账号的抽卡运气
技术挑战与解决方案
挑战1:UP状态的时间敏感性
解决方案:建立时间维度的UP状态判断机制,精确到秒级的时间区间匹配。
挑战2:多游戏数据兼容
解决方案:抽象通用接口,为每个游戏实现特定的数据处理逻辑。
挑战3:大数据量性能
解决方案:采用分批处理和内存计算,确保万条记录的快速统计。
总结与展望
Starward项目的UP角色平均抽数统计功能通过精心的架构设计和算法实现,为玩家提供了专业级的抽卡数据分析能力。该方案不仅解决了玩家对抽卡历史深度分析的需求,还展示了如何在一个开源项目中实现复杂的数据统计功能。
未来可能的改进方向包括:
- 增加更细粒度的统计分析(如分时段统计)
- 提供可视化图表展示
- 支持自定义统计规则
- 增加预测模型功能
通过持续的技术迭代,Starward将继续为米哈游游戏玩家提供更优质的抽卡数据分析体验。
【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 项目地址: https://gitcode.com/gh_mirrors/st/Starward
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



