概述
本人云顶新手,好多年不玩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)
————————————————