云顶之弈阵容助手-基于遗传算法

  概述

  本人云顶新手,好多年不玩LOL了,被朋友安利云顶之弈,玩了两天觉得有点意思。但是这个游戏阵容可搭配太多了,如果不是天天研究这个游戏的,很难吃鸡。所以我就心血来潮想写个阵容助手(python),给定几个你想玩的英雄,基于遗传算法向玩家推荐阵容。目前适配9.19版本,不过后面有新阵容出现的话,改起来也方便。增加铲子功能,不过只能增加一个(增加两个的话计算量大,不够实时性)

  爬取相关网站内容获取英雄信息

  这一步是可以自己输入的,但是作为一个倔强的程序员,显然不能做这种事(手动狗头)

  一开始选的是lol官网…搞半天都搞不出来(技术不够,泪目)

  后来发现还是多玩好爬一点

  结果如下

  另外还保存了英雄的昵称与其对应的id,方便输入(有时候真想不起来英雄的真名啊)

  阵容搭配与得分

  建立一个列表,记录各种阵容搭配,需要人口数目,记录铲子能增加的羁绊

  计算英雄阵容与所需金币总数

  def teamtype(hero_ids, heros_info):

  '''

  查看阵容,金币

  '''

  team = {}

  gold = 0

  for hero_id in hero_ids:

  gold += heros_info['gold'][hero_id]

  for job in heros_info['info'][hero_id]:

  if job in team:

  team[job] += 1

  else:

  team[job] = 1

  return team, gold

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  计算得分时候,不考虑羁绊效果不平衡的情况(我也玩得少…不大了解)

  另外,默认组成人口越多,羁绊效果增加得越多(采用平方得分函数)

  def calculateTeamScore(team, show= 0, shovel= False):

  '''

  计算队伍得分(铲子)

  羁绊得分规则:按达成羁绊人数得分,不考虑羁绊效果不平衡

  '''

  max_score = 0

  if shovel:

  #计算铲子

  change = 'null'

  team_out = {}

  for j in shovel_add:

  #如果队伍里没有相关职业,跳过(铲子没有单独羁绊)

  if j not in team.keys():

  continue

  team_copy = copy.deepcopy(team)

  team_copy[j] +=1

  score = calc(team= team_copy, show= 0)

  change = change if score <= max_score else j

  team_out = team_out if score <= max_score else copy.deepcopy(team_copy)

  max_score = max_score if score <= max_score else score

  calc(team= team_out, show= show)

  return max_score, change

  else:

  max_score = calc(team= team, show= show)

  return max_score, None

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  遗传算法设计

  编码的话,就是用的实数编码

  得分函数选择是上面的阵容得分+所需金币数(越贵的英雄越强)

  选择策略是得分最高的个体直接复制到下一代,得分最低的9个个体直接全部重抽

  上代码:

  def GA(team_pnum, selected_ids, heros_info, heros_info_short,gens = 100, sample = 50, alpha = 0.5, shovel= False):

  '''

  team_pnum:你想组成多少人队伍

  selected_ids:列表,已经选定哪些英雄

  heros_info:英雄信息

  heros_info_short:英雄名称缩写信息

  gens:最大繁殖多少代

  sample:每代繁衍个体数

  alpha:金钱影响程度(值越大,越偏向便宜的英雄)

  '''

  selected_ids = getHeroid(selected_ids,heros_info_short= heros_info_short)

  hero_info_cp = copy.deepcopy(heros_info)

  k = len(selected_ids)

  n = team_pnum - k

  hero_couldchose = hero_info_cp['hero_id']

  for idxs in selected_ids:

  hero_couldchose.pop(hero_couldchose.index(idxs))

  #生成第一代

  scores = {

  'chosed_ids':[],

  'score':[]

  }

  for i in range(sample):

  hero_thisGenCouldChose = copy.deepcopy(hero_couldchose)

  random.shuffle(hero_thisGenCouldChose)

  teamChoesd = selected_ids + hero_thisGenCouldChose[:n]

  team, gold = teamtype(teamChoesd, hero_info_cp)

  score,change = calculateTeamScore(team,shovel= shovel)

  # print('<================================>')

  score = score * 10 - gold * alpha if score > 0 else 0

  scores['chosed_ids'].append(teamChoesd)

  scores['score'].append(score)

  #开始繁衍

  maxscores = []

  for gen in range(gens):

  scores_thisgen = {

  'chosed_ids':[],

  'score':[]

  }

  #最优的个体直接保存

  score_max_idx = scores['score'].index(max(scores['score']))

  scores_thisgen['chosed_ids'].append(scores['chosed_ids'][score_max_idx])

  scores_thisgen['score'].append(scores['score'][score_max_idx])

  #最差个体的直接重置掉(重复9次)

  for i in range(9):

  #重排、重选序号

  random.shuffle(hero_thisGenCouldChose)

  teamChoesd= selected_ids + hero_thisGenCouldChose[:n]

  #重新赋值

  score_min_idx = scores['score'].index(min(scores['score']))

  scores['chosed_ids'][score_min_idx] = teamChoesd

  scores_thisgen['chosed_ids'].append(teamChoesd)

  #计算得分

  team, gold = teamtype(teamChoesd, hero_info_cp)

  score,change = calculateTeamScore(team, shovel= shovel)

  score = score * 10 - gold * alpha if score > 0 else 0

  scores['score'][score_min_idx] = score

  scores_thisgen['score'].append(score)

  #计算累积概率

  p = [0]

  totalScores = sum(scores['score'])

  for i in range(2,sample):

  p.append(p[-1] + scores['score'][i]/totalScores)

  #根据轮盘赌法生成新一代个体

  for i in range(sample):

  #有莫名bug找不到双亲,所以先赋值,如果后面找到了会被覆盖

  Dad = scores['chosed_ids'][0]

  Mom = scores['chosed_ids'][-1]

  #选父体

  rnd = random.random()

  for theone in range(len(p)):

  if p[theone] > rnd:

  Dad = scores['chosed_ids'][theone - 1]

  break

  else:

  continue

  #选母体

  rnd = random.random()

  for theone in range(len(p)):

  if p[theone] > rnd:

  Mom = scores['chosed_ids'][theone - 1]

  break

  else:

  continue

  #求并集

  dadmon = list(set(Dad[k:]) | set(Mom[k:]))

  random.shuffle(dadmon)

  baby = selected_ids + dadmon[:n]

  #求得分

  team, gold = teamtype(baby, hero_info_cp)

  score,change = calculateTeamScore(team, shovel= shovel)

  score = score * 10 - gold * alpha if score > 0 else 0

  scores_thisgen['chosed_ids'].append(baby)

  scores_thisgen['score'].append(score)

  maxscores.append(max(scores_thisgen['score']))

  #保存这代信息

  scores = copy.deepcopy(scores_thisgen)

  #取出最佳个体

  besTeam = scores['chosed_ids'][scores['score'].index(max(scores['score']))]

  return besTeam, maxscores  郑州男科医院:http://www.63556355.com/郑州看男科哪家好:http://www.63556355.com/郑州割包皮多少钱:http://www.63556355.com/

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  41

  42

  43

  44

  45

  46

  47

  48

  49

  50

  51

  52

  53

  54

  55

  56

  57

  58

  59

  60

  61

  62

  63

  64

  65

  66

  67

  68

  69

  70

  71

  72

  73

  74

  75

  76

  77

  78

  79

  80

  81

  82

  83

  84

  85

  86

  87

  88

  89

  90

  91

  92

  93

  94

  95

  96

  97

  98

  99

  100

  101

  102

  103

  104

  105

  106

  107

  108

  109

  110

  111

  112

  113

  运行结果

  效果还不错,大概几秒钟就能运行出结果,不影响游戏进度

  同时为不熟悉python的小伙伴做了个双击直接运行版本

  双击,cmd里根据提示输入参数即可

  (至少需要安装pandas库,命令:pip install pandas)

  ————————————————

原文地址:https://www.cnblogs.com/sushine1/p/11654236.html