Project1
标题: [已解决]设计技能头大,大家提供点思路。 [打印本页]
作者: miantouchi 时间: 2020-4-19 19:59
标题: [已解决]设计技能头大,大家提供点思路。
本帖最后由 miantouchi 于 2020-4-22 06:34 编辑
我想设计个普通攻击的连击
如果是1-10级, 普通攻击只能出现 1连击
如果是11-30级,普通攻击是能出现 1连击 和 2连击
如果是31-50级,普通攻击是能出现 1连击 和 2连击 、3连击
如果是51级及以上, 普通攻击是能出现 1连击 和 2连击 、3连击、4连击
也就是4个阶段、每个阶段 可以按照等级、敏捷等吧,某一个数值 来确定,越高越大几率获得高连击
假如玩家35级,普通攻击可以出现 1连击 和 2连击 、3连击,决定不会出现4连击情况
35到50级,随着等级提升,越大几率触发3连击
假如玩家52级,普通攻击可以出现 1连击 和 2连击 、3连击、4连击
但是4连击触发几率不高,随着等级提高,越容易触发3连、4连
现在困惑是怎么协调这4个阶段,每个阶段各个连击的几率怎么匹配
51级以上有点咧不开了(1连几率多少、2连几率多少、3连几率多少、4连几率多少)。
52级以上有点咧不开了(1连几率多少、2连几率多少、3连几率多少、4连几率多少)。
53级以上有点咧不开了(1连几率多少、2连几率多少、3连几率多少、4连几率多少)。
54级以上有点咧不开了(1连几率多少、2连几率多少、3连几率多少、4连几率多少)。
55级以上有点咧不开了(1连几率多少、2连几率多少、3连几率多少、4连几率多少)。
.。。。。列不开了
或者是大家有没有什么更好地想法。
可以用熟练度、敏捷等等作为判断都行,不局限于等级,有的人提议是武器带有连击属性。
作者: SixRC 时间: 2020-4-19 22:08
想到一个很简单的想法
设置每攻递减的连击率
初始连击率为等级-10 递减值为 20
那么比方 40级 攻击一次后 二连击率 40-10=30% 三连击率 30-20=10% 无四连击
这是最简单的形式 40级伤害期望仅 133%
然后 不如整体概率×2
那么还是40级 二连击率 60 三连击率 20 期望是 172%
再然后
想扩大连击率间的倍数 可以考虑开个n次方 n>1
想缩小倍数 可以考虑开个1/n次方 要不加个log啥的
然后加个上限什么的..
我也不知道了
作者: Im剑侠客 时间: 2020-4-20 03:01
1连是必出的100%,要设定的也就是2、3、4连。要想更加精准设定,只能遍历区间了,手动预设每一个等级或者每一个等级区间的触发概率。
作者: 89444640 时间: 2020-4-20 06:28
分别计算?一击不算,11~30。30%几率发动两连击,每升级加1%发动几率,这样lv30。49%几率发动
31~50 在发动了两连击的基础上30%几率发动两连击 升级 两连击发动几率加0.5% 三连击发动几率加1%
余此类推
目的是随着等级提升低次数连击发动概率变高,高次数的也有更大几率发动。
这个挺像红美铃的连击,菜刀当初设计是随着等级提高技能之间可以继续发动,每个格斗招式动作做成衔接型号,可以随时切回收招动作,也可以继续连到头,类似于格斗游戏的普通技,特殊技,必杀技 超必杀技 奥义这样的连击,由于动作绘制过于耗时,目前没继做。
作者: 灯笼菜刀王 时间: 2020-4-20 10:04
本帖最后由 灯笼菜刀王 于 2020-4-20 11:27 编辑
用抽奖形式好了
def 连击数获得
f = []
battler.level.times {f.push(1)}
(battler.level - 10).times {f.push(2)}
(battler.level - 30).times {f.push(3)}
(battler.level - 50).times {f.push(4)}
#-洗牌-------------------------------------
(n=f.size).times do |j|
a = rand(n)
b = f[j]
f[j] = f[a]
f[a] = b
end
#--------------------------------------------
return f[rand(n)]
end
这样 100级的时候4的概率是1的一半, 而51级的时候, 4的概率是1的50分之一
作者: colonp_a 时间: 2020-4-20 11:11
给每个连击设一个权值(abcd),每升1级对应的权值+1,几率就是总权值/单个权值,代码很好写
a=level
b=level-10<0? 0 : level-10
c=level-30<0? 0 : level-30
d=level-50<0? 0 : level-50
e=a+b+c+d
f(触发率)=a/e
ghi以此类推
不用一级一级设置了
作者: 灯笼菜刀王 时间: 2020-4-20 16:19
@RyanBern
做个数组随机抽测试
1000次抽样结果, 执行三次
可以看到 中间的4,5,6号被抽中的概率会比较高一些~~
实际上我曾经有问过这个问题, rand用同一个种子在短间隔时随到的数值很接近~
碰到过这个姐妹舰(成长率差不多)在同时升级的时候随机加的点非常接近~ 所以我就一直用洗牌+随机抽的方式来以求"更随机"
作者: SailCat 时间: 2020-4-21 02:06
本帖最后由 SailCat 于 2020-4-21 02:15 编辑
从建模的角度上讲,最直接的办法是把表做死,然后直接查表
当然,“表”可以用公式来表示。
比方说:
让角色从1-99级(或敏捷从1-999),逐渐从100%打1击变成100%打4击
这其实是期望伤害从100%变成400%的意思
那么可得你的期望伤害公式=100+等级*3%(这个变化其实是103-397,但就按这个来也行)
另外,这个是线性变化,以下讨论两种情况
1. 全程线性变化的情况
2元1次方程组直接可以解,剩下的就是怎么实现
比如:在1 2 3 4连击的判定下,怎么做103%的伤害
很简单:97%出1击,3%出2击,这平均伤害就是103%
也就是说,每减少3%1击判定率,增加3%2击判定率,就可以提升伤害3%
当然,你也可以减少2%的1击判定率,增加1%的2击判定和1%的3击判定,这也提升伤害3%
那么
设自变量范围是[1,99]
那么首先,每级减少3%1击判定,增加3%2击判定
至11级时,判定从[97,3,0,0]变成[67,33,0,0]
这时1击的判定率已经是2击的2倍了,就改用:每级减2%的1击判定,增加1%的2击判定和1%的3击判定
至22级时,判定变为[45,44,11,0]
这时1击的判定率已经和2击相同,此时要改用第三个改法:每级减1%的1击和1%的2击判定,增加2%的3击判定(对,这也是+3%)
至33级时,判定变为[34,33,33,0]
这时,改为每级-1%2击判定和3击判定,+2%4击判定
至41级时,为[34,25,25,16],此时改为每击-1%1击,+1%4击。
至50级时,为[25,25,25,25]
从50-99级,按上面的逆向操作就可以了。至99级为[0,0,3,97]
def rand_hit(n)
m = n > 50 ? 100 - n : n
case m
when 1..11
x = [100 - 3*m, 3*m, 0, 0]
when 12..22
x = [89-2*m, 22+m, m-11, 0]
when 23..33
x = [57-m, 66-m, m, 0]
when 34..41
x = [34, 66-m, 66-m, m*2-66]
when 42..50
x = [75-m, 25, 25, m-25]
end
x.reverse! if n != m
y = [x[0], x[0]+x[1], x[0]+x[1]+x[2], x[0]+x[1]+x[2]+x[3]]
case rand(100)
when 0...y[0]
1
when y[0]...y[1]
2
when y[1]...y[2]
3
else
4
end
end
def rand_hit(n)
m = n > 50 ? 100 - n : n
case m
when 1..11
x = [100 - 3*m, 3*m, 0, 0]
when 12..22
x = [89-2*m, 22+m, m-11, 0]
when 23..33
x = [57-m, 66-m, m, 0]
when 34..41
x = [34, 66-m, 66-m, m*2-66]
when 42..50
x = [75-m, 25, 25, m-25]
end
x.reverse! if n != m
y = [x[0], x[0]+x[1], x[0]+x[1]+x[2], x[0]+x[1]+x[2]+x[3]]
case rand(100)
when 0...y[0]
1
when y[0]...y[1]
2
when y[1]...y[2]
3
else
4
end
end
2. 非全程线性变化的情况(比如你提问的情况)
非全程线性无非就是划分阶段,你先提出你的预期,比如10级内都是1击,30级以内只有2击,50级以内只有3击,51级以上才有4击
然后在每一个阶段内部,变化依然是线性的
例如,你设定好
1级[100,0,0,0]
10级[100,0,0,0]
11级[80,20,0,0]
30级[50,50,0,0]
31级[50,40,10,0]
50级[40,30,30,0]
51级[40,30,20,10]
99级[10,20,30,40]
然后其他级别用上述方法在中间插值就可以了,例如15级[71,29,0,0],43级[43,33,24,0],74级[28,26,24,22]等等
(插值代码略)
3. 指数衰减的判定,这个很简单,直接递归,写成每一击都有等级%机率连击一次即可,然后把最终结果限定为最多判3次(最多4击),这样判定的曲线大概是这样
1级[99,1,0,0]
10级[90,9,1,0]
20级[80,15,4,1]
30级[70,21,7,2]
40级[60,24,10,6]
50级[50,25,13,12]
60级[40,24,14,22]
70级[30,21,15,34]
80级[20,16,13,51]
90级[10,9,8,72]
99级[1,1,1,97]
指数衰减最大的问题,当人工卡次数时,曲线变化非常不平滑,特别是当触发率超过非触发率之后,大量机率堆在第4级别。但1-3级别依然是逐次下降机率,与常识不符。
def rand_hit(n)
x = 1
3.times do
rand(100) < n ? x += 1 : return x
end
x
end
def rand_hit(n)
x = 1
3.times do
rand(100) < n ? x += 1 : return x
end
x
end
4. 独立判定。即:除第1击外,多判定3次,每一次的触发机率是等级%。但不管是几级都总是判定3次,这样判定的曲线大概是这样
1级[97,3,0,0]
10级[73,25,2,0]
30级[34,44,19,3]
50级[13,37,37,13]
70级[3,19,44,34]
90级[0,2,25,73]
99级[0,0,3,97]
相对来说,最后一个的判定,是最接近人的心理预期的情况。
def rand_hit(n)
x = 1
3.times do
x += 1 if rand(100) < n
end
x
end
def rand_hit(n)
x = 1
3.times do
x += 1 if rand(100) < n
end
x
end
作者: RyanBern 时间: 2020-4-21 09:47
本帖最后由 RyanBern 于 2020-4-21 10:07 编辑
你的第一次实验就不是这样,就测了三次也未必严谨。更严谨的说法是“内置 rand(n) 产生的随机数性质不太好,不太像均匀分布”。应该不是“中间的概率变大”。比较追求数学上严谨性的话,可以对 rand 做个随机数检验,比方说卡方检验,统计专业的应该更清楚些。
这个问题和刚才聊的无关。因为设置同一个种子在短时间理应产生一样的随机数,这是随机数发生器的机制问题。因此不是每次生成随机数之前都要设置一个种子,这是不对的。比较正常的做法是程序启动时仅(根据系统时间)设置一次种子,之后种子就不要发生改变。不太清楚你所说的“很接近”的含义是指?
你可以测试一下每次给定 srand 之后 rand 出来的数值,应该是分毫不差的。
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |