基于Python的《明日方舟》限定卡池干员统计

前言

​ 在学习了一个星期的Python基础之后,正巧碰上方舟的限定卡池开放,便想着用自己的一个星期所学知识来做一个(很久之前就想做的)抽卡模拟器,以此来巩固和运用自己学到的东西。敲了一个晚上之后就完成了。

卡池规则:

​ 想做卡池模拟抽卡,那就要了解卡池的规则。明日方舟这款游戏的限定卡池规则如下:
卡池规则

  • 卡池的基本出率:六星干员2%、五星干员8%、四星干员50%、三星干员40%。

    • 每次获得的六星干员中,有70%的概率获得【纯烬艾雅法拉】、【琳琅诗怀雅】这两位干员中的一个。
    • 剩余30%的其他六星干员中,【百炼嘉维尔】与【假日威龙陈】出现概率位其他单个六星干员的5倍。
  • 每次获得的五星干员中,有50%的概率获得【青枳】干员。

  • 如果累计50抽都没有获得六星干员,那么从下一抽开始,获得六星干员的概率会随着抽数的增加而逐步增加+2%,获得六星干员后重置为2%。(例如第51抽出现六星干员的概率为4%,第52抽出现六星干员的概率为6%,以此类推)

  • 首次十连必定出现五星以上的干员(包括五星),仅限一次生效。

思路分析

​ 我自己的思路是这样的:首先按照卡池列出的概率先抽稀有度,然后再按照每个稀有度的出率再进行一次具体干员判定。这样的好处是不需要考虑太多,按照卡池规则走就好了(方舟的卡池出率描述比较清晰,隔壁某游戏只给出单抽出货概率,并且给出概率都是包含保底出率的)。坏处就是卡池更新难度大,每次更新需要重新往程序里塞干员,繁杂且易出错(后面会讲到一个比较轻松的导入干员的土办法),并且代码分支可能较多。

​ 首先第一条规则的思路

卡池的基本出率:六星干员2%、五星干员8%、四星干员50%、三星干员40%。

  • 每次获得的六星干员中,有70%的概率获得【纯烬艾雅法拉】、【琳琅诗怀雅】这两位干员中的一个。
  • 剩余30%的其他六星干员中,【百炼嘉维尔】与【假日威龙陈】出现概率位其他单个六星干员的5倍。

每次获得的五星干员中,有50%的概率获得【青枳】干员。

​ 基本出率很好实现,只需要用random模块的random.randint生成一个1到100的数,然后根据数的大小判定稀有度就可以了。

chance = random.randint(1,100)
if chance <= 2:
    print("六星干员")
elif chance <= 10:
    print("五星干员")
elif chance <= 60:
    print("四星干员")
elif chance <= 100:
    print("三星干员")

​ 然后是是否获得up干员的判定,这个也简单,建立几个列表用来存储干员以及up干员,在进行稀有度判定之后再进行一次random.uniform(1,100)的判定,如果小于70就从六星up干员列表中random.choice一个出来就好了。

Star6_Operator_Rate_Up = ['纯烬艾雅法拉', '琳琅诗怀雅']
Star6_Operator = ['歪了']
Star5_Operator_Rate_Up = ['青枳']
Star5_Operator = ['歪了']
Star4_Operator = ['蓝天']
Star3_Operator = ['白云']

chance = random.uniform(1,100)
if chance <= 2:
    print("六星干员:")
    Up_check = random.randint(1,100)
    if Up_check <= 70:
        Result = random.choice(Star6_Operator_Rate_Up)
        print(Result)
    else:
        Result = random.choice(Star6_Operator)
        print(Result)
elif chance <= 10:
    print("五星干员:")
    Up_check = random.randint(1,100)
    if Up_check <= 50:
        Result = random.choice(Star5_Operator_Rate_Up)
        print(Result)
    else:
        Result = random.choice(Star5_Operator)
        print(Result)
elif chance <= 60:
    print("四星干员:")
    Result = random.choice(Star4_Operator)
    print(Result)
elif chance <= 100:
    print("三星干员:")
    Result = random.choice(Star3_Operator)
    print(Result)

​ 最后是以往夏日限定的干员【百炼嘉维尔】和【假日威龙陈】,这个五倍权值也很好实现,只需要在普通的六星干员的列表里面赋值五个【百炼嘉维尔】和【假日威龙陈】就好了。这个会在后面的干员导入中一起实现。

​ 然后是第二条规则,也就是抽卡手游基本都存在的保底机制(不同游戏的保底机制可能不一样)。

如果累计50抽都没有获得六星干员,那么从下一抽开始,获得六星干员的概率会随着抽数的增加而逐步增加+2%,获得六星干员后重置为2%。(例如第51抽出现六星干员的概率为4%,第52抽出现六星干员的概率为6%,以此类推)

​ 实现的思路是增加一个表示没有获得六星干员的次数的参数No_Six_Count,初始为0,然后在获得三四五星干员的时候给这个参数+1,然后在获得六星干员的时候重置为0。在进行抽卡前先进行判定No_Six_Count是否小于50,是就走正常的抽卡流程,不是就走保底流程。

No_Six_Count = 0
chance = random.randint(1,100)
if No_Six_Count <= 50:
    if chance <= 2:
        print("六星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 70:
            Result = random.choice(Star6_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star6_Operator)
            print(Result)
        No_Six_Count = 0
    elif chance <= 10:
        print("五星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 50:
            Result = random.choice(Star5_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star5_Operator)
            print(Result)
        No_Six_Count += 1
    elif chance <= 60:
        print("四星干员:")
        Result = random.choice(Star4_Operator)
        print(Result)
        No_Six_Count += 1
    elif chance <= 100:
        print("三星干员:")
        Result = random.choice(Star3_Operator)
        print(Result)
        No_Six_Count += 1
else:
    if chance <= No_Six_Count - 48:
        print("六星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 70:
            Result = random.choice(Star6_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star6_Operator)
            print(Result)
        No_Six_Count = 0
    elif chance <= (148 - No_Six_Count)*2/23:
        print("五星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 50:
            Result = random.choice(Star5_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star5_Operator)
            print(Result)
        No_Six_Count += 1
    elif chance <= (148 - No_Six_Count)*25/46:
        print("四星干员:")
        Result = random.choice(Star4_Operator)
        print(Result)
        No_Six_Count += 1
    elif chance <= (148 - No_Six_Count)*10/23:
        print("三星干员:")
        Result = random.choice(Star3_Operator)
        print(Result)
        No_Six_Count += 1

​ 注意这里的保底流程的概率判定,明日方舟并没有明说在保底流程中,六星干员获取概率的增加是从哪里扣除的。这里我就自己武断认为是每次六星增加概率,剩余的概率中五星、四星与三星的出率与原来保持一致。在非保底情况下不出六星的98%概率中,五星有8%,四星有50%,三星有40%,我假设在保底的流程中,在不出六星的96%、94%等情况下,五星四星三星总保持一个8:50:40的比例。

​ 按照以上思路得出的判定条件如下:

六星干员的判定:No_Six_Count - 48
五星干员的判定:chance <= (148 - No_Six_Count)*2/23
四星干员的判定:chance <= (148 - No_Six_Count)*25/46
三星干员的判定:chance <= (148 - No_Six_Count)*10/23

​ 这样我们的保底机制也就写好了,接下来是首次十连保底机制。

首次十连必定出现五星以上的干员(包括五星),仅限一次生效。

​ 这个规则并没有说在这首次十连中,五星出现的概率是随着抽数越来越高还是前九次不是五星,第十次就必定是五六星。因此我(再一次)认定,前九次没有出现五六星,那么第十次必定出现五六星。其中五星与六星按照正常卡池中五六星的比例计算出率。也就是80%获得五星,20%获得六星。

Five_Stars_Least = 1
if draw_time == 10 and Five_Stars_Least == 1:
    if chance <= 20:
        print("六星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 70:
            Result = random.choice(Star6_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star6_Operator)
            print(Result)
        No_Six_Count = 0
        Five_Stars_Least = 0
    else:
        print("五星干员:")
        Up_check = random.randint(1,100)
        if Up_check <= 50:
            Result = random.choice(Star5_Operator_Rate_Up)
            print(Result)
        else:
            Result = random.choice(Star5_Operator)
            print(Result)
        No_Six_Count += 1
        Five_Stars_Least = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值