用机器学习算法来求取战斗力公式

一般游戏的战力公式,是一个线性回归方程:

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

猜你喜欢

转载自blog.csdn.net/x_studying/article/details/79924263