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

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
import matplotlib.pyplot as plt#假设战斗单位包含三个属性
# atk           攻击力
# def           防御力
# true_dmg      真实伤害
#假设伤害公式为:
# dmg = (player1.atk-0.5*player2.def)+player1.atk_plus
#这个公式可以直接看出伤害公式的权重比为 atk : def : atk_plus = 1 : 0.5 : 2 = 2 : 1 : 4
#也就是战力公式为:power = 2*atk+1*def+4*atk_plus
#我们让两个玩家互相攻击,来训练。最后比较权重。#需要训练的权重.
#初始(1,10)之间随机值
#我们需要利用梯度下降算法,使这些权重比为 2:1:4
weights = np.random.uniform(1,10,3)#用伤害计算公式来计算两个玩家的伤害
def damage(player1,player2):#攻击减防御dmg = player1[0] - 0.5*player2[1]#第三项为额外输出dmg += 2.0*player1[2]return dmg#数组求和
def sum(v):temp_v = 0for i in v:temp_v += ireturn temp_v#将权重值变为因子(总和为1)
def get_weight_factor(p):sum_p = sum(p)return [ p[i]/sum_p for i in range(len(p)) ]#已知单位的战斗力,以及战力公式的因子的情况下,计算玩家的三项属性值
#factor 玩家的 三项属性 的权重因子
#w 战力公式的权重因子
#power 总战力值
def get_propertys(factor,w, power):temp_v = []for i in range(len(factor)):temp_v.append(power * factor[i]/w[i])return temp_v#计算两个单位伤害值的方差
def error(p1,p2):return (damage(p1,p2) - damage(p2,p1))**2#梯度下降算法
def gradient_descent(player1_weights_factor,player2_weights_factor):#计算偏导数的间隔delta = 0.001#学习速度rate = 0.001#两个单位的战力值相同,依据当前的战力公式的因子,求出两个单位的属性值player1 = get_propertys(player1_weights_factor,weights,power)player2 = get_propertys(player2_weights_factor,weights,power)out_param = []for i in range(len(weights)):new_weights = [ x for x in weights]#偏置new_weights[i] += delta#返回新的玩家属性d_p1 = get_propertys(player1_weights_factor,new_weights,power)#计算新的玩家属性,与玩家2的属性的方差的变化d = (error(d_p1,player2)-error(player1,player2))/delta#梯度下降,得到新的权重out_param.append(weights[i] - rate*d)return out_param#总战力
power = 100#打印初始值
print(weights)errorData = []#训练100000次
for i in range(100000):#随机生成两个战斗单位的属性权重因子,他们的属性的比例值是随机的player1_weights_factor = get_weight_factor(np.random.uniform(5,30,3))player2_weights_factor = get_weight_factor(np.random.uniform(5,30,3))#梯度下降,生成新的权重weights =  gradient_descent(player1_weights_factor,player2_weights_factor)#每1000次训练,打印结果if i%1000 == 0:p1 = get_propertys(player1_weights_factor,weights,power)p2 = get_propertys(player2_weights_factor,weights,power)errorNum = error(p1,p2)errorData.append(errorNum)#print('p1 {} p2 {}'.format(p1,p2))print('weights = {} error = {:6f}'.format(weights, errorNum))#图形输入值
input_values = [x*1000 for x in range(len(errorData))]
#图形输出值
squares = errorData#plot根据列表绘制出有意义的图形,linewidth是图形线宽,可省略
plt.plot(input_values,squares,linewidth=1)
#设置图标标题
plt.title("Training",fontsize = 24)
#设置坐标轴标签
plt.xlabel("Training Times",fontsize = 14)
plt.ylabel("error value",fontsize = 14)
#设置刻度标记的大小
plt.tick_params(axis='both',labelsize = 14)
#打开matplotlib查看器,并显示绘制图形
plt.show()

输出结果:

总结:

驯良10000次之后,误差基本稳定下来。

战力公式的权重比值为:5.13 : 2.56 : 10.28

