云顶之弈阵容助⼿-基于遗传算法
LOL云顶之弈⼈⼯智障助⼿
概述
本⼈云顶新⼿,好多年不玩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
计算得分时候,不考虑羁绊效果不平衡的情况(我也玩得少…不⼤了解)另外,默认组成⼈⼝越多,羁绊效果增加得越多(采⽤平⽅得分函数)
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
遗传算法设计
编码的话,就是⽤的实数编码
得分函数选择是上⾯的阵容得分+所需⾦币数(越贵的英雄越强)
选择策略是得分最⾼的个体直接复制到下⼀代,得分最低的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 >0else0
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 >0else0
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 >0else0
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
运⾏结果
效果还不错,⼤概⼏秒钟就能运⾏出结果,不影响游戏进度
发布评论