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

概述

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

运行结果

在这里插入图片描述
效果还不错,大概几秒钟就能运行出结果,不影响游戏进度

同时为不熟悉python的小伙伴做了个双击直接运行版本
双击,cmd里根据提示输入参数即可
(至少需要安装pandas库,命令:pip install pandas)
在这里插入图片描述

完整代码——Github欢迎star

https://github.com/zzzzzzhang/LOL-ydzy

  • 47
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: 作为一个AI语言模型,我可以为您提供编写云顶之弈自动拿牌程序的一些基本思路和建议。但请注意,自动拿牌程序的开发需要一定的技术基础和对游戏规则的深入了解,也可能涉及到版权和合法性的问题,请用户自行考虑并承担风险。 首先,我们需要准备游戏数据和基础算法。通过对游戏进行观察和解析,收集玩家和AI的数据信息,建立相应的数据模型和算法模型,以实现自动判断拿牌的策略和优先级。 其次,我们需要通过编写代码,实现数据输入、处理、逻辑判断、输出等一系列操作,以实现自动化拿牌的功能。具体的实现思路可以包括:在游戏开始时读取游戏参数和数据,分析并记录手牌、桌牌、卡牌出牌历史等信息;根据模型算法,定义相应的优先级和规则,判断出牌策略;编写判断逻辑和规则,使AI在游戏中能够实时根据情况进行出牌。 最后,我们需要对程序进行测试和优化,验证程序的稳定性和准确性。在测试过程中,通过模拟多个游戏场景和对手,测试程序的表现和反应速度,并持续优化和改进程序的算法和效率。同时,针对可能出现的异常情况,添加异常处理和保护机制,避免程序出现崩溃或异常。 总的来说,编写自动拿牌程序需要多方面的努力和技能储备。除了计算机技术方面的知识,还需要对游戏规则和策略的深入理解,以及耐心和实践积累。 ### 回答2: 要编写一个云顶之弈的自动拿牌程序,需要考虑以下几个步骤: 首先,需要使用编程语言(如Python)创建一个图形用户界面(GUI),以便用户可以与程序进行交互。可以使用现有的GUI库(如Tkinter)来实现这一点。 接下来,程序需要实现云顶之弈游戏的基本规则和机制。这包括创建一个虚拟游戏板,初始化玩家和角色,设置游戏回合等。程序需要保持追踪玩家之间的顺序,以便在每个回合中按照规则正确地发给他们卡牌。 为了实现自动拿牌功能,程序可以使用随机数生成器来模拟抽牌的过程。在每个玩家的回合开始时,程序可以从卡组中随机选择一张卡牌,并将其添加到该玩家的手牌。 此外,程序还需要实现游戏策略和决策机制。这包括评估当前局势和卡牌的价值,选择最佳战略来调整自己的卡组,并决定是否购买更多的卡牌以增强实力。 最后,程序需要在每个回合结束后更新游戏板和玩家的状态,并在达到游戏结束条件时判断获胜者。 总结来说,要编写一个云顶之弈的自动拿牌程序,需要实现游戏规则和机制、随机抽牌、游戏策略和决策机制、以及游戏状态的更新和判断。 ### 回答3: 要编写一个云顶之弈的自动拿牌程序,首先需要了解游戏的规则和机制。云顶之弈是一款回合制策略游戏,玩家通过选择并购买卡牌来组建强力的战队,然后与其他玩家进行对战。 编写自动拿牌程序的主要步骤如下: 1. 创建游戏界面:使用图形化界面库创建一个模拟的游戏界面,包括显示卡牌和金币数量等信息的区域。 2. 获取游戏信息:通过屏幕截图或使用游戏客户端提供的API,获取游戏界面中有关当前玩家的信息,如当前场上的卡牌和金币数量。 3. 制定策略:根据游戏规则和当前的游戏状态,制定一个策略来决定应该购买哪些卡牌。策略可以基于卡牌的品质、费用和在当前局势下的战略意义等因素来决定。 4. 自动购买卡牌:根据制定的策略,通过模拟点击操作自动购买相应的卡牌。可以使用模拟点击库来实现自动点击。 5. 更新游戏信息:购买卡牌后,更新游戏界面中有关当前玩家的信息。即更新当前的场上卡牌和金币数量等信息。 6. 优化算法:持续观察游戏的发展和效果,并根据实际情况来改进策略和购买卡牌的算法。可以通过机器学习的方法来自动优化算法。 需要注意的是,编写一个完整的自动拿牌程序需要对游戏的战术、策略和规则有深入的理解。此外,还需要有编程经验和相关技术的支持才能实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值