Starward项目中实现UP角色平均抽数统计的技术方案

Starward项目中实现UP角色平均抽数统计的技术方案

【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 【免费下载链接】Starward 项目地址: https://gitcode.com/gh_mirrors/st/Starward

引言:抽卡数据分析的核心痛点

在米哈游系列游戏中,抽卡(Gacha)系统是玩家获取角色和武器的主要方式。对于追求特定UP角色的玩家来说,了解自己的抽卡历史数据至关重要。然而,官方提供的抽卡记录功能相对基础,无法提供深入的统计分析。Starward项目通过实现UP角色平均抽数统计功能,解决了这一核心痛点,让玩家能够清晰了解自己的抽卡效率和欧非程度。

技术架构概览

Starward的抽卡统计系统采用分层架构设计,主要包含以下核心组件:

mermaid

核心算法实现

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角色平均抽数统计功能,玩家可以获得以下关键洞察:

  1. 抽卡效率评估:了解获取UP角色的平均成本
  2. 欧非程度分析:对比官方概率与实际抽数差异
  3. 抽卡策略优化:基于历史数据制定更合理的抽卡计划
  4. 多账号对比:比较不同账号的抽卡运气

技术挑战与解决方案

挑战1:UP状态的时间敏感性

解决方案:建立时间维度的UP状态判断机制,精确到秒级的时间区间匹配。

挑战2:多游戏数据兼容

解决方案:抽象通用接口,为每个游戏实现特定的数据处理逻辑。

挑战3:大数据量性能

解决方案:采用分批处理和内存计算,确保万条记录的快速统计。

总结与展望

Starward项目的UP角色平均抽数统计功能通过精心的架构设计和算法实现,为玩家提供了专业级的抽卡数据分析能力。该方案不仅解决了玩家对抽卡历史深度分析的需求,还展示了如何在一个开源项目中实现复杂的数据统计功能。

未来可能的改进方向包括:

  • 增加更细粒度的统计分析(如分时段统计)
  • 提供可视化图表展示
  • 支持自定义统计规则
  • 增加预测模型功能

通过持续的技术迭代,Starward将继续为米哈游游戏玩家提供更优质的抽卡数据分析体验。

【免费下载链接】Starward Game Launcher for miHoYo - 米家游戏启动器 【免费下载链接】Starward 项目地址: https://gitcode.com/gh_mirrors/st/Starward

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值