一般游戏的战力公式,是一个线性回归方程:
a*x+b*y+c*z+… =p
其中,p是战斗力,[a,b,c…]是属性,[x,y,z…]是属性价值。
属性一般包括:最大生命值,攻击力,防御力,闪避,暴击,命中等等。
如果确定了属性价值,那么战斗力就确定了。
如果两个角色,战斗力相同,而属性可以不同,那么,属性价值相当于各属性的权重,并且属性价值有一个内在关系:
x/s+y/s+z/s+… = 1
s表示总属性价值。
x/s表示属性价值因子,总属性价值只和是1.
求取了价值因子,就可以求得权重,也就是属性价值。
很多游戏的属性价值是直觉得出的,这里提供一个机器学习方法
检验战斗力的方式,最简单的凭据是,实时战斗。
如果两个单位在实时战斗的情况下,如果战斗结果势均力敌,表示两个单位战力相当。
当然,一般影响战斗结果的因素很多,并不仅仅只有战力公式涉及到的属性。例如:单位移动速度,转向速度,AI程度等等。又或者受暴击率,闪避率等影响,一场战斗如果人品爆发次次暴击,也会影响战斗结果。又或者对于有操作的游戏,玩家的操作技巧,也影响战斗结果。
所以,为了屏蔽这些影响,战斗的时候有先决条件:1.非战斗力公式相关的属性相同;2.暴击率和闪避率一般多次判定之后趋于稳定,影响较小不考虑;3.玩家无法操作。
所以,可以用实时战斗的结果,来评估战斗力。
这里提供一个神经网络模型来进行学习。
可以看到线性方程,只用一个单层的前馈神经网络可以模拟出来。
输入层是N个神经元,对应N个属性,神经元的输出的权重,就是属性价值因子。而且,属性价值因子只和等于1,恰好满足神经网络的内在形式。
输出层是正则化的战斗力。乘以一个系数就是想要的总战斗力。系数可以随意。
属性值 = 属性价值因子*总战斗力
1.首先随机N个神经网络模型,模型的价值因子,是随机的,总和为1.
这样就得到N个神经网络模型。
2.然后求得属性值,得到N个单位的属性。
3.让这N个单位随机1v1匹配,进行战斗。
胜利的一方,表示这个单位战力比失败一方大,但不能表示这个比最终战斗力大。
如何求得最终权重?
未完待续。。。
以下是求取线性伤害公式的算法,战斗力公式使用线性(仅演示作用)
import numpy as np import random import math #需要训练的权重 攻击,防御,真实伤害 x_param = np.random.uniform(1,10,3) #伤害计算式 def damage(p1,p2): #攻击减防御 dmg = p1[0] - 0.5*p2[1] #第三项为额外输出 dmg += 2.0*p1[2] return dmg #如果涉及到暴击率之类的,可以进行多次计算伤害 def dmg_times(p1,p2): v = 0 for i in range(1): v += damage(p1,p2) return v #求和 def sum(v,len): temp_v = 0 for i in range(len): temp_v += v[i] return temp_v #返回权重的因子模式 def get_weight_factor(p,len=3): sum_p = sum(p,len) return [ p[i]/sum_p for i in range(len) ] #依据总战斗力,以及单位的属性比例,以及战力公式的权重,生成战斗单位属性(攻击,防御,真实伤害) #战斗力=a*x+b*y+c*z #(a,b,c)为需要求取的战斗力公式的权重 x_param #(x,y,z)为返回值。表示单位的属性 def get_propertys(p_factor,x_p, power): x_factors = [ x for x in x_p] temp_v = [ ] for i in range(len(p_factor)): temp_v.append( power * p_factor[i] / x_factors[i] ) return temp_v #两个单位战力的差别 def error(p1,p2): return (dmg_times(p1,p2) - dmg_times(p2,p1))**2 #梯度下降算法 def gradient_descent(u1,u2,power): delta = 0.0001 p1 = get_propertys(u1,x_param, power) p2 = get_propertys(u2,x_param, power) rate = 0.01 out_param = [] for i in range(len(x_param)): new_x_param = [ x for x in x_param] new_x_param[i] += delta d_p1 = get_propertys(u1,new_x_param,power) d = (error(d_p1,p2)-error(p1,p2))/delta out_param.append(max(0, x_param[i] - rate * d)) return out_param #总战力 power = 100 #打印初始值 print(x_param) #训练30000次 for i in range(30000): #随机两个单位属性 w1 = get_weight_factor(np.random.uniform(5,30,3)) w2 = get_weight_factor(np.random.uniform(5,30,3)) #梯度下降 x_param = gradient_descent(w1,w2,power) #每1000次训练,打印结果 if i%1000 == 0: p1 = get_propertys(w1,x_param,power) p2 = get_propertys(w2,x_param,power) errorNum = error(p1,p2) print('p1 {} p2 {}'.format(p1,p2)) print('x_param = {} dmg1 = {} dmg2 = {} error = {:6f}'.format(x_param,dmg_times(p1,p2),dmg_times(p2,p1), errorNum))
输出结果:
5.9887 : 2.9942 : 11.9791
比较接近伤害计算式的属性价值:2:1:4