【原神】祈愿概率计算
对祈愿的概率进行了计算,和官方公布的好像有点出入。
不知道是不是计算错误还是本身抽奖逻辑中隐藏了额外算法。

祈愿规则:
「奔行世间」常驻祈愿为永久性祈愿活动,玩家可以抽取非限定角色与武器。
在本祈愿内,每10次祈愿必会获得至少1个4星或以上物品。
※一般情况下所有角色或武器均适用基础概率,如触发概率UP、保底等以具体规则为准。
〓祈愿规则〓
规则1:5星物品祈愿的基础概率为0.600%,综合概率(含保底)为1.600%,最多90次祈愿必定能通过保底获取5星物品。
规则2:4星物品祈愿的基础概率为5.100%,综合概率(含保底)为13.000%,最多10次祈愿必定能通过保底获取4星或以上物品。

根据出现5星或4星重置保底次数,写了程序模拟抽取以后发现:
1.90连保底触发,重置90连保底次数。
2.90连保底触发/10连保底触发,如果重置10连保底次数依然无法计算出官方的综合几率。
3.10连保底如果不受90次保底触发重置次数/不受基础记录抽出4星重置10连保底次数,则可以模拟到官方计算的综合保底概率。(10连保底重置条件:触发10连保底出现4星,基础概率出现4星或以上不触发次数重置,90连保底不触发次数重置)
4.按照3规则,可以计算出,如果触发10连保底,出现5星概率约6%,出现4星概率约94%
代码如下:
Sub rand_card()
Dim rand_num As Long '随机次数
Dim rand_rate As Long '随机值
Dim rand_item(1 To 3) '随机权重列表
Dim rand_ten_item(1 To 2) '十连保底权重
Dim rand_max, rand_max_guaranteed '最大权重数
Dim rand_guaranteed_ten, rand_guaranteed_ninety '触发保底次数
Dim cur_guaranteed_ninety '未出5星累计次数
Dim cru_guranteed_ten '未出4星累计次数
Dim rand_five_star_time, rand_four_star_time '出现的5星次数,出现的4星次数
'=======基础几率==========
rand_item(1) = 60 '五星几率
rand_item(2) = 570 '四星几率
rand_item(3) = 10000 '其他几率
'=======十连保底几率======
rand_ten_item(1) = 60
rand_ten_item(2) = 1000
'====================
rand_guaranteed_ten = 10
rand_guaranteed_ninety = 90
cur_guaranteed_ninety = 0
cru_guranteed_ten = 0
rand_five_star_time = 0
rand_four_star_time = 0
rand_num = 100000
rand_max = rand_item(3)
rand_max_guaranteed = rand_ten_item(2)
For i = 1 To rand_num
'判断未出5星的累计次数
'90次则触发保底,次数清零,未达到90次,不触发保底
'不触发保底按照基础几率随机,出5星,次数清零,不出5星次数不清零
'判断是否触发10连保底,不触发,按照基础几率随机,触发,按照保底随机
If cur_guaranteed_ninety = 90 Then
rand_five_star_time = rand_five_star_time + 1
cur_guaranteed_ninety = 0
'cru_guranteed_ten = 0
Else
If cru_guranteed_ten >= 10 Then
rand_rate = Int((rand_max_guaranteed * Rnd) + 1)
If compara_rand(rand_rate, rand_ten_item) = 1 Then
rand_five_star_time = rand_five_star_time + 1
cur_guaranteed_ninety = 0
'cru_guranteed_ten = 0
Else
rand_four_star_time = rand_four_star_time + 1
cru_guranteed_ten = 0
End If
Else
rand_rate = Int((rand_max * Rnd) + 1)
Select Case compara_rand(rand_rate, rand_item)
Case 1:
rand_five_star_time = rand_five_star_time + 1
cur_guaranteed_ninety = 0
'cru_guranteed_ten = 0
Case 2:
rand_four_star_time = rand_four_star_time + 1
'cru_guranteed_ten = 0
Case 3:
cur_guaranteed_ninety = cur_guaranteed_ninety + 1
cru_guranteed_ten = cru_guranteed_ten + 1
End Select
End If
End If
Next i
Debug.Print rand_five_star_time & "-" & rand_four_star_time
Debug.Print rand_five_star_time / rand_num & "-" & rand_four_star_time / rand_num
End Sub
'数值落区间
Function compara_rand(rand_num, rand_item) '当前数,数组
For i = LBound(rand_item) To UBound(rand_item)
If rand_num <= rand_item(i) Then
compara_rand = i
Exit For
End If
Next i
End Function

以下未计算出5星或者4星后重置情况。是错误的。谢谢@aki-mine