约等于伤害计算式的属性价值:2:1:4

以下是tensorflow实现的算法

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np# 模型,有三个变量 a,b,c
# 模型输入为玩家属性
# 模型输出为玩家战斗力
weights = []
weights.append( tf.Variable(np.random.uniform(5,10),name='a'))
weights.append( tf.Variable(np.random.uniform(5,10),name='b'))
weights.append( tf.Variable(np.random.uniform(5,10),name='c'))# 假设战斗单位包含三个属性
# atk           攻击力
# def           防御力
# true_dmg      真实伤害
# 假设伤害公式为:
# dmg = (player1.atk-0.5*player2.def)+player1.atk_plus
# 战力公式:
# power = a*atk+b*def+c*true_dmg
# 则公式权重:2:1:4
# 训练完成的模型参数对比看是不是这个,如果是则表示正确
def damage(player1,player2):dmg = player1[0]-0.5*player2[1]dmg += 2.0*player1[2]return dmg#玩家的总战力
power = 100# 随机生成玩家的数据,用来训练
# 玩家的总战力是100,但三个属性值不一样
def create_player(weights):#随机玩家三个属性的战力分配比例player_factor = np.random.uniform(5,30,3)player_factor /= np.sum(player_factor)#各属性的战力除以战力公式的权重,得到玩家的属性player = []for i in range(len(weights)):player.append(power*player_factor[i]/weights[i])return player#定义损失函数
def loss(p1,p2):error = damage(p1,p2)-damage(p2,p1)return tf.square(error)+0.01*tf.reduce_sum(tf.square(weights)) #加上L2正则化项#训练
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)errorData = []with tf.GradientTape(persistent=True) as trap:for i in range(5000):player1 = create_player(weights)player2 = create_player(weights)loss_value = loss(player1,player2)grads = trap.gradient(loss_value,weights)optimizer.apply_gradients(zip(grads, weights))result = []result.append(weights[0].numpy())result.append(weights[1].numpy())result.append(weights[2].numpy())print("Loss at step {:03d}:weights = {} error =  {:.3f}".format(i,result, loss_value))errorData.append(loss( player1, player2))#图形输入值
input_values = [x for x in range(len(errorData))]
#图形输出值
squares = errorData#plot根据列表绘制出有意义的图形,linewidth是图形线宽,可省略
plt.plot(input_values,squares,linewidth=1)
#设置图标标题
plt.title("Training",fontsize = 24)
#设置坐标轴标签
plt.xlabel("Training Times",fontsize = 14)
plt.ylabel("error value",fontsize = 14)
#设置刻度标记的大小
plt.tick_params(axis='both',labelsize = 14)
#打开matplotlib查看器,并显示绘制图形
plt.show()

用机器学习算法来求取战斗力公式相关推荐

  1. 关于cuda和opencv混合编译之后的一些算法加速--求取灰度平均数值

    今天就来说说关于使用opencv 使用cuda加速的版本吧,来做一点记录,免的以后忘记了 下载opnecv4.10板本和contrib4.10版本,使用cmke编译,这里注意 opencv选项中,扩展 ...

  2. [机器学习-数学] 矩阵求导(分母布局与分子布局),以及常用的矩阵求导公式

    一, 矩阵求导 1,矩阵求导的本质 矩阵A对矩阵B求导: 矩阵A中的每一个元素分别对矩阵B中的每个元素进行求导. A1×1A_{1\times1}A1×1​, B1×1B_{1\times1}B1×1 ...

  3. 期末作业——基于机器学习算法的LOL比赛预测(求高分,拜托拜托)

    前言:2018年5月2日,各大高校男生宿舍不约而同的爆发出尖叫和呼喊声.难道是"单身少年们"集体受到刺激,而引发的集体抗议吗?在这一切的背后究竟隐藏着怎样的秘密? 其实真相是: 一 ...

  4. 算法学习:后缀数组 height的求取

    [前置知识] 后缀数组 [定义] [LCP]全名最长公共前缀,两个后缀之间的最长前缀,以下我们定义 lcp ( i , j ) 的意义是后缀 i 和 j 的最长前缀 [z函数] 函数z [ i ] 表 ...

  5. MATLAB点云处理:读取、展示、最近邻、ICP算法求取转移矩阵、旋转

    MATLAB中关于点云的几个函数的简单应用.作者使用的是MATLAB R2015b,这几个函数应该是在Computer Vison包里. 全文都是作者自己结合MATLAB文档的理解,欢迎指教. 1. ...

  6. 关系模式候选键求取的算法

    在学习数据库的时候,经常要碰到候选键的求取,但是一开始的时候,根本搞不清楚怎么去求,最近看了一些文章和资料,终于搞明白了. 首先来看候选键的定义:若关系中的某一属性组的值能唯一地标识一个元组,则称该属 ...

  7. 过滤三角网算法求取凹包(二)

    文章目录 一.原理概述 二.代码实现 三.实现效果 参考文献 一.原理概述 之前写过一篇文章过滤三角网算法求取凹包,但是这个方法当时编写的有问题,后面自己又重新修改了一下,过程仍然和之前的过程相同: ...

  8. 机器学习-算法-有监督学习:EM(最大期望值算法)<=> MLE(最大似然估计法)【关系类似“梯度下降法”<=>“直接求导法”】【EM“梯度下降”:先初始化一个随机值,然后通过迭代不断靠近真实值】

    机器学习-算法-有监督学习:EM(最大期望值算法)<=> MLE(最大似然估计法)[关系类似"梯度下降法"<=>"直接求导法"][EM& ...

  9. vivado HLS ORB算法设计实现----质心求取主方向

    在采用HLS进行设计的时候,必须要先了解它本身架构的数据处理流程,比如hls:stream这个数据流结构,HLS里面所有的例程都是根据这种数据流进行处理的. 由于fast算法里面已经有实现的封装库了, ...

最新文章

  1. oracle恢复是怎么看进度,Oracle中查看慢查询进度的脚本分享
  2. sql查询父节点所有子节点id_5招搞定SQL棘手问题,同事看到直呼“内行”
  3. Java执行main方法,异常为:could not find the main class.program will exit
  4. mysql创建非聚集索引_聚集索引和非聚集索引的区别
  5. gps数据存储mysql_gps数据存储mysql
  6. Ubuntu开放指定端口
  7. Effective Objective-C 2.0 初读小结
  8. 配置apache支持PHP(win7)
  9. 如何解决JSP中文乱码问题
  10. 斐波那契数列:一道100年后羊圈羊的数量算法题
  11. c语言关键用法大全,c语言关键字的用法详解
  12. go程序设计语言学习 popCount
  13. Debian 8 安装BtSync
  14. 如何理解静态库与动态库
  15. 一个懒得程序员才是一个好的程序员
  16. win7打印机显示服务器脱机怎么办,手把手教你设置win7系统网络打印机脱机的修复教程...
  17. NYOJ-1273-宣传墙
  18. CSDN日报180521——《如何选择值得深入学习的技术方向》
  19. 10个最佳iOS Photo App模板
  20. office365离线安装

热门文章

  1. 基于锁相环的直流电机控制系统simulink仿真
  2. 电子设计教程12:Buck降压电路
  3. 人生感悟人生是一场修行
  4. 计算机毕业设计之java+ssm的洗衣店管理系统
  5. 2 C/C++快速入门
  6. 诸葛io+DeepShare技术 轻松掌握渠道效果监测
  7. 围棋初学者入门知识——必需掌握的29个围棋术语
  8. HTML5+CSS3期末大作业:电影网站设计——黑色扁平的电影工作室静态网页 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码
  9. 解惑:NFC手机怎样轻松读取银行卡信息?
  10. 2021高考数学成绩查询,吐血整理!2020高考数学评分细则参考,2021高考这样准备少丢分!...