├── app ├── utils │ ├── icon │ │ ├── ahri.gif │ │ ├── ashe.gif │ │ ├── ekko.gif │ │ ├── fizz.gif │ │ ├── jhin.gif │ │ ├── jinx.gif │ │ ├── lulu.gif │ │ ├── lux.gif │ │ ├── shen.gif │ │ ├── sona.gif │ │ ├── vi.gif │ │ ├── zoe.gif │ │ ├── annie.gif │ │ ├── darius.gif │ │ ├── ezreal.gif │ │ ├── fiora.gif │ │ ├── graves.gif │ │ ├── irelia.gif │ │ ├── jayce.gif │ │ ├── kaisa.gif │ │ ├── karma.gif │ │ ├── kayle.gif │ │ ├── khazix.gif │ │ ├── leona.gif │ │ ├── lucian.gif │ │ ├── neeko.gif │ │ ├── poppy.gif │ │ ├── rakan.gif │ │ ├── rumble.gif │ │ ├── shaco.gif │ │ ├── soraka.gif │ │ ├── syndra.gif │ │ ├── thresh.gif │ │ ├── velkoz.gif │ │ ├── wukong.gif │ │ ├── xayah.gif │ │ ├── xerath.gif │ │ ├── yasuo.gif │ │ ├── ziggs.gif │ │ ├── Chogath.gif │ │ ├── caitlyn.gif │ │ ├── gangplank.gif │ │ ├── jarvan_iv.gif │ │ ├── kassadin.gif │ │ ├── malphite.gif │ │ ├── master_yi.gif │ │ ├── xin_zhao.gif │ │ ├── blitzcrank.gif │ │ ├── mordekaiser.gif │ │ ├── twistedfate.gif │ │ ├── aurelion_sol.gif │ │ ├── miss_fortune.gif │ │ └── player │ │ │ ├── agent1.gif │ │ │ ├── agent2.gif │ │ │ ├── agent3.gif │ │ │ ├── agent4.gif │ │ │ ├── agent5.gif │ │ │ ├── agent6.gif │ │ │ ├── agent7.gif │ │ │ └── agent8.gif │ ├── __pycache__ │ │ ├── draw.cpython-37.pyc │ │ ├── draw.cpython-38.pyc │ │ ├── view.cpython-37.pyc │ │ └── function.cpython-37.pyc │ ├── function.py │ └── view.py ├── json1.py ├── __pycache__ │ ├── env.cpython-36.pyc │ ├── env.cpython-37.pyc │ ├── env.cpython-38.pyc │ ├── json.cpython-37.pyc │ ├── config.cpython-36.pyc │ ├── __main__.cpython-38.pyc │ ├── config_2.cpython-36.pyc │ ├── config_3.cpython-36.pyc │ ├── config_3.cpython-37.pyc │ ├── config_3.cpython-38.pyc │ └── one_player.cpython-37.pyc ├── buff │ ├── __pycache__ │ │ ├── items.cpython-37.pyc │ │ └── synergy.cpython-37.pyc │ ├── items.py │ └── synergy.py ├── fight │ ├── __pycache__ │ │ ├── fight.cpython-36.pyc │ │ ├── fight.cpython-37.pyc │ │ ├── fight.cpython-38.pyc │ │ ├── items.cpython-37.pyc │ │ └── skill.cpython-37.pyc │ ├── fight.py │ └── skill.py ├── agent │ ├── __pycache__ │ │ ├── random_agent.cpython-37.pyc │ │ └── rulebased_agent.cpython-37.pyc │ ├── random_agent.py │ └── rulebased_agent.py ├── main.py ├── env.py ├── one_player.py ├── config_3.py └── result.json ├── Dockerfile └── README.md /app/utils/icon/ahri.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/ahri.gif -------------------------------------------------------------------------------- /app/utils/icon/ashe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/ashe.gif -------------------------------------------------------------------------------- /app/utils/icon/ekko.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/ekko.gif -------------------------------------------------------------------------------- /app/utils/icon/fizz.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/fizz.gif -------------------------------------------------------------------------------- /app/utils/icon/jhin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/jhin.gif -------------------------------------------------------------------------------- /app/utils/icon/jinx.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/jinx.gif -------------------------------------------------------------------------------- /app/utils/icon/lulu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/lulu.gif -------------------------------------------------------------------------------- /app/utils/icon/lux.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/lux.gif -------------------------------------------------------------------------------- /app/utils/icon/shen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/shen.gif -------------------------------------------------------------------------------- /app/utils/icon/sona.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/sona.gif -------------------------------------------------------------------------------- /app/utils/icon/vi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/vi.gif -------------------------------------------------------------------------------- /app/utils/icon/zoe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/zoe.gif -------------------------------------------------------------------------------- /app/utils/icon/annie.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/annie.gif -------------------------------------------------------------------------------- /app/utils/icon/darius.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/darius.gif -------------------------------------------------------------------------------- /app/utils/icon/ezreal.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/ezreal.gif -------------------------------------------------------------------------------- /app/utils/icon/fiora.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/fiora.gif -------------------------------------------------------------------------------- /app/utils/icon/graves.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/graves.gif -------------------------------------------------------------------------------- /app/utils/icon/irelia.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/irelia.gif -------------------------------------------------------------------------------- /app/utils/icon/jayce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/jayce.gif -------------------------------------------------------------------------------- /app/utils/icon/kaisa.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/kaisa.gif -------------------------------------------------------------------------------- /app/utils/icon/karma.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/karma.gif -------------------------------------------------------------------------------- /app/utils/icon/kayle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/kayle.gif -------------------------------------------------------------------------------- /app/utils/icon/khazix.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/khazix.gif -------------------------------------------------------------------------------- /app/utils/icon/leona.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/leona.gif -------------------------------------------------------------------------------- /app/utils/icon/lucian.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/lucian.gif -------------------------------------------------------------------------------- /app/utils/icon/neeko.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/neeko.gif -------------------------------------------------------------------------------- /app/utils/icon/poppy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/poppy.gif -------------------------------------------------------------------------------- /app/utils/icon/rakan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/rakan.gif -------------------------------------------------------------------------------- /app/utils/icon/rumble.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/rumble.gif -------------------------------------------------------------------------------- /app/utils/icon/shaco.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/shaco.gif -------------------------------------------------------------------------------- /app/utils/icon/soraka.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/soraka.gif -------------------------------------------------------------------------------- /app/utils/icon/syndra.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/syndra.gif -------------------------------------------------------------------------------- /app/utils/icon/thresh.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/thresh.gif -------------------------------------------------------------------------------- /app/utils/icon/velkoz.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/velkoz.gif -------------------------------------------------------------------------------- /app/utils/icon/wukong.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/wukong.gif -------------------------------------------------------------------------------- /app/utils/icon/xayah.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/xayah.gif -------------------------------------------------------------------------------- /app/utils/icon/xerath.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/xerath.gif -------------------------------------------------------------------------------- /app/utils/icon/yasuo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/yasuo.gif -------------------------------------------------------------------------------- /app/utils/icon/ziggs.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/ziggs.gif -------------------------------------------------------------------------------- /app/utils/icon/Chogath.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/Chogath.gif -------------------------------------------------------------------------------- /app/utils/icon/caitlyn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/caitlyn.gif -------------------------------------------------------------------------------- /app/utils/icon/gangplank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/gangplank.gif -------------------------------------------------------------------------------- /app/utils/icon/jarvan_iv.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/jarvan_iv.gif -------------------------------------------------------------------------------- /app/utils/icon/kassadin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/kassadin.gif -------------------------------------------------------------------------------- /app/utils/icon/malphite.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/malphite.gif -------------------------------------------------------------------------------- /app/utils/icon/master_yi.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/master_yi.gif -------------------------------------------------------------------------------- /app/utils/icon/xin_zhao.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/xin_zhao.gif -------------------------------------------------------------------------------- /app/json1.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | with open('result.json') as f: 4 | jd=json.load(f) 5 | print(jd) 6 | -------------------------------------------------------------------------------- /app/utils/icon/blitzcrank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/blitzcrank.gif -------------------------------------------------------------------------------- /app/utils/icon/mordekaiser.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/mordekaiser.gif -------------------------------------------------------------------------------- /app/utils/icon/twistedfate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/twistedfate.gif -------------------------------------------------------------------------------- /app/utils/icon/aurelion_sol.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/aurelion_sol.gif -------------------------------------------------------------------------------- /app/utils/icon/miss_fortune.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/miss_fortune.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent1.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent2.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent3.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent4.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent5.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent6.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent7.gif -------------------------------------------------------------------------------- /app/utils/icon/player/agent8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/icon/player/agent8.gif -------------------------------------------------------------------------------- /app/__pycache__/env.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/env.cpython-36.pyc -------------------------------------------------------------------------------- /app/__pycache__/env.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/env.cpython-37.pyc -------------------------------------------------------------------------------- /app/__pycache__/env.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/env.cpython-38.pyc -------------------------------------------------------------------------------- /app/__pycache__/json.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/json.cpython-37.pyc -------------------------------------------------------------------------------- /app/__pycache__/config.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/config.cpython-36.pyc -------------------------------------------------------------------------------- /app/__pycache__/__main__.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/__main__.cpython-38.pyc -------------------------------------------------------------------------------- /app/__pycache__/config_2.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/config_2.cpython-36.pyc -------------------------------------------------------------------------------- /app/__pycache__/config_3.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/config_3.cpython-36.pyc -------------------------------------------------------------------------------- /app/__pycache__/config_3.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/config_3.cpython-37.pyc -------------------------------------------------------------------------------- /app/__pycache__/config_3.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/config_3.cpython-38.pyc -------------------------------------------------------------------------------- /app/__pycache__/one_player.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/__pycache__/one_player.cpython-37.pyc -------------------------------------------------------------------------------- /app/buff/__pycache__/items.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/buff/__pycache__/items.cpython-37.pyc -------------------------------------------------------------------------------- /app/buff/__pycache__/synergy.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/buff/__pycache__/synergy.cpython-37.pyc -------------------------------------------------------------------------------- /app/fight/__pycache__/fight.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/fight/__pycache__/fight.cpython-36.pyc -------------------------------------------------------------------------------- /app/fight/__pycache__/fight.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/fight/__pycache__/fight.cpython-37.pyc -------------------------------------------------------------------------------- /app/fight/__pycache__/fight.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/fight/__pycache__/fight.cpython-38.pyc -------------------------------------------------------------------------------- /app/fight/__pycache__/items.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/fight/__pycache__/items.cpython-37.pyc -------------------------------------------------------------------------------- /app/fight/__pycache__/skill.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/fight/__pycache__/skill.cpython-37.pyc -------------------------------------------------------------------------------- /app/utils/__pycache__/draw.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/__pycache__/draw.cpython-37.pyc -------------------------------------------------------------------------------- /app/utils/__pycache__/draw.cpython-38.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/__pycache__/draw.cpython-38.pyc -------------------------------------------------------------------------------- /app/utils/__pycache__/view.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/__pycache__/view.cpython-37.pyc -------------------------------------------------------------------------------- /app/utils/__pycache__/function.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/utils/__pycache__/function.cpython-37.pyc -------------------------------------------------------------------------------- /app/agent/__pycache__/random_agent.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/agent/__pycache__/random_agent.cpython-37.pyc -------------------------------------------------------------------------------- /app/agent/__pycache__/rulebased_agent.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinJeon/RL_TFT/HEAD/app/agent/__pycache__/rulebased_agent.cpython-37.pyc -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM pytorch/pytorch 2 | 3 | RUN conda install -c conda-forge opencv 4 | 5 | COPY app /workspace/app 6 | 7 | 8 | WORKDIR /workspace/app 9 | 10 | CMD ["python", "main.py"] 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Teamfight Tactics(TFT) for Machine Learning 2 | 3 | Follow the command to test the environment. 4 | 5 | ```bash 6 | docker build -t rl_tft . 7 | docker run -it -e "DISPLAY" -v /tmp/.X11-unix/:/tmp/.X11-unix/ rl_tft 8 | 9 | # In case, you're running on Windows system, make sure that a X dispaly server is installed, such as Xming. 10 | ``` 11 | 12 | ## TODOs 13 | - [ ] Modularize a big file into smaller pieces. 14 | - [ ] Make use of Environment variables for configuration. 15 | - [ ] Extend this Todo list. 16 | - [ ] Make Pathfinder. 17 | - [ ] Update View File 18 | 19 | -------------------------------------------------------------------------------- /app/agent/random_agent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | class RandomAgent: 3 | def bef_action(money,player_level,five_champs,five_cost,total_units,unit_number): 4 | a = list(range(9)) 5 | if money < 2: 6 | ind = a.index(7) 7 | del a[ind] 8 | if (money < 4) or (player_level == 9): 9 | ind = a.index(8) 10 | del a[ind] 11 | if unit_number >= player_level + 9: 12 | ind = a.index(0) 13 | del a[ind] 14 | ind = a.index(1) 15 | del a[ind] 16 | ind = a.index(2) 17 | del a[ind] 18 | ind = a.index(3) 19 | del a[ind] 20 | ind = a.index(4) 21 | del a[ind] 22 | else: 23 | for i in range(5): 24 | if (five_champs[i] == False) or (money < five_cost[i]): 25 | ind = a.index(i) 26 | del a[ind] 27 | if total_units: 28 | ind = a.index(6) 29 | del a[ind] 30 | if money <= 0: 31 | a = [5] 32 | act = np.random.choice(a,1)[0] 33 | return act 34 | def rearr_action(player_level,syns): 35 | 1 == 1 36 | -------------------------------------------------------------------------------- /app/utils/function.py: -------------------------------------------------------------------------------- 1 | import config_3 as cfg 2 | import numpy as np 3 | def find_name(ind): 4 | champs = list(cfg.champ_state_info) 5 | if ind == 100: 6 | return dict(name='Mech Pilot',cost=0,elem=[]) 7 | return champs[ind-1] 8 | def a_star(hexes,st,en): 9 | sth = [st[0]+int(round(st[1]/2+0.001)),st[1]] 10 | enh = [en[0]+int(round(en[1]/2+0.001)),en[1]] 11 | move = [[-1,0],[1,0],[0,-1],[0,1],[1,1],[-1,-1]] 12 | f_list = [] 13 | for i in range(6): 14 | g = np.max([abs(move[i][0]),abs(move[i][1]),abs(move[i][0]-move[i][1])]) 15 | h = np.max([abs(enh[0]-sth[0]-move[i][0]),abs(enh[1]-sth[1]-move[i][1]), 16 | abs(enh[0]-sth[0]-move[i][0]-enh[1]+sth[1]+move[i][1])]) 17 | f = g + h 18 | f_list.append(f) 19 | while True: 20 | minval = np.min(f_list) 21 | candidates = np.where(f_list==minval) 22 | near = np.random.choice(candidates[0],1)[0] 23 | mxh,myh = move[near][0]+sth[0],sth[1]+move[near][1] 24 | orig = np.array([int(mxh-round(myh/2+0.001)),myh]) 25 | if np.sum(f_list) == 6000: 26 | return [0,0] 27 | elif (orig[0] < 0) or (orig[0] > 6) or (orig[1] < 0) or (orig[1] > 7): 28 | f_list[near] = 1000 29 | elif hexes[orig[0],orig[1],0] != 0: 30 | f_list[near] = 1000 31 | else: 32 | break 33 | return orig 34 | -------------------------------------------------------------------------------- /app/main.py: -------------------------------------------------------------------------------- 1 | from env import TFT_env 2 | import config_3 as cfg 3 | import numpy as np 4 | from agent.random_agent import RandomAgent 5 | from agent.rulebased_agent import RulebasedAgent 6 | from one_player import Player 7 | import json,os,copy 8 | 9 | def main(champ_state_info=None): 10 | keys = dict() 11 | print(len(cfg.champ_level_info)) 12 | for k,i in cfg.__dict__.items(): 13 | if k[:2] != '__': 14 | keys[k] = i 15 | env = TFT_env(**keys) 16 | if champ_state_info: 17 | env.champ_state_info = champ_state_info 18 | # plug-in the player 19 | rand = RandomAgent 20 | rule = RulebasedAgent 21 | agent1 = Player(rule) 22 | agent2 = Player(rand) 23 | agent3 = Player(rand) 24 | agent4 = Player(rand) 25 | agent5 = Player(rand) 26 | agent6 = Player(rand) 27 | agent7 = Player(rand) 28 | agent8 = Player(rand) 29 | env.agent1 = agent1 30 | env.agent2 = agent2 31 | env.agent3 = agent3 32 | env.agent4 = agent4 33 | env.agent5 = agent5 34 | env.agent6 = agent6 35 | env.agent7 = agent7 36 | env.agent8 = agent8 37 | env.init_game() 38 | while len(env.players) > 1: 39 | env.play_round(gui=True) 40 | return env.final_place,env.jd 41 | if __name__ == '__main__': 42 | with open('result.json','r') as f: 43 | jd = json.load(f) 44 | dataset = dict(state=[],action=[]) 45 | for i in range(1): 46 | champ_state_info = copy.deepcopy(cfg.champ_state_info) 47 | final_place,data = main(champ_state_info=champ_state_info) 48 | for k,it in final_place.items(): 49 | print(k,it) 50 | jd[k] += [it] 51 | dataset['state'] += data['state'] 52 | dataset['action'] += data['action'] 53 | #if i % 10 == 0: 54 | # with open('result.json', 'w', encoding='utf-8') as f: 55 | # json.dump(jd, f, indent="\t") 56 | -------------------------------------------------------------------------------- /app/agent/rulebased_agent.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import config_3 as cfg 3 | import operator 4 | class RulebasedAgent(object): 5 | 6 | def _synergy(total_units): 7 | synergy = dict() 8 | for unit,items in total_units.items(): 9 | for syn in items['synergy']: 10 | if str(syn) not in synergy.keys(): 11 | synergy[str(syn)] = 1 12 | else: 13 | synergy[str(syn)] += 1 14 | return synergy 15 | def bef_action(money,player_level,five_champs,five_cost,total_units,unit_number, 16 | life=None): 17 | synergy = RulebasedAgent._synergy(total_units) 18 | sorted_syns = sorted(synergy.items(),key=operator.itemgetter(0)) 19 | if len(sorted_syns) > 3: 20 | sorted_syns = sorted_syns[:3] 21 | RulebasedAgent.top_syns = [int(syn[0]) for syn in sorted_syns] 22 | a = list(range(9)) 23 | # base rule 24 | if money < 2: 25 | ind = a.index(7) 26 | del a[ind] 27 | if (money < 4) or (player_level == 9): 28 | ind = a.index(8) 29 | del a[ind] 30 | if unit_number >= player_level + 9: 31 | ind = a.index(0) 32 | del a[ind] 33 | ind = a.index(1) 34 | del a[ind] 35 | ind = a.index(2) 36 | del a[ind] 37 | ind = a.index(3) 38 | del a[ind] 39 | ind = a.index(4) 40 | del a[ind] 41 | else: 42 | for i in range(5): 43 | if (five_champs[i] == False) or (money < five_cost[i]): 44 | ind = a.index(i) 45 | del a[ind] 46 | else: 47 | syns = cfg.champ_state_info[five_champs[i]]['elem'] 48 | print(syns) 49 | for s in syns: 50 | if s in RulebasedAgent.top_syns: 51 | print(five_champs) 52 | ind = a.index(i) 53 | return i 54 | #if life < 20: 55 | # np.random.choice([7,8],1,p=[0.7,0.3])[0] 56 | if total_units: 57 | ind = a.index(6) 58 | del a[ind] 59 | if money <= 0: 60 | a = [5] 61 | if money <= 30: 62 | a = [5] 63 | else: 64 | return np.random.choice([7,8],1,p=[0.7,0.3])[0] 65 | return a[0] 66 | def rearr_action(avail_units,syns): 67 | battle_indices = [] 68 | check = list(range(len(syns))) 69 | for i,syn in enumerate(syns): 70 | is_pass = False 71 | for s in syn: 72 | if is_pass: 73 | pass 74 | elif (s in RulebasedAgent.top_syns) or (s in RulebasedAgent.top_syns): 75 | battle_indices.append(i) 76 | check.remove(i) 77 | is_pass = True 78 | tofill = avail_units - len(battle_indices) 79 | if tofill > 0: 80 | rand_fill = list(np.random.choice(check,tofill)) 81 | battle_indices += rand_fill 82 | else: 83 | 1 == 1 84 | return battle_indices 85 | -------------------------------------------------------------------------------- /app/buff/items.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | class Item: 4 | def __init__(self,item_assign,stats): 5 | self.subitem = np.zeros(13) 6 | self.subitem[5] = 15 7 | self.subitem[6] = 0.15 8 | self.subitem[7] = 25 9 | self.subitem[8] = 25 10 | self.subitem[10] = 0.2 11 | self.subitem[3] = 15 12 | self.subitem[2] = 200 13 | self.subitem[9] = 0 14 | self.subitem[12] = 0.1 15 | self.stat_infos = {2:'health',3:'mana',5:'attack_damage',6:'attack_speed', 16 | 7:'armor',8:'magical_resistance',9:'no',10:'skill',12:'dodge'} 17 | #items 18 | self.deathblade= False 19 | self.force_of_nature = 0 20 | self._make_table() 21 | self.stats = self._update(item_assign,stats) 22 | def _update(self,assigned_items,stats): 23 | for items,stat in zip(assigned_items,stats): 24 | sub = 0 25 | for item in items: 26 | sub += 1 27 | if item == 9: 28 | continue 29 | elif item == 12: 30 | stat['critical'] += self.subitem[item] 31 | stat['dodge'] += self.subitem[item] 32 | elif item == 3: 33 | stat['mana'][0] += self.subitem[item] 34 | else: 35 | stat[self.stat_infos[item]] += self.subitem[item] 36 | if sub == 2: 37 | sub = 0 38 | stat = self._merge_item(stat, i1, i2) 39 | return stats 40 | def _make_table(self): 41 | items = [2,3,5,6,7,8,9,10,12] 42 | health = [0,0,self._warmogs_armor,self._redemption,0,self._zekes_herald, 43 | self._zzrot_portal,self._red_buff,self._zephyr,self._protectors_chestguard, 44 | self._morellonomicon,0,self._trap_claw] 45 | mana = [0,0,self._redemption,self._seraphs_embrace,0,self._spear_of_shojin, 46 | self._statikk_shiv,self._frozen_heart,self._chalice_of_favor,self._star_guardians_charm, 47 | self._ludens_echo,0,self._hand_of_justice] 48 | attack_damage = [0,0,self._zekes_herald,self._spear_of_shojin,0,self._death_blade, 49 | self._giant_slayer,self._guardian_angel,self._blood_thirster,self._blade_of_the_ruined_king, 50 | self._hextech_gunblade,0,self._infinity_edge] 51 | attack_speed = [0,0,self._zzrot_portal,self._statikk_shiv,0,self._giant_slayer, 52 | self._rapid_firecannon,self._titans_resolve,self._runnans_hurricane, 53 | self._infiltrators_talons,self._guinsoos_rageblade,0,self._last_whisper] 54 | armor = [0,0,self._red_buff,self._frozen_heart,0,self._guardian_angel,self._titans_resolve, 55 | self._bramble_vest,self._sword_breaker,self._rebel_medal,self._locket_of_the_iron_solari, 56 | 0,self._shroud_of_stillness] 57 | magical_resistance = [0,0,self._zephyr,self._chalice_of_favor,0,self._blood_thirster, 58 | self._runnans_hurricane,self._sword_breaker,self._dragons_claw,self._celestial_orb, 59 | self._ionic_spark,0,self._quicksilver] 60 | spatula = [0,0,self._protectors_chestguard,self._star_guardians_charm,0, 61 | self._blade_of_the_ruined_king,self._infiltrators_talons,self._rebel_medal, 62 | self._celestial_orb,self._force_of_nature,self._demolitionists_charge, 63 | 0,self._dark_stars_heart] 64 | skill = [0,0,self._morellonomicon,self._ludens_echo,0,self._hextech_gunblade, 65 | self._guinsoos_rageblade,self._locket_of_the_iron_solari,self._ionic_spark, 66 | self._demolitionists_charge,self._rabadons_deathcap,0,self._jeweled_gauntlet] 67 | dodge_cri = [0,0,self._trap_claw,self._hand_of_justice,0,self._infinity_edge, 68 | self._last_whisper,self._shroud_of_stillness,self._quicksilver,self._dark_stars_heart, 69 | self._jeweled_gauntlet,0,self._thiefs_gloves] 70 | tables = [0,0,health,mana,0,attack_damage,attack_speed,armor,magical_resistance, 71 | spatula,skill,0,dodge_cri] 72 | self.item_table = list(np.zeros((13,13))) 73 | for i in items: 74 | for j in items: 75 | self.item_table[i] = list(self.item_table[i]) 76 | self.item_table[i][j] = tables[i][j] 77 | def _merge_item(self,stat,i1,i2): 78 | mixed_item = self.item_table[i1][i2] 79 | stat['item'] = mixed_item 80 | def _death_blade(self,c): 81 | 1 == 1 82 | def _giant_slayer(self,c): 83 | 1 == 1 84 | def _guardian_angel(self,c): 85 | 1 == 1 86 | def _blood_thirster(self,c): 87 | 1 == 1 88 | def _hextech_gunblade(self,c): 89 | 1 == 1 90 | def _spear_of_shojin(self,c): 91 | 1 == 1 92 | def _zekes_herald(self,c): 93 | 1 == 1 94 | def _blade_of_the_ruined_king(self,c): 95 | 1 == 1 96 | def _infinity_edge(self,c): 97 | 1 == 1 98 | def _rapid_firecannon(self,c): 99 | 1 == 1 100 | def _titans_resolve(self,c): 101 | 1 == 1 102 | def _runnans_hurricane(self,c): 103 | 1 == 1 104 | def _guinsoos_rageblade(self,c): 105 | 1 == 1 106 | def _statikk_shiv(self,c): 107 | 1 == 1 108 | def _zzrot_portal(self,c): 109 | 1 == 1 110 | def _infiltrators_talons(self,c): 111 | 1 == 1 112 | def _last_whisper(self,c): 113 | 1 == 1 114 | def _bramble_vest(self,c): 115 | 1 == 1 116 | def _sword_breaker(self,c): 117 | 1 == 1 118 | def _locket_of_the_iron_solari(self,c): 119 | 1 == 1 120 | def _frozen_heart(self,c): 121 | 1 == 1 122 | def _red_buff(self,c): 123 | 1 == 1 124 | def _rebel_medal(self,c): 125 | 1 == 1 126 | def _shroud_of_stillness(self,c): 127 | 1 == 1 128 | def _dragons_claw(self,c): 129 | 1 == 1 130 | def _ionic_spark(self,c): 131 | 1 == 1 132 | def _chalice_of_favor(self,c): 133 | 1 == 1 134 | def _zephyr(self,c): 135 | 1 == 1 136 | def _celestial_orb(self,c): 137 | 1 == 1 138 | def _quicksilver(self,c): 139 | 1 == 1 140 | def _rabadons_deathcap(self,c): 141 | 1 == 1 142 | def _ludens_echo(self,c): 143 | 1 == 1 144 | def _morellonomicon(self,c): 145 | 1 == 1 146 | def _demolitionists_charge(self,c): 147 | 1 == 1 148 | def _jeweled_gauntlet(self,c): 149 | 1 == 1 150 | def _seraphs_embrace(self,c): 151 | 1 == 1 152 | def _redemption(self,c): 153 | 1 == 1 154 | def _star_guardians_charm(self,c): 155 | 1 == 1 156 | def _hand_of_justice(self,c): 157 | 1 == 1 158 | def _warmogs_armor(self,c): 159 | 1 == 1 160 | def _protectors_chestguard(self,c): 161 | 1 == 1 162 | def _trap_claw(self,c): 163 | 1 == 1 164 | def _force_of_nature(self,c): 165 | 1 == 1 166 | def _dark_stars_heart(self,c): 167 | 1 == 1 168 | def _thiefs_gloves(self,c): 169 | 1 == 1 170 | -------------------------------------------------------------------------------- /app/env.py: -------------------------------------------------------------------------------- 1 | 2 | import config_3 as cfg 3 | import numpy as np 4 | from fight.fight import Fight 5 | from buff.items import Item 6 | import time 7 | # env 8 | ''' 9 | 1. mixed item 10 | 2. visualize more 11 | ''' 12 | 13 | class TFT_env: 14 | def __init__(self,elements,champ_state_info,champ_cost_info,champ_level_info, 15 | champ_distribution,sushi_distribution,synergy_info,agent1=None,agent2=None, 16 | agent3=None,agent4=None,agent5=None,agent6=None,agent7=None,agent8=None, 17 | **kwargs): 18 | ''' 19 | action space : 20 | act1 = player's act before fight 21 | act2 = player's act about arrange units 22 | act3 = about item 23 | state : 24 | units, arrange, xp, money, life 25 | ''' 26 | # base 27 | self.items = ['items'] 28 | self.act1_spc = ['pick1','pick2','pick3','pick4','pick5','save','sell','reroll','xp'] 29 | self.act2_spc = [i for i in range(28)] 30 | self.act3_spc = ['item'] 31 | self.champ_state_info = champ_state_info 32 | self.champ_cost_info = champ_cost_info 33 | self.champ_level_info = champ_level_info 34 | self.cur_round = '1-1' 35 | self.synergy_info = synergy_info 36 | self.items = [2,3,5,6,7,8,9,10,12] 37 | self.elements = elements 38 | self.limit = dict(c1=29,c2=22,c3=16,c4=12,c5=10) 39 | # player 40 | self.need_xp = [2,4,8,14,24,44,76,126,192] 41 | # about sushi,reroll 42 | self.sushi_distribution = sushi_distribution 43 | self.champ_distribution = champ_distribution 44 | # agent 45 | self.agent1 = agent1 46 | self.agent2 = agent2 47 | self.agent3 = agent3 48 | self.agent4 = agent4 49 | self.agent5 = agent5 50 | self.agent6 = agent6 51 | self.agent7 = agent7 52 | self.agent8 = agent8 53 | self.place = 8 54 | self.place_table = [['agent{}'.format(i+1),100] for i in range(8)] 55 | self.final_place = dict(agent1=1,agent2=1,agent3=1,agent4=1,agent5=1, 56 | agent6=1,agent7=1,agent8=1,) 57 | def init_game(self): 58 | self.players = [self.agent1,self.agent2,self.agent3,self.agent4,self.agent5, 59 | self.agent6,self.agent7,self.agent8] 60 | self.jd = dict(state=[],action=[]) 61 | for n,player in enumerate(self.players): 62 | player.name = 'agent{}'.format(n+1) 63 | player.champ_distribution = self.champ_distribution 64 | player.champ_state_info = self.champ_state_info 65 | player.champ_level_info = self.champ_level_info 66 | player.champ_cost_info = self.champ_cost_info 67 | player.synergy_info = self.synergy_info 68 | player.act1_spc = self.act1_spc 69 | player.act2_spc = self.act2_spc 70 | player.act3_spc = self.act3_spc 71 | player.cur_round = self.cur_round 72 | player.need_xp = self.need_xp 73 | player.init_player() 74 | self._sushi() 75 | def _round(self): 76 | big_round = int(self.cur_round[0]) 77 | sub_round = int(self.cur_round[-1]) 78 | if big_round == 1: 79 | if sub_round == 4: 80 | big_round += 1 81 | sub_round = 1 82 | else: 83 | sub_round += 1 84 | else: 85 | if sub_round == 7: 86 | big_round += 1 87 | sub_round = 1 88 | else: 89 | sub_round += 1 90 | self.cur_round = '{}-{}'.format(big_round,sub_round) 91 | 92 | def _sushi(self): 93 | self.sushi = [] 94 | tofill = 9 95 | while len(self.sushi) != 9: 96 | stars = np.bincount(np.random.choice(range(5),tofill, 97 | p=self.sushi_distribution['r'+str(self.cur_round[0])])) 98 | for star,n_champs in zip(stars,self.champ_cost_info.items()): 99 | if len(n_champs[1]) < star: 100 | star = len(n_champs) 101 | cnts = [self.champ_state_info[champ]['count'] for champ in n_champs[1]] 102 | if sum(cnts) == 0: 103 | continue 104 | prob = [c/sum(cnts) for c in cnts] 105 | print('sushi cnts',cnts) 106 | champs = list(np.random.choice(len(n_champs[1]),star,replace=False,p=prob)) 107 | self.sushi += [n_champs[1][c] for c in champs ] 108 | tofill -= star 109 | orders = np.arange(8) 110 | np.random.shuffle(orders) 111 | item = list(np.random.choice(self.items,8,replace=False)) 112 | for i,(order,player) in enumerate(zip(orders,self.players)): 113 | self.champ_state_info[self.sushi[order]]['count'] -= 1 114 | print('sushi!',self.champ_state_info[self.sushi[order]]['count']) 115 | player.champ_append(self.sushi[order]+'_1',[item[i]]) 116 | print('sushi finished {} champ is {}'.format(player.name,self.sushi[order])) 117 | def _prepare(self): 118 | total_champ_queues = [] 119 | for player in self.players: 120 | player.champ_state_info = self.champ_state_info 121 | print(player.name) 122 | player.cur_round = self.cur_round 123 | champ_queues,action_sequence,arrange,num = player.prepare_round() 124 | self.jd['action'].append(dict(buysell=np.array(action_sequence).tolist(), 125 | arrange=np.array(arrange).tolist(),chosen=np.array(num).tolist())) 126 | print(player.wait_num) 127 | self.jd['state'].append(dict(xp=player.xp,money=int(player.money), 128 | wait=player.wait_num,fight=player.fight_num,synergy=player.fight_synergy, 129 | life=player.life,continuous=player.continuous)) 130 | for champ,count in champ_queues: 131 | if champ == None: 132 | continue 133 | self.champ_state_info[champ]['count'] += count 134 | def _match(self): 135 | match_queue = np.arange(len(self.players)) 136 | np.random.shuffle(match_queue) 137 | match_queue = list(match_queue) 138 | is_ai = False 139 | if len(match_queue) % 2 == 1: 140 | ai = np.random.choice(match_queue[:-1],1)[0] 141 | match_queue.append(ai) 142 | is_ai = False 143 | match_queue = np.reshape(np.array(match_queue),(-1,2)) 144 | return match_queue,is_ai 145 | def _continuous(self,agent,win): 146 | if win: 147 | if agent.continuous >= 0: 148 | agent.continuous += 1 149 | else: 150 | agent.continuous = 1 151 | else: 152 | if agent.continuous <= 0: 153 | agent.continuous -= 1 154 | else: 155 | agent.continuous = -1 156 | def _game_over(self): 157 | for player in self.players: 158 | if player.life <= 0: 159 | self.players.remove(player) 160 | self.final_place[player.name] = self.place 161 | self.place -= 1 162 | units = player.total_units 163 | for unit,info in units.items(): 164 | self.champ_state_info[unit[:-2]]['count'] += \ 165 | info['count']*(int(unit[-1])-1) 166 | def play_round(self,gui=True): 167 | result = 'sushi' 168 | print(self.cur_round) 169 | if self.cur_round == '1-1': 170 | 1 == 1 171 | elif (self.cur_round[0] != '1') and (self.cur_round[-1] == '4'): 172 | self._sushi() 173 | else: 174 | self._prepare() 175 | match_order,is_ai = self._match() 176 | for i,m in enumerate(match_order): 177 | a1 = self.players[m[0]] 178 | a2 = self.players[m[1]] 179 | fight = Fight(a1,a2,self.cur_round) 180 | fight.my_queue = a1.five_champs 181 | fight.my_cost = a1.five_cost 182 | fight.my_money = a1.money 183 | fight.opp_money = a2.money 184 | fight.place_table = self.place_table 185 | if str(match_order[i]) == str(match_order[-1]): 186 | fight.is_ai = is_ai 187 | result,life_change = fight.fight(gui=gui) 188 | if gui: 189 | fight.gui.root.destroy() 190 | time.sleep(0.001) 191 | print('finish fight!') 192 | if result: 193 | a2.life -= life_change 194 | a1.money += 1 195 | self._continuous(a1,True) 196 | self._continuous(a2,False) 197 | a1.result(result) 198 | a2.result(False) 199 | self.place_table[int(a2.name[-1])-1] = [a2.name,a2.life] 200 | elif result == 0: 201 | a2.life -= life_change 202 | a1.life -= life_change 203 | self._continuous(a1,False) 204 | self._continuous(a2,False) 205 | self.place_table[int(a1.name[-1])-1] = [a1.name,a1.life] 206 | self.place_table[int(a2.name[-1])-1] = [a2.name,a2.life] 207 | else: 208 | a1.life -= life_change 209 | a2.money += 1 210 | self._continuous(a2,True) 211 | self._continuous(a1,False) 212 | a1.result(True) 213 | a2.result(result) 214 | self.place_table[int(a1.name[-1])-1] = [a1.name,a1.life] 215 | self._game_over() 216 | tem = [(k,i['count']) for k,i in self.champ_state_info.items()] 217 | #print(tem) 218 | names = [player.name for player in self.players] 219 | print('survived players : {}'.format(names)) 220 | self._round() 221 | -------------------------------------------------------------------------------- /app/buff/synergy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import config_3 as cfg 3 | 4 | class Synergy: 5 | def __init__(self,hexes,start_hexes,mysyn,tic,arrs,opparrs,ds_died=False, 6 | mech_died=[False,'init'],pirate_kill=0,star_skilled=0,valkyrie_target=[], 7 | demol_skilled=False,protector_skillcast=[],protector_maintain=[]): 8 | ''' 9 | hexes : chess board 10 | mysyn : synergies 11 | - index : synergy index 12 | - champ : champ (x,y) 13 | - effect : effect 14 | tic : time 15 | ds_died : dead dark star, judge when _die - done 16 | mech_died : [True,xy of mech] - 17 | pirate_kill : int 18 | star_skilled : int 19 | valkyrie_target : enemy - [x,y] 20 | demol_skilled : stunned 21 | protector_skillcast : shield make 22 | ''' 23 | self.syns = list(mysyn.items()) 24 | self.arrs = arrs 25 | self.opparrs = opparrs 26 | self.hexes = hexes 27 | self.start_hexes = start_hexes 28 | self.tic = tic 29 | self.ds_died = ds_died 30 | self.mech_died = mech_died 31 | self.pirate_kill = pirate_kill 32 | self.pirate_money,self.pirate_item = 0,[] 33 | self.star_skilled = star_skilled 34 | self.valkyrie_target = valkyrie_target 35 | self.demol_skilled = demol_skilled # later 36 | self.protector_skillcast = protector_skillcast 37 | self.is_pirate,self.is_sniper,self.is_void = False,False,False 38 | self.is_starguard,self.is_protector,self.is_valkyrie = False,False,False 39 | self.is_infil,self.is_demol,self.is_mana = False,False,False 40 | self.functions = [self._celestial,self._chrono,self._cybernatic,self._dark_star, 41 | self._mech_pilot,self._rebel,self._space_pirate,self._star_guardian, 42 | self._valkyrie,self._void,self._blademaster,self._blaster,self._brawler, 43 | self._demolitionist,self._infiltrator,self._mana_reaver,self._mercenary, 44 | self._mystic,self._protector,self._sniper,self._sorcerer,self._starship, 45 | self._vanguard] 46 | self.updated_hexes = None 47 | def apply(self): 48 | for k,i in self.syns: 49 | xy = np.where(self.hexes[:,:,14:15]==i['index']) 50 | champs = [[x,y] for x,y in zip(xy[0],xy[1])] 51 | self.functions[i['index']](champs,i['effect']) 52 | def _celestial(self,champs,effect): 53 | if self.tic == 0: 54 | #print('_celestial') 55 | for arr in self.arrs: 56 | self.hexes[arr[0],arr[1],11] = effect 57 | def _chrono(self,champs,effect): 58 | if self.tic > 15: 59 | #print('_chrono') 60 | pass 61 | elif self.tic % 4 == 3: 62 | #print('_chrono') 63 | for arr in self.arrs: 64 | if arr == None: 65 | continue 66 | self.hexes[arr[0],arr[1],6] += effect 67 | 68 | def _cybernatic(self,champs,effect): 69 | if self.tic == 0: 70 | #print('_cybernatic') 71 | for champ in champs: 72 | if self.hexes[champ[0],champ[1],16] != 0: 73 | self.hexes[champ[0],champ[1],2] += effect[0] 74 | self.hexes[champ[0],champ[1],5] += effect[1] 75 | def _dark_star(self,champs,effect): 76 | if self.ds_died: 77 | #print('_dark_star') 78 | for champ in champs: 79 | self.hexes[champ[0],champ[1],10] += self.ds_died*effect 80 | self.hexes[champ[0],champ[1],5] += self.ds_died*effect 81 | def _mech_pilot(self,champs,effect): 82 | if self.mech_died[0]: 83 | #print('_mech_pilot') 84 | xy = self.mech_died[1] 85 | n = 0 86 | tofill = [self.mech1,self.mech2,self.mech3] 87 | while n != 3: 88 | xlist = list(range(self.mech_died[1][0]-2,self.mech_died[1][0]+2)) 89 | ylist = list(range(self.mech_died[1][1]-2,self.mech_died[1][1]+2)) 90 | x = np.random.choice(xlist,1)[0] 91 | y = np.random.choice(ylist,1)[0] 92 | if self.hexes[x,y,0] == 0: 93 | self.hexes[x,y,:] = tofill[n] 94 | n += 1 95 | elif self.mech_died[1] == 'init': 96 | #print('_mech_pilot') 97 | selected = np.random.choice(len(champs),3,replace=False) 98 | xy = np.random.choice(selected,1)[0] 99 | selected = [champs[sel] for sel in selected] 100 | items = [] 101 | it = 0 102 | self.mech1 = self.hexes[selected[0][0],selected[0][1],:] 103 | self.mech2 = self.hexes[selected[1][0],selected[1][1],:] 104 | self.mech3 = self.hexes[selected[2][0],selected[2][1],:] 105 | for sel in selected: 106 | if str(sel) == str(champs[xy]): 107 | continue 108 | else: 109 | self.hexes[champs[xy][0],champs[xy][1],1] = 100 110 | self.hexes[champs[xy][0],champs[xy][1],2:14] += self.hexes[sel[0],sel[1],2:14] 111 | for i in range(3): 112 | item = self.hexes[sel[0],sel[1],17+2*i:19+2*i] 113 | self.hexes[champs[xy][0],champs[xy][1],17] += self.hexes[sel[0],sel[1],17] 114 | if sum(item) == 0: 115 | continue 116 | is_chosen = np.random.choice([0,1],1) 117 | if it > 3: 118 | continue 119 | if is_chosen != 0: 120 | self.hexes[champs[xy][0],champs[xy][1],17+2*it:19+2*it] = item 121 | it += 1 122 | self.hexes[champs[xy][0],champs[xy][1],17] = \ 123 | int(self.hexes[champs[xy][0],champs[xy][1],17]/3) 124 | def _rebel(self,champs,effect): 125 | if self.tic == 0: 126 | #print('_rebel') 127 | for champ in champs: 128 | copies = np.tile(champ,(len(champs),1)) 129 | diff = abs(copies-champs) 130 | adj = len(diff[diff<=1]) 131 | self.hexes[champ[0],champ[1],25] += effect[0]*adj 132 | self.hexes[champ[0],champ[1],5] += effect[1]*adj 133 | def _space_pirate(self,champs,effect): 134 | #print('_space_pirate') 135 | self.is_pirate = True 136 | items = [1,2,4,5,6,7,8,10,12,13] 137 | for kill in range(self.pirate_kill): 138 | self.pirate_money += np.random.choice([0,1],1)[0] 139 | give = np.random.choice([0,1],1,p=[1-effect[0],effect[0]])[0] 140 | if give == 1: 141 | self.pirate_item += np.random.choice(items,1)[0] 142 | def _star_guardian(self,champs,effect): 143 | #print('_star_guardian') 144 | self.is_starguard = True 145 | for champ in champs: 146 | self.hexes[champ[0],champ[1],3] += self.star_skilled * effect 147 | def _valkyrie(self,champs,effect): 148 | ''' 149 | apply at fight.py 150 | ''' 151 | #print('_valkyrie') 152 | def _void(self,champs,effect): 153 | ''' 154 | apply at fight.py 155 | ''' 156 | #print('_void') 157 | self.is_void = True 158 | 1 == 1 159 | def _blademaster(self,champs,effect): 160 | #print('_blademaster') 161 | for champ in champs: 162 | hit = np.random.choice([1,2],1,p=[1-effect,effect])[0] 163 | self.hexes[champ[0],champ[1],5] = hit * self.hexes[champ[0],champ[1],5] 164 | def _blaster(self,champs,effect): 165 | if self.tic % 4 == 1: 166 | #print('_blaster') 167 | for champ in champs: 168 | if len(self.opparr) <= effect: 169 | effect = len(self.opparr) 170 | additonals = np.random.choice(self.opparr,effect,replace=False) 171 | for add in additonals: 172 | damage = self.hexes[champ[0],champ[1],5] - self.hexes[add[0],add[1],7] 173 | if damage < 0: 174 | damage = 0 175 | self.hexes[add[0],add[1],2] -= damage/2*self.hexes[champ[0],champ[1],6] 176 | def _brawler(self,champs,effect): 177 | #print('_brawler') 178 | if self.tic == 0: 179 | for champ in champs: 180 | self.hexes[champ[0],champ[1],2] += effect 181 | def _demolitionist(self,champs,effect): 182 | self.is_demol = True 183 | def _infiltrator(self,champs,effect): 184 | #print('_infiltrator') 185 | self.is_infil = True 186 | if self.tic == 0: 187 | ''' 188 | move later 189 | ''' 190 | for champ in champs: 191 | self.hexes[champ[0],champ[1],6] += effect 192 | def _mana_reaver(self,champs,effect): 193 | self.is_mana = True 194 | def _mercenary(self,champs,effect): 195 | ''' 196 | later 197 | ''' 198 | #print('_mercenary') 199 | 1 == 1 200 | def _mystic(self,champs,effect): 201 | if self.tic == 0: 202 | #print('_mystic') 203 | for champ in champs: 204 | self.hexes[champ[0],champ[1],8] += effect 205 | def _protector(self,champs,effect): 206 | #print('_protector') 207 | self.is_protector = True 208 | for prot in self.protector_skillcast: 209 | self.hexes[prot[0],prot[1],25] += self.start_hexes[prot[0],prot[1],25]*effect 210 | '''disappear shield later''' 211 | def _sniper(self,champs,effect): 212 | self.is_sniper = True 213 | def _sorcerer(self,champs,effect): 214 | if self.tic == 0: 215 | #print('_sorcerer') 216 | for champ in champs: 217 | self.hexes[champ[0],champ[1],10] += effect 218 | def _starship(self,champs,effect): 219 | '''move later''' 220 | #print('_starship') 221 | 222 | for champ in champs: 223 | self.hexes[champ[0],champ[1],3] += 20 224 | def _vanguard(self,champs,effect): 225 | if self.tic == 0: 226 | #print('_vanguard') 227 | for champ in champs: 228 | self.hexes[champ[0],champ[1],7] += effect 229 | -------------------------------------------------------------------------------- /app/utils/view.py: -------------------------------------------------------------------------------- 1 | import tkinter as tk 2 | from PIL import ImageTk as itk 3 | from PIL import Image 4 | import tkinter.font as TkFont 5 | 6 | class GUI: 7 | #pallete 8 | black = '#000000' 9 | red = '#ff0000' 10 | blue = '#0000ff' 11 | white = '#ffffff' 12 | cost1 = '#d9ded7' 13 | cost2 = '#3ed119' 14 | cost3 = '#0974b3' 15 | cost4 = '#4d0391' 16 | cost5 = '#ffcb3b' 17 | queue = '#35353d' 18 | queue_border = '#5e4604' 19 | wait = '#918f89' 20 | gold = '#e0d44f' 21 | nogold = '#3b3b3b' 22 | battlefield = '#69bf47' 23 | health = '#37d456' 24 | mana = '#1424db' 25 | def __init__(self,x,y,cost=None,name=None,is_exist=None,infos=None, 26 | my_money=0,opp_money=0,title=None,place_table=None): 27 | # canvas 28 | self.x = x 29 | self.y = y 30 | self.w = 11*x 31 | self.h = 10*x+y 32 | # queue 33 | self.q_w = 10*x 34 | self.q_h = y 35 | # waitfield 36 | self.w_w = 9*x 37 | self.w_h = x 38 | # gold 39 | self.g = 0.7*x 40 | #battlefield 41 | self.b_w = 8*x 42 | self.b_h = 8*x 43 | self.root = tk.Tk() 44 | self.root.title('TFT GYM') 45 | self.root.geometry('{}x{}+{}+{}'.format(self.w,self.h,0,0)) 46 | self.root.resizable(False,False) 47 | self.arr = [] 48 | self.game = tk.Canvas(self.root,width=self.w,height=self.h,bd=0) 49 | # wait 50 | self.game.create_rectangle(self.x+1,self.h-self.q_h,self.x+self.w_w, 51 | self.h-self.q_h-self.w_h,fill=GUI.wait,outline=GUI.black) 52 | self.game.create_rectangle(self.x,0,self.x+self.w_w,self.w_h,fill=GUI.wait, 53 | outline=GUI.black) 54 | # item 55 | self.game.create_rectangle(0,self.h-self.q_h,self.x,self.h-self.q_h-1.5*self.x, 56 | fill=GUI.wait,outline=GUI.black) 57 | self.game.create_rectangle(self.w,0,self.w-self.x,1.5*self.x,fill=GUI.wait, 58 | outline=GUI.black) 59 | # queue 60 | self.game.create_rectangle(0,self.h,self.q_w,self.h-self.q_h,fill=GUI.queue, 61 | outline=GUI.queue_border,width=2) 62 | self._make_queue(self.game,is_exist,cost,name=name) 63 | # _gold 64 | self._gold(self.game,my_money,opp_money) 65 | # field 66 | self.game.create_rectangle(self.x*1.5,self.x,self.x*1.5+self.b_w, 67 | self.x+self.b_h,fill=GUI.battlefield,outline=GUI.black,width=1) 68 | # gamename 69 | self.game.create_text(self.w/2,10,text=title,fill='black') 70 | # make chessboard 71 | self._make_board(self.game,self.x*1.75) 72 | # arrange champs 73 | self.init_make_champs(self.game,infos) 74 | # make place_table 75 | self.place = dict() 76 | self._make_place(self.game,place_table) 77 | self.game.pack() 78 | def _make_place(self,game,place_table): 79 | self.placexy = [] 80 | place_table = sorted(place_table,key=lambda place : place[1]) 81 | game.p1 = None 82 | game.p2 = None 83 | game.p3 = None 84 | game.p4 = None 85 | game.p5 = None 86 | game.p6 = None 87 | game.p7 = None 88 | game.p8 = None 89 | self.imgs = [game.p1,game.p2,game.p3,game.p4,game.p5, 90 | game.p6,game.p7,game.p8] 91 | for n,(player,life) in enumerate(place_table): 92 | img = tk.PhotoImage(file='./utils/icon/player/{}.gif'.format(player)) 93 | self.imgs[n] = img 94 | image_info = self.game.create_image(self.w-30,self.h-38*(n)-30, 95 | image=self.imgs[n]) 96 | text_info1 = game.create_text(self.w-30,self.h-38*(n)-10,text=str(life), 97 | fill='black') 98 | text_info2 = game.create_text(self.w-53,self.h-38*(n)-30, 99 | text=player[0]+player[-1],fill='blue') 100 | self.place[player] = [image_info,n,text_info1,text_info2] 101 | self.placexy.append([self.w-30,self.h-38*(n)-30,self.w-30,self.h-38*(n)-10, 102 | self.w-55,self.h-38*(n)-30]) 103 | def _gold(self,game,data1,data2): 104 | dist = 0.2*self.g 105 | clr1,clr2 = GUI.gold,GUI.gold 106 | money1 = data1 // 10 107 | money2 = data2 // 10 108 | for i in range(5): 109 | if i+1 > money1: 110 | clr1 = GUI.nogold 111 | if i+1 > money2: 112 | clr2 = GUI.nogold 113 | st = (self.g+dist)*(i+1) 114 | en = self.g+(self.g+dist)*(i+1) 115 | game.create_oval(2,self.h-self.q_h-self.w_h-st,self.g+2, 116 | self.h-self.q_h-self.w_h-en,fill=clr1,outline=GUI.white) 117 | game.create_oval(self.w-2,self.w_h+st,self.w-2-self.g, 118 | self.w_h+en,fill=clr2,outline=GUI.white) 119 | def _make_board(self,game,st): 120 | self.center = dict() 121 | for i in range(8): 122 | h = self.w_h+self.x*i 123 | if i % 2 == 0: 124 | st1 = st 125 | else: 126 | st1 = st+self.x*0.5 127 | for j in range(7): 128 | game.create_rectangle(st1+self.x*j,h,st1+self.x*(j+1),h+self.x, 129 | fill=GUI.battlefield,outline=GUI.black,width=2) 130 | x,y = (st1+self.x*j+st1+self.x*(j+1))/2,h+self.x/2 131 | self.center['[{}, {}]'.format(j,i)] = [y,x] 132 | def _make_queue(self,game,data,cost,name): 133 | w = self.x * 2 134 | h = self.y 135 | i_w = 50 136 | i_h = 50 137 | clrs = [GUI.cost1,GUI.cost2,GUI.cost3,GUI.cost4,GUI.cost5] 138 | imgs = [] 139 | for n in name: 140 | if n == None: 141 | img = None 142 | else: 143 | img = tk.PhotoImage(file='./utils/icon/{}.gif'.format(n)) 144 | imgs.append(img) 145 | game.ph1 = imgs[0] 146 | game.ph2 = imgs[1] 147 | game.ph3 = imgs[2] 148 | game.ph4 = imgs[3] 149 | game.ph5 = imgs[4] 150 | imgs = [game.ph1,game.ph2,game.ph3,game.ph4,game.ph5] 151 | self.photos = self._ready_champs(game) 152 | for i in range(5): 153 | if data[i]==False: 154 | continue 155 | game.create_rectangle(w*i,self.h,w*(i+1),self.h-h,fill=clrs[cost[i]-1]) 156 | game.create_text(w*i+w/3,self.h-h/4,text=name[i],fill='black') 157 | game.create_oval(w*i,self.h-3*h/4,w*i+10,self.h-3*h/4-10,fill=GUI.gold) 158 | game.create_text(w*i+15,self.h-3*h/4-10,text=str(cost[i]),fill='black') 159 | game.create_image(w*(i+1)-i_w/2,self.h-h+i_h/2,image=imgs[i]) 160 | def init_make_champs(self,game,infos): 161 | helv36 = TkFont.Font(family='Helvetica',size=10, weight='bold') 162 | for n,(k,info) in enumerate(infos.items()): 163 | k = str(list(k)) 164 | xy = self.center[k] 165 | name = info[0] 166 | myopp = info[1] 167 | if myopp == 1: 168 | clr = GUI.blue 169 | else: 170 | clr = GUI.red 171 | img = tk.PhotoImage(file='./utils/icon/{}.gif'.format(name)) 172 | border = game.create_rectangle(xy[1]-25,xy[0]-25,xy[1]+25,xy[0]+25, 173 | outline=clr,width=2) 174 | 175 | self.photos[n] = img 176 | image_info = game.create_image(xy[1],xy[0],image=self.photos[n]) 177 | mana = game.create_text(xy[1]+12,xy[0]+20,text=info[4],fill=GUI.mana, 178 | font=helv36) 179 | health = game.create_text(xy[1]+12,xy[0]+10,text=info[3],fill=GUI.health, 180 | font=helv36) 181 | self.arr.append([info[2],k,info[0],self.photos[n],image_info, 182 | border,health,mana]) 183 | def update_champs(self,game,infos): 184 | hexes = [i[1] for i in self.arr] 185 | who = [i[0] for i in self.arr] 186 | check1 = [i[4] for i in self.arr] 187 | check2 = [i[5] for i in self.arr] 188 | check3 = [i[6] for i in self.arr] 189 | check4 = [i[7] for i in self.arr] 190 | for k,info in infos.items(): 191 | k = str(list(k)) 192 | ind = who.index(info[2]) 193 | check1.remove(self.arr[ind][4]) 194 | check2.remove(self.arr[ind][5]) 195 | check3.remove(self.arr[ind][6]) 196 | check4.remove(self.arr[ind][7]) 197 | health = self.arr[ind][6] 198 | mana = self.arr[ind][7] 199 | game.itemconfig(health,text=info[3]) 200 | game.itemconfig(mana,text=info[4]) 201 | if hexes[ind] != k: 202 | xy = self.center[k] 203 | kk =eval(k) 204 | hex = eval(hexes[ind]) 205 | change = self.center[k] 206 | orig = self.center[hexes[ind]] 207 | dx,dy = change[1]-orig[1],change[0]-orig[0] 208 | #dx,dy = kk[0]-hex[0],kk[1]-hex[1] 209 | game.move(self.arr[ind][4],dx,dy) 210 | game.move(self.arr[ind][5],dx,dy) 211 | game.move(health,dx,dy) 212 | game.move(mana,dx,dy) 213 | self.arr[ind][1] = k 214 | self.arr[ind][6] = health 215 | self.arr[ind][7] = mana 216 | for c1,c2,c3,c4 in zip(check1,check2,check3,check4): 217 | game.delete(c1) 218 | game.delete(c2) 219 | game.delete(c3) 220 | game.delete(c4) 221 | def _ready_champs(self,game): 222 | game.ch1 = None 223 | game.ch2 = None 224 | game.ch3 = None 225 | game.ch4 = None 226 | game.ch5 = None 227 | game.ch6 = None 228 | game.ch7 = None 229 | game.ch8 = None 230 | game.ch9 = None 231 | game.ch10 = None 232 | game.ch11 = None 233 | game.ch12 = None 234 | game.ch13 = None 235 | game.ch14 = None 236 | game.ch15 = None 237 | game.ch16 = None 238 | game.ch17 = None 239 | game.ch18 = None 240 | game.ch19 = None 241 | game.ch20 = None 242 | game.ch21 = None 243 | game.ch22 = None 244 | game.ch23 = None 245 | game.ch24 = None 246 | game.ch25 = None 247 | photos = [game.ch1,game.ch2,game.ch3,game.ch4,game.ch5,game.ch6,game.ch7, 248 | game.ch8,game.ch9,game.ch10,game.ch11,game.ch12,game.ch13,game.ch14, 249 | game.ch15,game.ch16,game.ch17,game.ch18,game.ch19,game.ch20,game.ch21, 250 | game.ch22,game.ch23,game.ch24,game.ch25] 251 | return photos 252 | if __name__ == '__main__': 253 | GUI(60,70) 254 | -------------------------------------------------------------------------------- /app/one_player.py: -------------------------------------------------------------------------------- 1 | 2 | import config_3 as cfg 3 | import numpy as np 4 | from fight.fight import Fight 5 | from buff.items import Item 6 | from env import TFT_env 7 | from agent.random_agent import * 8 | from agent.rulebased_agent import * 9 | class Player: 10 | def __init__(self,agent,name=None): 11 | ''' 12 | action space : 13 | act1 = player's act before fight 14 | act2 = player's act about arrange units 15 | act3 = about item 16 | state : 17 | units, arrange, xp, money, life 18 | ''' 19 | 20 | # units 21 | self.total_units = dict() 22 | self.removal = dict(c1=[],c2=[],c3=[],c4=[],c5=[]) # already level 3 unit 23 | self.fight_group = [] 24 | self.fight_units = [] # fore rearrange 25 | self.fight_synergy = [] 26 | self.fight_items = [] 27 | self.wait_num = [] 28 | self.agent = agent 29 | self.unit_number = 0 30 | def init_player(self): 31 | # init game 32 | self.money = 0 # 돈 33 | self.place = 8 # 등수 --> 최종 reward 34 | self.life = 100 # 체력 35 | self.xp = 0 # xp 36 | self.continuous = 0 # state reward 37 | self.player_level = 1 38 | self.five_champs = [True]*5 39 | self.five_cost = [0]*5 40 | self.player_synergy = dict() 41 | def _count_units(self): 42 | self.unit_number = 0 43 | for k,i in self.total_units.items(): 44 | self.unit_number += i['count'] 45 | def _champ_queue(self): 46 | self.five_champs,self.five_cost = [],[] 47 | tofill = 5 48 | while True: 49 | #print('tofill',tofill) 50 | stars = np.bincount(np.random.choice(5,size=tofill, 51 | p=self.champ_distribution['l'+str(self.player_level)])) 52 | for rem,star,n_champs in zip(self.removal.items(),stars,self.champ_cost_info.items()): 53 | n_champs = n_champs[1] 54 | for r in rem[1]: 55 | if r in n_champs: 56 | n_champs.remove(r) 57 | cnts = [self.champ_state_info[champ]['count'] for champ in n_champs] 58 | candidates = list(range(len(n_champs))) 59 | if sum(cnts) == 0: 60 | continue 61 | prob = [c/sum(cnts) for c in cnts] 62 | #print('n_champs : {}, removal {}, star {}'.format(n_champs,self.removal,star)) 63 | champs = np.random.choice(candidates,size=star,p=prob) 64 | self.five_champs += [n_champs[c] for c in champs] 65 | for c in self.five_champs: 66 | if self.champ_state_info[c]['count'] < self.five_champs.count(c): 67 | erase = self.five_champs.count(c) - self.champ_state_info[c]['count'] 68 | for e in range(erase): 69 | self.five_champs.remove(c) 70 | tofill = 5 - len(self.five_champs) 71 | if tofill == 0: 72 | break 73 | self.five_cost += [self._cost(c+'_1') for c in self.five_champs] 74 | def _cost(self,champ): 75 | cost_info = np.array([1,3,5]) 76 | level = int(champ[-1]) 77 | champ = champ[:-2] 78 | for (star,champs) in self.champ_cost_info.items(): 79 | if champ in champs: 80 | return cost_info[level-1] 81 | cost_info += 1 82 | def _money(self): 83 | ''' 84 | money rule 85 | 1. '1-2','1-3' : 2 86 | 2. '1-4','2-1 : 3 87 | 3. '2-2' : 4 88 | 4. interset : 10골드 당 1원 max 5 89 | 5. continuous : 2 - +1 3 - +2 4 ~ - +3 90 | ''' 91 | if self.cur_round in ['1-2','1-3','1-4','2-1','2-2']: 92 | self.money += 2 93 | if (self.cur_round[0] == '2') or (self.cur_round[-1] == '4'): 94 | self.money += 1 95 | if self.cur_round[-1] == '2': 96 | self.money += 1 97 | else: 98 | self.money += 5 99 | if self.money > 50: 100 | self.money += 5 101 | else: 102 | self.money += self.money // 10 103 | if abs(self.continuous) >= 4: 104 | self.money += 3 105 | elif abs(self.continuous) >= 3: 106 | self.money += 2 107 | elif abs(self.continuous) >= 2: 108 | self.money += 1 109 | def _update_synergy(self): 110 | ''' 111 | for fight units 112 | ''' 113 | syn_list = [] 114 | used = [] 115 | self.player_synergy = dict() 116 | for syns,unit in zip(self.fight_synergy,self.fight_units): 117 | if unit[:-4] not in used: 118 | syn_list += syns 119 | used.append(unit[:-4]) 120 | syn = np.bincount(syn_list) 121 | for n,((k,i),s) in enumerate(zip(self.synergy_info.items(),syn)): 122 | rate = 0 123 | while s >= i['rate'][rate]: 124 | rate += 1 125 | if rate >= len(i['rate']): 126 | break 127 | if rate >= 1: 128 | champs = [] 129 | for m,info in enumerate(self.fight_infos): 130 | if n in info['synergy'] : 131 | champs.append(m) 132 | self.player_synergy[k] = dict(champ=champs, 133 | effect=i['effect'][rate-1],index=n) 134 | def champ_append(self,champ,item=None): 135 | self.unit_number += 1 136 | if champ in self.total_units.keys(): 137 | self.total_units[champ]['count'] += 1 138 | if item: 139 | self.total_units[champ]['item'] += item 140 | self.total_units[champ]['owner'].append(1) 141 | if self.total_units[champ]['count'] == 3: 142 | self.unit_number -= 2 143 | levup = int(champ[-1]) + 1 144 | levup_champ = champ[:-1] + str(levup) 145 | self.champ_append(levup_champ,self.total_units[champ]['item']) 146 | del self.total_units[champ] 147 | else: 148 | num = self.champ_state_info[champ[:-2]]['num'] 149 | synergy = self.champ_state_info[champ[:-2]]['elem'] 150 | infos = self.champ_level_info[champ[:-2]].items() 151 | info = dict() 152 | level = champ[-1] 153 | for k,i in infos: 154 | if (k == 'health') or (k=='attack_damage') or (k=='dps'): 155 | info[k] = i*1.8**(int(level)-1) 156 | else: 157 | info[k] = i 158 | if item: 159 | self.total_units[champ] = dict(count=1,synergy=synergy,info=info, 160 | item=item,owner=[0],num=num) 161 | else: 162 | self.total_units[champ] = dict(count=1,synergy=synergy,info=info, 163 | item=[],owner=[],num=num) 164 | 165 | if level == '3': 166 | for c in self.champ_cost_info.items(): 167 | if champ[:-2] in c[1]: 168 | if c[0] in self.removal.keys(): 169 | self.removal[c[0]].append(champ[:-2]) 170 | else: 171 | self.removal[c[1]] = [champ[:-2]] 172 | def _player_levelup(self): 173 | if self.player_level == 9: 174 | pass 175 | else: 176 | while self.xp >= self.need_xp[self.player_level-1]: 177 | self.player_level += 1 178 | self.champ_prob = self.champ_distribution['l'+str(self.player_level)] 179 | def _before_fight(self,act1): 180 | champ_queue = [None,None] 181 | if act1 <= 4: 182 | cost = self._cost(self.five_champs[act1]+'_1') 183 | self.money -= cost 184 | self.champ_append(self.five_champs[act1]+'_1',None) 185 | champ_queue = [self.five_champs[act1],-1] 186 | print('buy!',champ_queue) 187 | self.five_champs[act1] = False 188 | self.is_prepared = False 189 | elif act1 == 5: 190 | self.is_prepared = True 191 | elif act1 == 6: 192 | ind = np.random.choice(len(self.total_units.keys())) 193 | champ = list(self.total_units.keys())[ind] 194 | self.money += self._cost(champ) 195 | self.unit_number -= 1 196 | self.total_units[champ]['count'] -= 1 197 | champ_queue = [champ[:-2],3**(int(champ[-1])-1)] 198 | print('sell!',[champ[:-2],3**(int(champ[-1])-1)]) 199 | if self.total_units[champ]['count'] == 0: 200 | if self.total_units[champ]['item']: 201 | self.wait_items += self.total_units[champ]['item'] 202 | del self.total_units[champ] 203 | self.is_prepared = False 204 | elif act1 == 7: 205 | self.money -= 2 206 | self._champ_queue() 207 | self.is_prepared = False 208 | elif act1 == 8: 209 | self.xp += 4 210 | self._player_levelup() 211 | self.money -= 4 212 | self.is_prepared = False 213 | self._update_synergy() 214 | return champ_queue 215 | def _rearrange(self,action=None): 216 | # random pick & random arrange 217 | units,syns = [],[] 218 | self.fight_num,self.fight_infos = [],[] 219 | self.fight_items,self.fight_units = [],[] 220 | self.wait_num = [] 221 | for k,i in self.total_units.items(): 222 | for n in range(i['count']): 223 | info = i['info'] 224 | info['synergy'] = i['synergy'] 225 | units += [k+'_'+str(n)] 226 | syns += [i['synergy']] 227 | self.fight_num += [i['num']] 228 | self.fight_infos += [info] 229 | if len(units) <= self.player_level: 230 | self.fight_units = units 231 | avail_units = len(units) 232 | else: 233 | avail_units = self.player_level 234 | if action==RandomAgent.rearr_action: 235 | chosen = np.random.choice(len(units),self.player_level,replace=False) 236 | else: 237 | chosen = action(avail_units,syns) 238 | for i,n in enumerate(self.fight_num): 239 | if i in chosen: 240 | continue 241 | self.wait_num.append(self.fight_num[i]) 242 | self.fight_units = [units[c] for c in chosen] 243 | self.fight_synergy = [syns[c] for c in chosen] 244 | self.fight_infos = [self.fight_infos[c] for c in chosen] 245 | self.fight_num = [self.fight_num[c] for c in chosen] 246 | for unit in self.fight_units: 247 | items = self.total_units[unit[:-2]]['item'] 248 | owners = self.total_units[unit[:-2]]['owner'] 249 | unit_item = [] 250 | for owner,item in zip(owners,items): 251 | if owner == int(unit[-1]): 252 | unit_item += [item] 253 | self.fight_items.append(unit_item) 254 | yy = np.arange(4) 255 | xx = np.arange(7) 256 | hex_x = np.random.choice(xx,avail_units) 257 | hex_y = np.random.choice(yy,avail_units) 258 | self.fight_arrange = list(set([(x,y) for x,y in zip(hex_x,hex_y)])) 259 | tofill = avail_units - len(self.fight_arrange) 260 | while tofill != 0: 261 | hex_x = np.random.choice(xx,1)[0] 262 | hex_y = np.random.choice(yy,1)[0] 263 | if tuple([hex_x,hex_y]) not in list(self.fight_arrange): 264 | self.fight_arrange.append((hex_x,hex_y)) 265 | tofill -= 1 266 | def _assign_item(self): 267 | items = Item(self.fight_items,self.fight_infos) 268 | def prepare_round(self): 269 | self._money() 270 | self._champ_queue() 271 | self.xp += 2 272 | self._player_levelup() 273 | self.is_prepared = False 274 | champ_queues = [] 275 | action_sequence = [] 276 | while self.is_prepared != True: 277 | act = self.agent.bef_action(self.money,self.player_level,self.five_champs, 278 | self.five_cost,self.total_units,self.unit_number) 279 | action_sequence.append(act) 280 | #print(act) 281 | #print(self.act1_spc[act]) 282 | champ_queue = self._before_fight(act) 283 | champ_queues.append(champ_queue) 284 | if act == 5: 285 | self.is_prepared = True 286 | self._rearrange(action=self.agent.rearr_action) 287 | self._assign_item() 288 | self._update_synergy() 289 | self._count_units() 290 | return champ_queues,action_sequence,self.fight_arrange,self.fight_num 291 | def result(self,result): 292 | msg = ('-----------------------\n'+\ 293 | '{}\n'+\ 294 | 'ROUND {} finish\n'+\ 295 | 'Win : {}\n'+\ 296 | 'Life : {}\n'+\ 297 | 'Player level : {}\n'+\ 298 | 'Money : {}\n'+\ 299 | 'Champs : {}\n'+\ 300 | 'Continuous : {}\n'+\ 301 | 'Synergy : {}\n'+\ 302 | 'Items : {}\n'+\ 303 | '-----------------------').format(self.name,self.cur_round,result,self.life,self.player_level, 304 | self.money,self.fight_units,self.continuous,self.player_synergy,self.fight_items) 305 | #print(msg) 306 | -------------------------------------------------------------------------------- /app/config_3.py: -------------------------------------------------------------------------------- 1 | # for TFT set 3 10.7 2 | elements = ['Celestial','Chrono','Cybernetic','Dark_Star','Mech_Pilot','Rebel',#5 3 | 'Space_Pirate','Star_Guardian','Valkyrie','Void','Blademaster','Blaster',#11 4 | 'Brawler','Demolitionist','Infiltrator','Mana_Reaver','Mercenary','Mystic',#17 5 | 'Protector','Sniper','Sorcerer','Starship','Vanguard']#22 6 | champ_state_info = dict( 7 | zoe=dict(name='Zoe',cost=1,elem=[7,20],num=1,count=29), 8 | ziggs=dict(name='Ziggs',cost=1,elem=[5,13],num=2,count=29), 9 | xayah=dict(name='Xayah',cost=1,elem=[0,10],num=3,count=29), 10 | twistedfate=dict(name='Twistedfate',cost=1,elem=[1,20],num=4,count=29), 11 | poppy=dict(name='Poppy',cost=1,elem=[7,22],num=5,count=29), 12 | malphite=dict(name='Malphite',cost=1,elem=[5,12],num=6,count=29), 13 | leona=dict(name='Leona',cost=1,elem=[2,22],num=7,count=29), 14 | khazix=dict(name='Khazix',cost=1,elem=[9,14],num=8,count=29), 15 | jarvan_iv=dict(name='Jarvan IV',cost=1,elem=[3,18],num=9,count=29), 16 | graves=dict(name='Graves',cost=1,elem=[6,11],num=10,count=29), 17 | fiora=dict(name='Fiora',cost=1,elem=[2,10],num=11,count=29), 18 | caitlyn=dict(name='Caitlyn',cost=1,elem=[1,19],num=12,count=29), 19 | yasuo=dict(name='Yasuo',cost=2,elem=[5,10],num=13,count=22), 20 | xin_zhao=dict(name='Xin_zhao',cost=1,elem=[0,18],num=14,count=22), 21 | sona=dict(name='Sona',cost=2,elem=[5,17],num=15,count=22), 22 | shen=dict(name='Shen',cost=2,elem=[1,9],num=16,count=22), 23 | rakan=dict(name='Rakan',cost=2,elem=[0,18],num=17,count=22), 24 | mordekaiser=dict(name='Mordekaiser',cost=2,elem=[3,22],num=18,count=22), 25 | lucian=dict(name='Lucian',cost=2,elem=[2,11],num=19,count=22), 26 | kaisa=dict(name='Kaisa',cost=2,elem=[9,14],num=20,count=22), 27 | darius=dict(name='Darius',cost=2,elem=[6,15],num=21,count=22), 28 | blitzcrank=dict(name='Blitzcrank',cost=2,elem=[1,12],num=22,count=22), 29 | annie=dict(name='Annie',cost=2,elem=[4,20],num=23,count=22), 30 | ahri=dict(name='Ahri',cost=2,elem=[7,20],num=24,count=22), 31 | vi=dict(name='Vi',cost=3,elem=[2,12],num=25,count=16), 32 | syndra=dict(name='Syndra',cost=3,elem=[7,20],num=26,count=16), 33 | shaco=dict(name='Shaco',cost=3,elem=[3,14],num=27,count=16), 34 | rumble=dict(name='Rumble',cost=3,elem=[4,13],num=28,count=16), 35 | neeko=dict(name='Neeko',cost=3,elem=[7,18],num=29,count=16), 36 | master_yi=dict(name='Master_yi',cost=3,elem=[5,10],num=30,count=16), 37 | lux=dict(name='Lux',cost=3,elem=[3,20],num=31,count=16), 38 | kassadin=dict(name='Kassadin',cost=3,elem=[0,15],num=32,count=16), 39 | karma=dict(name='Karma',cost=3,elem=[3,17],num=33,count=16), 40 | jayce=dict(name='Jayce',cost=3,elem=[6,22],num=34,count=16), 41 | ezreal=dict(name='Ezreal',cost=3,elem=[1,11],num=35,count=16), 42 | ashe=dict(name='Ashe',cost=3,elem=[1,19],num=36,count=16), 43 | wukong=dict(name='Wukong',cost=4,elem=[1,22],num=37,count=12), 44 | velkoz=dict(name='Velkoz',cost=4,elem=[9,20],num=38,count=12), 45 | soraka=dict(name='Soraka',cost=4,elem=[7,17],num=39,count=12), 46 | kayle=dict(name='Kayle',cost=4,elem=[8,10],num=40,count=12), 47 | jinx=dict(name='Jinx',cost=4,elem=[5,11],num=41,count=12), 48 | jhin=dict(name='Jhin',cost=4,elem=[3,19],num=42,count=12), 49 | irelia=dict(name='Irelia',cost=4,elem=[2,10,15],num=43,count=12), 50 | fizz=dict(name='Fizz',cost=4,elem=[4,14],num=44,count=12), 51 | chogath=dict(name='Chogath',cost=4,elem=[9,12],num=45,count=12), 52 | thresh=dict(name='Thresh',cost=5,elem=[1,15],num=46,count=10), 53 | miss_fortune=dict(name='Miss_Fortune',cost=5,elem=[8,11,16],num=47,count=10), 54 | lulu=dict(name='Lulu',cost=5,elem=[0,17],num=48,count=10), 55 | gangplank=dict(name='Gangplank',cost=5,elem=[6,13,16],num=49,count=10), 56 | ekko=dict(name='Ekko',cost=5,elem=[2,14],num=50,count=10), 57 | aurelion_sol=dict(name='Aurelion_Sol',cost=5,elem=[5,21],num=51,count=10), 58 | ) 59 | champ_cost_info = dict( 60 | c1=['zoe','ziggs','xayah','twistedfate','poppy','malphite', 61 | 'leona','khazix','jarvan_iv','graves','fiora','caitlyn'], 62 | c2=['yasuo','xin_zhao','sona','shen','rakan','mordekaiser','lucian', 63 | 'kaisa','darius','blitzcrank','annie','ahri'], 64 | c3=['vi','syndra','shaco','rumble','neeko','master_yi','lux', 65 | 'kassadin','karma','jayce','ezreal','ashe'], 66 | c4=['wukong','velkoz','soraka','kayle','jinx','jhin','irelia', 67 | 'fizz','chogath'], 68 | c5=['thresh','miss_fortune','lulu','gangplank','ekko','aurelion_sol']) # for distribution 69 | champ_level_info = dict( 70 | zoe=dict(health=500,attack_damage=40,dps=28,attack_range=3,dodge=0.15,skill=0, 71 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[90,120],critical=0.15), 72 | ziggs=dict(health=500,attack_damage=40,dps=28,attack_range=3,dodge=0.15,skill=0, 73 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[0,40],critical=0.15), 74 | xayah=dict(health=500,attack_damage=55,dps=41,attack_range=3,dodge=0.15,skill=0, 75 | attack_speed=0.75,armor=20,magical_resistance=20,mana=[0,50],critical=0.15), 76 | twistedfate=dict(health=500,attack_damage=40,dps=28,attack_range=3,dodge=0.15,skill=0, 77 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[0,75],critical=0.15), 78 | poppy=dict(health=650,attack_damage=50,dps=28,attack_range=1,dodge=0.15,skill=0, 79 | attack_speed=0.55,armor=40,magical_resistance=20,mana=[60,100],critical=0.15), 80 | malphite=dict(health=700,attack_damage=70,dps=35,attack_range=1,dodge=0.15,skill=0, 81 | attack_speed=0.5,armor=30,magical_resistance=20,mana=[0,0],critical=0.15), 82 | leona=dict(health=600,attack_damage=50,dps=28,attack_range=1,dodge=0.15,skill=0, 83 | attack_speed=0.55,armor=40,magical_resistance=20,mana=[50,100],critical=0.15), 84 | khazix=dict(health=500,attack_damage=50,dps=30,attack_range=1,dodge=0.15,skill=0, 85 | attack_speed=0.7,armor=25,magical_resistance=20,mana=[0,65],critical=0.15), 86 | jarvan_iv=dict(health=650,attack_damage=50,dps=30,attack_range=1,dodge=0.15,skill=0, 87 | attack_speed=0.6,armor=40,magical_resistance=20,mana=[50,100],critical=0.15), 88 | graves=dict(health=650,attack_damage=55,dps=30,attack_range=1,dodge=0.15,skill=0, 89 | attack_speed=0.55,armor=35,magical_resistance=20,mana=[50,80],critical=0.15), 90 | fiora=dict(health=450,attack_damage=45,dps=45,attack_range=1,dodge=0.15,skill=0, 91 | attack_speed=1,armor=30,magical_resistance=20,mana=[0,85],critical=0.15), 92 | caitlyn=dict(health=500,attack_damage=45,dps=34,attack_range=5,dodge=0.15,skill=0, 93 | attack_speed=0.75,armor=20,magical_resistance=20,mana=[0,125],critical=0.15), 94 | yasuo=dict(health=600,attack_damage=50,dps=38,attack_range=1,dodge=0.15,skill=0, 95 | attack_speed=0.75,armor=30,magical_resistance=20,mana=[0,100],critical=0.15), 96 | xin_zhao=dict(health=650,attack_damage=60,dps=42,attack_range=1,dodge=0.15,skill=0, 97 | attack_speed=0.7,armor=35,magical_resistance=20,mana=[0,50],critical=0.15), 98 | sona=dict(health=550,attack_damage=40,dps=26,attack_range=3,dodge=0.15,skill=0, 99 | attack_speed=0.65,armor=20,magical_resistance=20,mana=[0,40],critical=0.15), 100 | shen=dict(health=700,attack_damage=60,dps=42,attack_range=1,dodge=0.15,skill=0, 101 | attack_speed=0.7,armor=35,magical_resistance=20,mana=[100,150],critical=0.15), 102 | rakan=dict(health=600,attack_damage=45,dps=32,attack_range=2,dodge=0.15,skill=0, 103 | attack_speed=0.7,armor=35,magical_resistance=20,mana=[50,150],critical=0.15), 104 | mordekaiser=dict(health=650,attack_damage=55,dps=33,attack_range=1,dodge=0.15,skill=0, 105 | attack_speed=0.6,armor=40,magical_resistance=20,mana=[0,90],critical=0.15), 106 | lucian=dict(health=500,attack_damage=55,dps=39,attack_range=4,dodge=0.15,skill=0, 107 | attack_speed=0.7,armor=25,magical_resistance=20,mana=[0,35],critical=0.15), 108 | kaisa=dict(health=550,attack_damage=50,dps=38,attack_range=2,dodge=0.15,skill=0, 109 | attack_speed=0.75,armor=20,magical_resistance=20,mana=[0,60],critical=0.15), 110 | darius=dict(health=650,attack_damage=60,dps=39,attack_range=1,dodge=0.15,skill=0, 111 | attack_speed=0.65,armor=35,magical_resistance=20,mana=[0,70],critical=0.15), 112 | blitzcrank=dict(health=650,attack_damage=55,dps=28,attack_range=1,dodge=0.15,skill=0, 113 | attack_speed=0.5,armor=35,magical_resistance=20,mana=[125,125],critical=0.15), 114 | annie=dict(health=600,attack_damage=40,dps=26,attack_range=2,dodge=0.15,skill=0, 115 | attack_speed=0.65,armor=35,magical_resistance=20,mana=[75,150],critical=0.15), 116 | ahri=dict(health=600,attack_damage=45,dps=34,attack_range=3,dodge=0.15,skill=0, 117 | attack_speed=0.75,armor=20,magical_resistance=20,mana=[0,60],critical=0.15), 118 | vi=dict(health=750,attack_damage=60,dps=39,attack_range=1,dodge=0.15,skill=0, 119 | attack_speed=0.65,armor=35,magical_resistance=20,mana=[70,140],critical=0.15), 120 | syndra=dict(health=600,attack_damage=45,dps=32,attack_range=3,dodge=0.15,skill=0, 121 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[0,50],critical=0.15), 122 | shaco=dict(health=650,attack_damage=55,dps=44,attack_range=1,dodge=0.15,skill=0, 123 | attack_speed=0.8,armor=25,magical_resistance=20,mana=[0,60],critical=0.15), 124 | rumble=dict(health=800,attack_damage=50,dps=35,attack_range=1,dodge=0.15,skill=0, 125 | attack_speed=0.7,armor=35,magical_resistance=20,mana=[0,60],critical=0.15), 126 | neeko=dict(health=800,attack_damage=50,dps=33,attack_range=2,dodge=0.15,skill=0, 127 | attack_speed=0.65,armor=30,magical_resistance=20,mana=[75,150],critical=0.15), 128 | master_yi=dict(health=750,attack_damage=55,dps=44,attack_range=1,dodge=0.15,skill=0, 129 | attack_speed=0.8,armor=30,magical_resistance=20,mana=[0,55],critical=0.15), 130 | lux=dict(health=600,attack_damage=40,dps=28,attack_range=4,dodge=0.15,skill=0, 131 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[50,100],critical=0.15), 132 | kassadin=dict(health=800,attack_damage=50,dps=33,attack_range=1,dodge=0.15,skill=0, 133 | attack_speed=0.65,armor=30,magical_resistance=20,mana=[40,100],critical=0.15), 134 | karma=dict(health=600,attack_damage=50,dps=33,attack_range=3,dodge=0.15,skill=0, 135 | attack_speed=0.65,armor=20,magical_resistance=20,mana=[75,100],critical=0.15), 136 | jayce=dict(health=750,attack_damage=60,dps=42,attack_range=1,dodge=0.15,skill=0, 137 | attack_speed=0.7,armor=40,magical_resistance=20,mana=[0,80],critical=0.15), 138 | ezreal=dict(health=600,attack_damage=60,dps=42,attack_range=3,dodge=0.15,skill=0, 139 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[60,120],critical=0.15), 140 | ashe=dict(health=600,attack_damage=60,dps=48,attack_range=5,dodge=0.15,skill=0, 141 | attack_speed=0.8,armor=20,magical_resistance=20,mana=[50,125],critical=0.15), 142 | wukong=dict(health=850,attack_damage=50,dps=38,attack_range=1,dodge=0.15,skill=0, 143 | attack_speed=0.75,armor=40,magical_resistance=20,mana=[50,150],critical=0.15), 144 | velkoz=dict(health=650,attack_damage=45,dps=34,attack_range=4,dodge=0.15,skill=0, 145 | attack_speed=0.75,armor=20,magical_resistance=20,mana=[0,80],critical=0.15), 146 | soraka=dict(health=650,attack_damage=45,dps=34,attack_range=3,dodge=0.15,skill=0, 147 | attack_speed=0.75,armor=30,magical_resistance=20,mana=[50,150],critical=0.15), 148 | kayle=dict(health=700,attack_damage=60,dps=48,attack_range=3,dodge=0.15,skill=0, 149 | attack_speed=0.8,armor=25,magical_resistance=20,mana=[0,60],critical=0.15), 150 | jinx=dict(health=600,attack_damage=70,dps=49,attack_range=3,dodge=0.15,skill=0, 151 | attack_speed=0.7,armor=20,magical_resistance=20,mana=[0,0],critical=0.15), 152 | jhin=dict(health=600,attack_damage=90,dps=81,attack_range=5,dodge=0.15,skill=0, 153 | attack_speed=0.9,armor=20,magical_resistance=20,mana=[0,0],critical=0.15), 154 | irelia=dict(health=800,attack_damage=70,dps=60,attack_range=1,dodge=0.15,skill=0, 155 | attack_speed=0.85,armor=35,magical_resistance=20,mana=[0,30],critical=0.15), 156 | fizz=dict(health=650,attack_damage=60,dps=42,attack_range=1,dodge=0.15,skill=0, 157 | attack_speed=0.75,armor=25,magical_resistance=20,mana=[80,150],critical=0.15), 158 | chogath=dict(health=1000,attack_damage=70,dps=42,attack_range=1,dodge=0.15,skill=0, 159 | attack_speed=0.6,armor=20,magical_resistance=20,mana=[50,150],critical=0.15), 160 | thresh=dict(health=950,attack_damage=50,dps=48,attack_range=2,dodge=0.15,skill=0, 161 | attack_speed=0.95,armor=35,magical_resistance=20,mana=[50,85],critical=0.15), 162 | miss_fortune=dict(health=800,attack_damage=60,dps=66,attack_range=4,dodge=0.15,skill=0, 163 | attack_speed=1.1,armor=20,magical_resistance=20,mana=[50,150],critical=0.15), 164 | lulu=dict(health=800,attack_damage=45,dps=38,attack_range=3,dodge=0.15,skill=0, 165 | attack_speed=0.85,armor=25,magical_resistance=20,mana=[75,150],critical=0.15), 166 | gangplank=dict(health=1000,attack_damage=60,dps=60,attack_range=1,dodge=0.15,skill=0, 167 | attack_speed=1,armor=30,magical_resistance=20,mana=[50,150],critical=0.15), 168 | ekko=dict(health=850,attack_damage=60,dps=54,attack_range=1,dodge=0.15,skill=0, 169 | attack_speed=0.9,armor=30,magical_resistance=20,mana=[50,150],critical=0.15), 170 | aurelion_sol=dict(health=900,attack_damage=10,dps=8,attack_range=1,dodge=0.15,skill=0, 171 | attack_speed=0.8,armor=30,magical_resistance=20,mana=[30,80],critical=0.15), 172 | ) 173 | champ_distribution = dict( 174 | l1=[1,0,0,0,0], 175 | l2=[1,0,0,0,0],#4 176 | l3=[0.70,0.3,0.0,0.0,0.0],#6 177 | l4=[0.50,0.35,0.15,0.0,0.0],#10 178 | l5=[0.35,0.4,0.2,0.05,0.0],#20 179 | l6=[0.2,0.35,0.35,0.1,0.0],#32 180 | l7=[0.14,0.3,0.4,0.15,0.01],#50 181 | l8=[0.15,0.2,0.35,0.24,0.06],#66 182 | l9=[0.1,0.15,0.3,0.3,0.15] 183 | ) 184 | sushi_distribution = dict( 185 | r1=[1,0,0,0,0], 186 | r2=[0.12,0.44,0.44,0,0], 187 | r3=[0.12,0.2,0.38,0.3,0], 188 | r4=[0.05,0.15,0.3,0.4,0.1], 189 | r5=[0.05,0.15,0.3,0.4,0.1], 190 | r6=[0.05,0.15,0.3,0.4,0.1], 191 | r7=[0.05,0.15,0.3,0.4,0.1] 192 | ) 193 | 194 | synergy_info = dict( 195 | Celestial=dict(rate=[2,4,6],effect=[0.15,0.3,0.6], 196 | description='heal of damage percent'), 197 | Chrono=dict(rate=[2,4,6],effect=[0.15,0.35,0.65], 198 | description='attack speed'), 199 | Cybernetic=dict(rate=[3,6],effect=[[350,50],[800,80]], 200 | description='health,damage when item occupied'), 201 | Dark_Star=dict(rate=[3,6],effect=[25,35], 202 | description='damage percent, hexes'), 203 | Mech_Pilot=dict(rate=[3],effect=[1], 204 | description='mech robot'), 205 | Rebel=dict(rate=[3,6],effect=[[150,0.1],[225,0.12]], 206 | description='shield,damaage per adjacent units'), 207 | Space_Pirate=dict(rate=[2,4],effect=[[0],[0.15]], 208 | description='percent of 1 gold & random item'), 209 | Star_Guardian=dict(rate=[3,6],effect=[30,60], 210 | description='mana restore when other champ use skill'), 211 | Valkyrie=dict(rate=[2],effect=[0.5], 212 | description='critical when health below percent'), 213 | Void=dict(rate=[3],effect=[1.0], 214 | description='true damage'), 215 | Blademaster=dict(rate=[3,6],effect=[0.3,0.55], 216 | description='chance to attack other two champs'), 217 | Blaster=dict(rate=[2,4],effect=[3,6], 218 | description='additional attack for every fourth attack'), 219 | Brawler=dict(rate=[2,4],effect=[300,750], 220 | description='additional health'), 221 | Demolitionist=dict(rate=[3],effect=[1.5], 222 | description='stun for seconds when skill'), 223 | Infiltrator=dict(rate=[2,4],effect=[0.5,0.8], 224 | description='bonus attack speed, when initialize when takedown'), 225 | Mana_Reaver=dict(rate=[2],effect=[0.4], 226 | description='all attacks mana usage increase'), 227 | Mercenary=dict(rate=[1],effect=[5], 228 | description='add skill'), 229 | Mystic=dict(rate=[2,4],effect=[30,120], 230 | description='skill resistance'), 231 | Protector=dict(rate=[2,4],effect=[0.2,0.4], 232 | description='4 secs for max health shields when skill cast'), 233 | Sniper=dict(rate=[2],effect=[0.12], 234 | description='damage increase per hex'), 235 | Sorcerer=dict(rate=[2,4,6],effect=[0.2,0.4,0.8], 236 | description='skill damage increase'), 237 | Starship=dict(rate=[1],effect=[20], 238 | description='20 mana per sec & move around'), 239 | Vanguard=dict(rate=[2,4],effect=[60,250], 240 | description='add armor'), 241 | ) 242 | -------------------------------------------------------------------------------- /app/result.json: -------------------------------------------------------------------------------- 1 | { 2 | "agent1": [ 3 | 1, 4 | 2, 5 | 8, 6 | 1, 7 | 7, 8 | 6, 9 | 1, 10 | 1, 11 | 1, 12 | 5, 13 | 7, 14 | 5, 15 | 1, 16 | 8, 17 | 7, 18 | 6, 19 | 6, 20 | 4, 21 | 6, 22 | 4, 23 | 6, 24 | 1, 25 | 1, 26 | 1, 27 | 8, 28 | 3, 29 | 8, 30 | 3, 31 | 6, 32 | 8, 33 | 1, 34 | 2, 35 | 2, 36 | 6, 37 | 2, 38 | 4, 39 | 1, 40 | 5, 41 | 8, 42 | 8, 43 | 3, 44 | 2, 45 | 1, 46 | 8, 47 | 7, 48 | 7, 49 | 4, 50 | 7, 51 | 5, 52 | 5, 53 | 1, 54 | 1, 55 | 2, 56 | 7, 57 | 1, 58 | 6, 59 | 4, 60 | 3, 61 | 8, 62 | 5, 63 | 3, 64 | 6, 65 | 2, 66 | 1, 67 | 5, 68 | 5, 69 | 6, 70 | 1, 71 | 7, 72 | 6, 73 | 6, 74 | 2, 75 | 2, 76 | 8, 77 | 1, 78 | 5, 79 | 2, 80 | 8, 81 | 4, 82 | 1, 83 | 5, 84 | 3, 85 | 1, 86 | 3, 87 | 5, 88 | 3, 89 | 1, 90 | 8, 91 | 8, 92 | 7, 93 | 1, 94 | 8, 95 | 3, 96 | 1, 97 | 1, 98 | 7, 99 | 1, 100 | 1, 101 | 2, 102 | 4, 103 | 1, 104 | 1, 105 | 3, 106 | 3, 107 | 1, 108 | 2, 109 | 6, 110 | 5, 111 | 1, 112 | 6, 113 | 5, 114 | 2, 115 | 6, 116 | 8, 117 | 4, 118 | 1, 119 | 4, 120 | 3, 121 | 8, 122 | 1, 123 | 3, 124 | 5, 125 | 1, 126 | 5, 127 | 5, 128 | 4, 129 | 1, 130 | 8, 131 | 7, 132 | 2, 133 | 2, 134 | 8, 135 | 1, 136 | 1, 137 | 5, 138 | 1, 139 | 3, 140 | 8, 141 | 4, 142 | 5, 143 | 8, 144 | 5, 145 | 5, 146 | 8, 147 | 7, 148 | 5, 149 | 1, 150 | 1, 151 | 1, 152 | 1, 153 | 6, 154 | 5, 155 | 3, 156 | 5, 157 | 7, 158 | 1, 159 | 5, 160 | 6, 161 | 1, 162 | 3, 163 | 1, 164 | 1, 165 | 1, 166 | 4, 167 | 3, 168 | 6, 169 | 3, 170 | 5, 171 | 6, 172 | 2, 173 | 5, 174 | 5, 175 | 3, 176 | 6, 177 | 3, 178 | 7, 179 | 1, 180 | 2, 181 | 1, 182 | 1, 183 | 7, 184 | 5, 185 | 8, 186 | 7, 187 | 6, 188 | 1, 189 | 1, 190 | 2, 191 | 4, 192 | 7, 193 | 4, 194 | 2, 195 | 4, 196 | 8, 197 | 1, 198 | 3, 199 | 3, 200 | 4, 201 | 4, 202 | 1, 203 | 4, 204 | 5, 205 | 6, 206 | 1, 207 | 1, 208 | 5, 209 | 7, 210 | 2, 211 | 1, 212 | 7, 213 | 1, 214 | 8, 215 | 6, 216 | 1, 217 | 2, 218 | 5, 219 | 7, 220 | 8, 221 | 1, 222 | 1, 223 | 1, 224 | 2, 225 | 6, 226 | 8, 227 | 5, 228 | 7, 229 | 1, 230 | 1, 231 | 4, 232 | 8, 233 | 1, 234 | 8, 235 | 1, 236 | 7, 237 | 5, 238 | 1, 239 | 1, 240 | 8, 241 | 1, 242 | 2 243 | ], 244 | "agent2": [ 245 | 8, 246 | 5, 247 | 7, 248 | 5, 249 | 8, 250 | 5, 251 | 3, 252 | 6, 253 | 2, 254 | 8, 255 | 5, 256 | 8, 257 | 5, 258 | 4, 259 | 2, 260 | 4, 261 | 8, 262 | 1, 263 | 8, 264 | 5, 265 | 5, 266 | 6, 267 | 8, 268 | 7, 269 | 5, 270 | 1, 271 | 6, 272 | 1, 273 | 5, 274 | 5, 275 | 6, 276 | 8, 277 | 5, 278 | 8, 279 | 6, 280 | 1, 281 | 8, 282 | 7, 283 | 7, 284 | 6, 285 | 7, 286 | 5, 287 | 7, 288 | 6, 289 | 4, 290 | 1, 291 | 7, 292 | 5, 293 | 8, 294 | 3, 295 | 8, 296 | 8, 297 | 8, 298 | 5, 299 | 8, 300 | 3, 301 | 6, 302 | 5, 303 | 5, 304 | 3, 305 | 8, 306 | 8, 307 | 8, 308 | 4, 309 | 3, 310 | 3, 311 | 4, 312 | 6, 313 | 6, 314 | 7, 315 | 1, 316 | 7, 317 | 6, 318 | 6, 319 | 5, 320 | 3, 321 | 1, 322 | 7, 323 | 6, 324 | 8, 325 | 8, 326 | 5, 327 | 8, 328 | 2, 329 | 2, 330 | 8, 331 | 5, 332 | 3, 333 | 7, 334 | 8, 335 | 8, 336 | 6, 337 | 7, 338 | 4, 339 | 5, 340 | 2, 341 | 8, 342 | 4, 343 | 8, 344 | 8, 345 | 5, 346 | 5, 347 | 6, 348 | 2, 349 | 7, 350 | 7, 351 | 4, 352 | 7, 353 | 6, 354 | 3, 355 | 2, 356 | 4, 357 | 1, 358 | 5, 359 | 6, 360 | 8, 361 | 8, 362 | 5, 363 | 6, 364 | 3, 365 | 6, 366 | 2, 367 | 4, 368 | 6, 369 | 1, 370 | 1, 371 | 5, 372 | 7, 373 | 8, 374 | 3, 375 | 5, 376 | 6, 377 | 8, 378 | 5, 379 | 7, 380 | 7, 381 | 7, 382 | 5, 383 | 6, 384 | 7, 385 | 6, 386 | 2, 387 | 8, 388 | 6, 389 | 5, 390 | 3, 391 | 6, 392 | 7, 393 | 7, 394 | 8, 395 | 8, 396 | 2, 397 | 5, 398 | 3, 399 | 8, 400 | 2, 401 | 1, 402 | 3, 403 | 8, 404 | 6, 405 | 5, 406 | 6, 407 | 3, 408 | 8, 409 | 7, 410 | 4, 411 | 8, 412 | 2, 413 | 3, 414 | 7, 415 | 6, 416 | 7, 417 | 2, 418 | 4, 419 | 1, 420 | 5, 421 | 6, 422 | 4, 423 | 8, 424 | 8, 425 | 1, 426 | 8, 427 | 3, 428 | 4, 429 | 8, 430 | 8, 431 | 7, 432 | 7, 433 | 8, 434 | 4, 435 | 6, 436 | 1, 437 | 8, 438 | 1, 439 | 7, 440 | 2, 441 | 8, 442 | 7, 443 | 7, 444 | 4, 445 | 2, 446 | 8, 447 | 4, 448 | 8, 449 | 8, 450 | 2, 451 | 5, 452 | 8, 453 | 7, 454 | 4, 455 | 3, 456 | 4, 457 | 3, 458 | 6, 459 | 4, 460 | 3, 461 | 5, 462 | 6, 463 | 3, 464 | 7, 465 | 5, 466 | 8, 467 | 7, 468 | 7, 469 | 6, 470 | 3, 471 | 5, 472 | 7, 473 | 5, 474 | 1, 475 | 6, 476 | 7, 477 | 3, 478 | 2, 479 | 8, 480 | 5, 481 | 8, 482 | 4, 483 | 8, 484 | 8 485 | ], 486 | "agent3": [ 487 | 6, 488 | 8, 489 | 1, 490 | 3, 491 | 3, 492 | 3, 493 | 7, 494 | 5, 495 | 7, 496 | 3, 497 | 8, 498 | 7, 499 | 8, 500 | 7, 501 | 6, 502 | 1, 503 | 5, 504 | 7, 505 | 4, 506 | 8, 507 | 8, 508 | 7, 509 | 7, 510 | 2, 511 | 3, 512 | 7, 513 | 5, 514 | 5, 515 | 3, 516 | 3, 517 | 8, 518 | 1, 519 | 7, 520 | 3, 521 | 7, 522 | 3, 523 | 5, 524 | 8, 525 | 2, 526 | 7, 527 | 5, 528 | 3, 529 | 6, 530 | 7, 531 | 6, 532 | 3, 533 | 8, 534 | 3, 535 | 1, 536 | 4, 537 | 7, 538 | 4, 539 | 6, 540 | 2, 541 | 6, 542 | 8, 543 | 8, 544 | 7, 545 | 2, 546 | 2, 547 | 6, 548 | 4, 549 | 4, 550 | 7, 551 | 8, 552 | 4, 553 | 5, 554 | 8, 555 | 3, 556 | 2, 557 | 5, 558 | 5, 559 | 4, 560 | 4, 561 | 3, 562 | 8, 563 | 7, 564 | 6, 565 | 7, 566 | 7, 567 | 7, 568 | 1, 569 | 3, 570 | 6, 571 | 6, 572 | 7, 573 | 8, 574 | 2, 575 | 1, 576 | 4, 577 | 4, 578 | 3, 579 | 6, 580 | 7, 581 | 3, 582 | 6, 583 | 7, 584 | 8, 585 | 5, 586 | 2, 587 | 3, 588 | 3, 589 | 7, 590 | 7, 591 | 8, 592 | 8, 593 | 7, 594 | 3, 595 | 4, 596 | 2, 597 | 4, 598 | 1, 599 | 5, 600 | 4, 601 | 2, 602 | 2, 603 | 7, 604 | 7, 605 | 3, 606 | 8, 607 | 5, 608 | 8, 609 | 2, 610 | 8, 611 | 2, 612 | 2, 613 | 7, 614 | 4, 615 | 2, 616 | 6, 617 | 8, 618 | 4, 619 | 2, 620 | 7, 621 | 8, 622 | 3, 623 | 2, 624 | 7, 625 | 8, 626 | 3, 627 | 4, 628 | 8, 629 | 1, 630 | 7, 631 | 3, 632 | 1, 633 | 7, 634 | 8, 635 | 4, 636 | 6, 637 | 4, 638 | 7, 639 | 7, 640 | 8, 641 | 2, 642 | 5, 643 | 4, 644 | 8, 645 | 6, 646 | 7, 647 | 3, 648 | 8, 649 | 5, 650 | 2, 651 | 5, 652 | 2, 653 | 5, 654 | 1, 655 | 5, 656 | 6, 657 | 1, 658 | 6, 659 | 1, 660 | 5, 661 | 8, 662 | 8, 663 | 8, 664 | 7, 665 | 5, 666 | 7, 667 | 8, 668 | 3, 669 | 6, 670 | 6, 671 | 7, 672 | 5, 673 | 6, 674 | 4, 675 | 7, 676 | 3, 677 | 2, 678 | 6, 679 | 7, 680 | 3, 681 | 2, 682 | 6, 683 | 5, 684 | 5, 685 | 2, 686 | 8, 687 | 8, 688 | 3, 689 | 2, 690 | 3, 691 | 5, 692 | 4, 693 | 2, 694 | 5, 695 | 5, 696 | 6, 697 | 7, 698 | 6, 699 | 8, 700 | 4, 701 | 5, 702 | 8, 703 | 8, 704 | 3, 705 | 4, 706 | 8, 707 | 6, 708 | 5, 709 | 8, 710 | 1, 711 | 3, 712 | 2, 713 | 2, 714 | 6, 715 | 8, 716 | 3, 717 | 7, 718 | 4, 719 | 5, 720 | 6, 721 | 3, 722 | 7, 723 | 5, 724 | 2, 725 | 6, 726 | 7 727 | ], 728 | "agent4": [ 729 | 4, 730 | 6, 731 | 2, 732 | 7, 733 | 6, 734 | 8, 735 | 5, 736 | 3, 737 | 5, 738 | 1, 739 | 2, 740 | 3, 741 | 3, 742 | 2, 743 | 5, 744 | 2, 745 | 3, 746 | 6, 747 | 1, 748 | 2, 749 | 4, 750 | 3, 751 | 3, 752 | 6, 753 | 6, 754 | 5, 755 | 2, 756 | 6, 757 | 4, 758 | 7, 759 | 3, 760 | 5, 761 | 8, 762 | 1, 763 | 3, 764 | 8, 765 | 7, 766 | 3, 767 | 4, 768 | 1, 769 | 4, 770 | 8, 771 | 4, 772 | 5, 773 | 3, 774 | 6, 775 | 6, 776 | 1, 777 | 4, 778 | 1, 779 | 2, 780 | 6, 781 | 3, 782 | 8, 783 | 4, 784 | 5, 785 | 2, 786 | 1, 787 | 4, 788 | 7, 789 | 7, 790 | 5, 791 | 7, 792 | 5, 793 | 2, 794 | 1, 795 | 2, 796 | 7, 797 | 5, 798 | 8, 799 | 3, 800 | 3, 801 | 8, 802 | 7, 803 | 8, 804 | 4, 805 | 8, 806 | 5, 807 | 2, 808 | 4, 809 | 3, 810 | 7, 811 | 5, 812 | 7, 813 | 8, 814 | 6, 815 | 3, 816 | 1, 817 | 6, 818 | 6, 819 | 2, 820 | 2, 821 | 8, 822 | 2, 823 | 6, 824 | 5, 825 | 6, 826 | 7, 827 | 6, 828 | 6, 829 | 7, 830 | 7, 831 | 2, 832 | 4, 833 | 6, 834 | 3, 835 | 5, 836 | 4, 837 | 2, 838 | 1, 839 | 1, 840 | 8, 841 | 3, 842 | 7, 843 | 3, 844 | 5, 845 | 1, 846 | 1, 847 | 2, 848 | 4, 849 | 4, 850 | 7, 851 | 6, 852 | 3, 853 | 4, 854 | 8, 855 | 4, 856 | 6, 857 | 6, 858 | 8, 859 | 7, 860 | 7, 861 | 6, 862 | 2, 863 | 2, 864 | 4, 865 | 6, 866 | 3, 867 | 2, 868 | 6, 869 | 7, 870 | 4, 871 | 4, 872 | 4, 873 | 1, 874 | 7, 875 | 4, 876 | 4, 877 | 6, 878 | 4, 879 | 1, 880 | 1, 881 | 1, 882 | 1, 883 | 3, 884 | 7, 885 | 2, 886 | 1, 887 | 4, 888 | 4, 889 | 2, 890 | 3, 891 | 2, 892 | 1, 893 | 1, 894 | 3, 895 | 7, 896 | 6, 897 | 1, 898 | 4, 899 | 8, 900 | 3, 901 | 8, 902 | 8, 903 | 7, 904 | 3, 905 | 4, 906 | 6, 907 | 3, 908 | 6, 909 | 6, 910 | 7, 911 | 2, 912 | 3, 913 | 4, 914 | 4, 915 | 5, 916 | 1, 917 | 6, 918 | 6, 919 | 1, 920 | 8, 921 | 1, 922 | 2, 923 | 5, 924 | 8, 925 | 7, 926 | 6, 927 | 8, 928 | 2, 929 | 1, 930 | 6, 931 | 7, 932 | 4, 933 | 7, 934 | 8, 935 | 8, 936 | 7, 937 | 6, 938 | 1, 939 | 4, 940 | 2, 941 | 5, 942 | 5, 943 | 1, 944 | 6, 945 | 2, 946 | 7, 947 | 6, 948 | 4, 949 | 2, 950 | 1, 951 | 5, 952 | 3, 953 | 7, 954 | 6, 955 | 4, 956 | 4, 957 | 2, 958 | 7, 959 | 8, 960 | 2, 961 | 7, 962 | 5, 963 | 7, 964 | 6, 965 | 3, 966 | 5, 967 | 4, 968 | 6 969 | ], 970 | "agent5": [ 971 | 5, 972 | 3, 973 | 4, 974 | 2, 975 | 4, 976 | 2, 977 | 8, 978 | 8, 979 | 4, 980 | 4, 981 | 4, 982 | 2, 983 | 7, 984 | 1, 985 | 4, 986 | 8, 987 | 7, 988 | 8, 989 | 3, 990 | 3, 991 | 7, 992 | 8, 993 | 6, 994 | 3, 995 | 1, 996 | 2, 997 | 7, 998 | 7, 999 | 8, 1000 | 2, 1001 | 5, 1002 | 6, 1003 | 3, 1004 | 7, 1005 | 1, 1006 | 6, 1007 | 4, 1008 | 2, 1009 | 1, 1010 | 4, 1011 | 2, 1012 | 1, 1013 | 8, 1014 | 3, 1015 | 2, 1016 | 4, 1017 | 3, 1018 | 6, 1019 | 2, 1020 | 8, 1021 | 6, 1022 | 3, 1023 | 1, 1024 | 4, 1025 | 7, 1026 | 2, 1027 | 5, 1028 | 4, 1029 | 1, 1030 | 4, 1031 | 1, 1032 | 7, 1033 | 1, 1034 | 6, 1035 | 4, 1036 | 8, 1037 | 1, 1038 | 4, 1039 | 1, 1040 | 3, 1041 | 7, 1042 | 6, 1043 | 1, 1044 | 1, 1045 | 7, 1046 | 7, 1047 | 5, 1048 | 1, 1049 | 5, 1050 | 6, 1051 | 1, 1052 | 4, 1053 | 2, 1054 | 5, 1055 | 4, 1056 | 2, 1057 | 7, 1058 | 5, 1059 | 4, 1060 | 5, 1061 | 5, 1062 | 5, 1063 | 4, 1064 | 6, 1065 | 8, 1066 | 8, 1067 | 4, 1068 | 2, 1069 | 3, 1070 | 7, 1071 | 4, 1072 | 2, 1073 | 1, 1074 | 6, 1075 | 4, 1076 | 6, 1077 | 3, 1078 | 1, 1079 | 7, 1080 | 4, 1081 | 6, 1082 | 6, 1083 | 2, 1084 | 3, 1085 | 8, 1086 | 7, 1087 | 6, 1088 | 8, 1089 | 5, 1090 | 2, 1091 | 8, 1092 | 4, 1093 | 8, 1094 | 4, 1095 | 3, 1096 | 6, 1097 | 8, 1098 | 2, 1099 | 3, 1100 | 5, 1101 | 4, 1102 | 1, 1103 | 4, 1104 | 8, 1105 | 4, 1106 | 6, 1107 | 8, 1108 | 1, 1109 | 1, 1110 | 1, 1111 | 2, 1112 | 6, 1113 | 7, 1114 | 2, 1115 | 4, 1116 | 8, 1117 | 5, 1118 | 6, 1119 | 3, 1120 | 5, 1121 | 7, 1122 | 4, 1123 | 8, 1124 | 7, 1125 | 1, 1126 | 6, 1127 | 8, 1128 | 2, 1129 | 5, 1130 | 1, 1131 | 7, 1132 | 5, 1133 | 7, 1134 | 5, 1135 | 8, 1136 | 1, 1137 | 1, 1138 | 8, 1139 | 7, 1140 | 5, 1141 | 4, 1142 | 2, 1143 | 5, 1144 | 2, 1145 | 5, 1146 | 1, 1147 | 3, 1148 | 3, 1149 | 7, 1150 | 5, 1151 | 5, 1152 | 4, 1153 | 5, 1154 | 1, 1155 | 2, 1156 | 7, 1157 | 3, 1158 | 6, 1159 | 2, 1160 | 1, 1161 | 8, 1162 | 4, 1163 | 2, 1164 | 4, 1165 | 8, 1166 | 5, 1167 | 2, 1168 | 2, 1169 | 6, 1170 | 3, 1171 | 3, 1172 | 2, 1173 | 5, 1174 | 6, 1175 | 3, 1176 | 7, 1177 | 4, 1178 | 3, 1179 | 4, 1180 | 8, 1181 | 8, 1182 | 1, 1183 | 7, 1184 | 8, 1185 | 3, 1186 | 4, 1187 | 6, 1188 | 1, 1189 | 2, 1190 | 6, 1191 | 8, 1192 | 7, 1193 | 2, 1194 | 6, 1195 | 2, 1196 | 1, 1197 | 3, 1198 | 3, 1199 | 7, 1200 | 5, 1201 | 5, 1202 | 3, 1203 | 2, 1204 | 1, 1205 | 1, 1206 | 4, 1207 | 7, 1208 | 7, 1209 | 2, 1210 | 5 1211 | ], 1212 | "agent6": [ 1213 | 7, 1214 | 7, 1215 | 5, 1216 | 6, 1217 | 1, 1218 | 7, 1219 | 2, 1220 | 4, 1221 | 8, 1222 | 2, 1223 | 1, 1224 | 6, 1225 | 2, 1226 | 6, 1227 | 1, 1228 | 7, 1229 | 4, 1230 | 3, 1231 | 7, 1232 | 1, 1233 | 1, 1234 | 2, 1235 | 2, 1236 | 5, 1237 | 7, 1238 | 6, 1239 | 3, 1240 | 4, 1241 | 7, 1242 | 6, 1243 | 7, 1244 | 4, 1245 | 4, 1246 | 5, 1247 | 8, 1248 | 2, 1249 | 3, 1250 | 6, 1251 | 5, 1252 | 2, 1253 | 1, 1254 | 7, 1255 | 5, 1256 | 1, 1257 | 8, 1258 | 2, 1259 | 2, 1260 | 4, 1261 | 7, 1262 | 6, 1263 | 5, 1264 | 5, 1265 | 7, 1266 | 1, 1267 | 5, 1268 | 4, 1269 | 7, 1270 | 6, 1271 | 7, 1272 | 1, 1273 | 5, 1274 | 3, 1275 | 5, 1276 | 2, 1277 | 6, 1278 | 2, 1279 | 8, 1280 | 2, 1281 | 2, 1282 | 5, 1283 | 8, 1284 | 4, 1285 | 7, 1286 | 3, 1287 | 2, 1288 | 2, 1289 | 4, 1290 | 3, 1291 | 3, 1292 | 3, 1293 | 6, 1294 | 8, 1295 | 7, 1296 | 1, 1297 | 1, 1298 | 5, 1299 | 2, 1300 | 7, 1301 | 5, 1302 | 2, 1303 | 7, 1304 | 7, 1305 | 5, 1306 | 8, 1307 | 4, 1308 | 3, 1309 | 3, 1310 | 6, 1311 | 1, 1312 | 3, 1313 | 2, 1314 | 6, 1315 | 8, 1316 | 1, 1317 | 3, 1318 | 1, 1319 | 8, 1320 | 8, 1321 | 8, 1322 | 8, 1323 | 3, 1324 | 3, 1325 | 7, 1326 | 6, 1327 | 5, 1328 | 6, 1329 | 3, 1330 | 6, 1331 | 7, 1332 | 5, 1333 | 1, 1334 | 1, 1335 | 3, 1336 | 7, 1337 | 8, 1338 | 3, 1339 | 6, 1340 | 3, 1341 | 4, 1342 | 1, 1343 | 3, 1344 | 5, 1345 | 5, 1346 | 4, 1347 | 1, 1348 | 8, 1349 | 1, 1350 | 6, 1351 | 5, 1352 | 2, 1353 | 3, 1354 | 1, 1355 | 3, 1356 | 5, 1357 | 8, 1358 | 4, 1359 | 2, 1360 | 3, 1361 | 2, 1362 | 2, 1363 | 3, 1364 | 3, 1365 | 2, 1366 | 4, 1367 | 6, 1368 | 3, 1369 | 7, 1370 | 4, 1371 | 7, 1372 | 2, 1373 | 8, 1374 | 2, 1375 | 6, 1376 | 7, 1377 | 6, 1378 | 7, 1379 | 4, 1380 | 4, 1381 | 4, 1382 | 1, 1383 | 2, 1384 | 4, 1385 | 6, 1386 | 1, 1387 | 4, 1388 | 4, 1389 | 7, 1390 | 5, 1391 | 4, 1392 | 3, 1393 | 4, 1394 | 1, 1395 | 1, 1396 | 5, 1397 | 3, 1398 | 2, 1399 | 8, 1400 | 3, 1401 | 1, 1402 | 5, 1403 | 5, 1404 | 3, 1405 | 6, 1406 | 7, 1407 | 6, 1408 | 1, 1409 | 4, 1410 | 1, 1411 | 1, 1412 | 5, 1413 | 7, 1414 | 7, 1415 | 8, 1416 | 7, 1417 | 4, 1418 | 6, 1419 | 6, 1420 | 6, 1421 | 2, 1422 | 3, 1423 | 5, 1424 | 5, 1425 | 1, 1426 | 3, 1427 | 8, 1428 | 7, 1429 | 4, 1430 | 5, 1431 | 7, 1432 | 2, 1433 | 4, 1434 | 4, 1435 | 1, 1436 | 4, 1437 | 4, 1438 | 4, 1439 | 8, 1440 | 8, 1441 | 3, 1442 | 2, 1443 | 2, 1444 | 6, 1445 | 8, 1446 | 3, 1447 | 4, 1448 | 8, 1449 | 4, 1450 | 3, 1451 | 7, 1452 | 3 1453 | ], 1454 | "agent7": [ 1455 | 2, 1456 | 1, 1457 | 3, 1458 | 8, 1459 | 2, 1460 | 1, 1461 | 4, 1462 | 2, 1463 | 6, 1464 | 7, 1465 | 6, 1466 | 4, 1467 | 6, 1468 | 3, 1469 | 3, 1470 | 5, 1471 | 1, 1472 | 5, 1473 | 5, 1474 | 7, 1475 | 3, 1476 | 5, 1477 | 5, 1478 | 8, 1479 | 4, 1480 | 8, 1481 | 4, 1482 | 2, 1483 | 2, 1484 | 4, 1485 | 2, 1486 | 3, 1487 | 6, 1488 | 2, 1489 | 5, 1490 | 5, 1491 | 2, 1492 | 4, 1493 | 6, 1494 | 5, 1495 | 8, 1496 | 4, 1497 | 3, 1498 | 2, 1499 | 5, 1500 | 8, 1501 | 1, 1502 | 8, 1503 | 3, 1504 | 7, 1505 | 4, 1506 | 7, 1507 | 5, 1508 | 3, 1509 | 3, 1510 | 1, 1511 | 3, 1512 | 8, 1513 | 3, 1514 | 6, 1515 | 2, 1516 | 1, 1517 | 6, 1518 | 3, 1519 | 7, 1520 | 6, 1521 | 3, 1522 | 3, 1523 | 8, 1524 | 1, 1525 | 4, 1526 | 8, 1527 | 5, 1528 | 5, 1529 | 4, 1530 | 6, 1531 | 6, 1532 | 4, 1533 | 1, 1534 | 5, 1535 | 4, 1536 | 2, 1537 | 6, 1538 | 8, 1539 | 7, 1540 | 4, 1541 | 6, 1542 | 6, 1543 | 2, 1544 | 3, 1545 | 3, 1546 | 1, 1547 | 1, 1548 | 3, 1549 | 7, 1550 | 4, 1551 | 5, 1552 | 5, 1553 | 7, 1554 | 1, 1555 | 8, 1556 | 4, 1557 | 5, 1558 | 8, 1559 | 5, 1560 | 4, 1561 | 2, 1562 | 6, 1563 | 5, 1564 | 5, 1565 | 7, 1566 | 7, 1567 | 8, 1568 | 1, 1569 | 7, 1570 | 3, 1571 | 5, 1572 | 4, 1573 | 1, 1574 | 6, 1575 | 2, 1576 | 6, 1577 | 7, 1578 | 1, 1579 | 7, 1580 | 7, 1581 | 2, 1582 | 1, 1583 | 5, 1584 | 4, 1585 | 6, 1586 | 3, 1587 | 3, 1588 | 6, 1589 | 6, 1590 | 2, 1591 | 4, 1592 | 4, 1593 | 7, 1594 | 4, 1595 | 1, 1596 | 3, 1597 | 2, 1598 | 3, 1599 | 2, 1600 | 6, 1601 | 8, 1602 | 5, 1603 | 5, 1604 | 3, 1605 | 5, 1606 | 6, 1607 | 6, 1608 | 6, 1609 | 4, 1610 | 8, 1611 | 3, 1612 | 7, 1613 | 2, 1614 | 5, 1615 | 4, 1616 | 4, 1617 | 4, 1618 | 3, 1619 | 4, 1620 | 8, 1621 | 2, 1622 | 7, 1623 | 2, 1624 | 8, 1625 | 3, 1626 | 8, 1627 | 4, 1628 | 7, 1629 | 6, 1630 | 6, 1631 | 5, 1632 | 1, 1633 | 2, 1634 | 2, 1635 | 2, 1636 | 6, 1637 | 4, 1638 | 2, 1639 | 5, 1640 | 3, 1641 | 2, 1642 | 8, 1643 | 5, 1644 | 2, 1645 | 3, 1646 | 7, 1647 | 3, 1648 | 5, 1649 | 3, 1650 | 4, 1651 | 1, 1652 | 3, 1653 | 5, 1654 | 7, 1655 | 5, 1656 | 4, 1657 | 3, 1658 | 5, 1659 | 6, 1660 | 1, 1661 | 1, 1662 | 4, 1663 | 3, 1664 | 2, 1665 | 2, 1666 | 3, 1667 | 4, 1668 | 2, 1669 | 6, 1670 | 1, 1671 | 1, 1672 | 2, 1673 | 5, 1674 | 5, 1675 | 3, 1676 | 6, 1677 | 4, 1678 | 2, 1679 | 8, 1680 | 5, 1681 | 6, 1682 | 5, 1683 | 1, 1684 | 4, 1685 | 4, 1686 | 1, 1687 | 4, 1688 | 4, 1689 | 2, 1690 | 3, 1691 | 2, 1692 | 1, 1693 | 5, 1694 | 1 1695 | ], 1696 | "agent8": [ 1697 | 3, 1698 | 4, 1699 | 6, 1700 | 4, 1701 | 5, 1702 | 4, 1703 | 6, 1704 | 7, 1705 | 3, 1706 | 6, 1707 | 3, 1708 | 1, 1709 | 4, 1710 | 5, 1711 | 8, 1712 | 3, 1713 | 2, 1714 | 2, 1715 | 2, 1716 | 6, 1717 | 2, 1718 | 4, 1719 | 4, 1720 | 4, 1721 | 2, 1722 | 4, 1723 | 1, 1724 | 8, 1725 | 1, 1726 | 1, 1727 | 4, 1728 | 7, 1729 | 1, 1730 | 4, 1731 | 4, 1732 | 7, 1733 | 6, 1734 | 1, 1735 | 3, 1736 | 3, 1737 | 6, 1738 | 6, 1739 | 2, 1740 | 4, 1741 | 1, 1742 | 5, 1743 | 5, 1744 | 2, 1745 | 6, 1746 | 2, 1747 | 3, 1748 | 2, 1749 | 4, 1750 | 6, 1751 | 2, 1752 | 7, 1753 | 1, 1754 | 2, 1755 | 6, 1756 | 8, 1757 | 4, 1758 | 2, 1759 | 3, 1760 | 8, 1761 | 1, 1762 | 7, 1763 | 7, 1764 | 5, 1765 | 4, 1766 | 4, 1767 | 2, 1768 | 1, 1769 | 3, 1770 | 2, 1771 | 6, 1772 | 1, 1773 | 3, 1774 | 2, 1775 | 8, 1776 | 2, 1777 | 2, 1778 | 6, 1779 | 4, 1780 | 4, 1781 | 3, 1782 | 1, 1783 | 4, 1784 | 4, 1785 | 3, 1786 | 1, 1787 | 6, 1788 | 4, 1789 | 2, 1790 | 5, 1791 | 2, 1792 | 1, 1793 | 2, 1794 | 3, 1795 | 4, 1796 | 5, 1797 | 6, 1798 | 8, 1799 | 4, 1800 | 5, 1801 | 2, 1802 | 5, 1803 | 1, 1804 | 2, 1805 | 3, 1806 | 7, 1807 | 8, 1808 | 5, 1809 | 4, 1810 | 2, 1811 | 1, 1812 | 4, 1813 | 2, 1814 | 2, 1815 | 4, 1816 | 7, 1817 | 7, 1818 | 3, 1819 | 5, 1820 | 2, 1821 | 6, 1822 | 5, 1823 | 3, 1824 | 5, 1825 | 1, 1826 | 7, 1827 | 1, 1828 | 2, 1829 | 7, 1830 | 3, 1831 | 3, 1832 | 5, 1833 | 5, 1834 | 2, 1835 | 3, 1836 | 8, 1837 | 5, 1838 | 7, 1839 | 6, 1840 | 1, 1841 | 6, 1842 | 2, 1843 | 3, 1844 | 2, 1845 | 8, 1846 | 7, 1847 | 2, 1848 | 8, 1849 | 4, 1850 | 2, 1851 | 5, 1852 | 4, 1853 | 6, 1854 | 5, 1855 | 3, 1856 | 8, 1857 | 6, 1858 | 7, 1859 | 8, 1860 | 6, 1861 | 2, 1862 | 5, 1863 | 6, 1864 | 3, 1865 | 8, 1866 | 3, 1867 | 7, 1868 | 1, 1869 | 7, 1870 | 3, 1871 | 2, 1872 | 2, 1873 | 2, 1874 | 8, 1875 | 6, 1876 | 4, 1877 | 3, 1878 | 2, 1879 | 7, 1880 | 8, 1881 | 1, 1882 | 6, 1883 | 4, 1884 | 5, 1885 | 3, 1886 | 8, 1887 | 7, 1888 | 5, 1889 | 5, 1890 | 6, 1891 | 4, 1892 | 7, 1893 | 6, 1894 | 8, 1895 | 3, 1896 | 6, 1897 | 6, 1898 | 1, 1899 | 1, 1900 | 2, 1901 | 2, 1902 | 3, 1903 | 3, 1904 | 1, 1905 | 8, 1906 | 5, 1907 | 6, 1908 | 7, 1909 | 2, 1910 | 7, 1911 | 7, 1912 | 2, 1913 | 3, 1914 | 4, 1915 | 8, 1916 | 3, 1917 | 7, 1918 | 3, 1919 | 3, 1920 | 5, 1921 | 1, 1922 | 8, 1923 | 7, 1924 | 2, 1925 | 6, 1926 | 6, 1927 | 3, 1928 | 5, 1929 | 6, 1930 | 8, 1931 | 6, 1932 | 2, 1933 | 6, 1934 | 6, 1935 | 3, 1936 | 4 1937 | ] 1938 | } -------------------------------------------------------------------------------- /app/fight/fight.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import copy,os 3 | from utils.function import * 4 | from utils.view import GUI 5 | from buff.synergy import Synergy 6 | from fight.skill import Skill 7 | import time 8 | class Fight: 9 | ''' 10 | ''' 11 | def __init__(self,my,opp,cur_round): 12 | myskill = None 13 | my = copy.deepcopy(my) 14 | opp =copy.deepcopy(opp) 15 | self.cur_round = cur_round 16 | # first agent info 17 | self.myunits = my.fight_units 18 | self.mynum = my.fight_num 19 | self.myarr = my.fight_arrange 20 | self.myitems = my.fight_items 21 | self.mysyn = my.player_synergy 22 | self.myinfo = my.fight_infos 23 | self.myname = my.name 24 | # second agent info 25 | self.oppunits = opp.fight_units 26 | self.oppnum = opp.fight_num 27 | self.opparr = [(6-oa[0],7-oa[1]) for oa in opp.fight_arrange] 28 | self.oppitems = opp.fight_items 29 | self.oppsyn = opp.player_synergy 30 | self.oppinfo = opp.fight_infos 31 | self.oppname = opp.name 32 | hexes1 = np.zeros((7,8,30)) 33 | hexes2 = np.zeros((7,8,30)) 34 | self.start_hexes = self._assign_hexes(hexes1,self.mynum,self.myarr,self.myitems, 35 | self.mysyn,self.myinfo,self.oppnum,self.opparr,self.oppitems,self.oppsyn, 36 | self.oppinfo,max=True) 37 | self.cur_hexes = self._assign_hexes(hexes2,self.mynum,self.myarr,self.myitems, 38 | self.mysyn,self.myinfo,self.oppnum,self.opparr,self.oppitems,self.oppsyn, 39 | self.oppinfo,max=False) 40 | self.mysyns = dict() 41 | self.oppsyns = dict() 42 | self.mywait = my.wait_num 43 | self.oppwait = opp.wait_num 44 | self.is_ai = False 45 | def _assign_hexes(self,hexes,mynum,myarr,myitems,mysyn,myinfo, 46 | oppnum,opparr,oppitems,oppsyn,oppinfo,max=True): 47 | ''' 48 | ''' 49 | if max: 50 | mana = 1 51 | else: 52 | mana = 0 53 | n = 0 54 | for ou,on,oa,oitem,oinf in zip(self.oppunits,oppnum,opparr,oppitems,oppinfo): 55 | n += 1 56 | hexes[oa[0],oa[1],-1] = n 57 | hexes[oa[0],oa[1],0] = -1 58 | hexes[oa[0],oa[1],1] = on 59 | hexes[oa[0],oa[1],2] = oinf['health'] 60 | hexes[oa[0],oa[1],3] = oinf['mana'][mana] 61 | hexes[oa[0],oa[1],4] = oinf['attack_range'] 62 | hexes[oa[0],oa[1],5] = oinf['attack_damage'] 63 | hexes[oa[0],oa[1],6] = oinf['attack_speed'] 64 | hexes[oa[0],oa[1],7] = oinf['armor'] 65 | hexes[oa[0],oa[1],8] = oinf['magical_resistance'] 66 | # index 9 is is_skill 67 | # index 10 is sklll damage - config 68 | hexes[oa[0],oa[1],11] = 0.5 69 | hexes[oa[0],oa[1],12] = oinf['dodge'] 70 | hexes[oa[0],oa[1],13] = oinf['critical'] 71 | hexes[oa[0],oa[1],14] = oinf['synergy'][0] 72 | hexes[oa[0],oa[1],15] = oinf['synergy'][1] 73 | if len(oinf['synergy']) == 3: 74 | hexes[oa[0],oa[1],16] = oinf['synergy'][2] 75 | else: 76 | hexes[oa[0],oa[1],16] = -1 77 | hexes[oa[0],oa[1],17] = int(ou[-1]) 78 | # index 18 is stunned time 79 | for c,o in enumerate(oitem): 80 | hexes[oa[0],oa[1],19+c] = o 81 | # index 25 is skill shield 82 | # index 26 is shield remain time 83 | # index 26 is skill own buff 84 | # index 27 is skill remain time 85 | # index 28.29 is point of hex(x,y) 86 | for mu,mn,ma,mitem,minf in zip(self.myunits,mynum,myarr,myitems,myinfo): 87 | n += 1 88 | hexes[ma[0],ma[1],-1] = n 89 | hexes[ma[0],ma[1],0] = 1 90 | hexes[ma[0],ma[1],1] = mn 91 | hexes[ma[0],ma[1],2] = minf['health'] 92 | hexes[ma[0],ma[1],3] = minf['mana'][mana] 93 | hexes[ma[0],ma[1],4] = minf['attack_range'] 94 | hexes[ma[0],ma[1],5] = minf['attack_damage'] 95 | hexes[ma[0],ma[1],6] = minf['attack_speed'] 96 | hexes[ma[0],ma[1],7] = minf['armor'] 97 | hexes[ma[0],ma[1],8] = minf['magical_resistance'] 98 | # index 9 is is_skill 99 | # index 10 is sklll damage - config 100 | hexes[ma[0],ma[1],11] = 0.5 # critical damagepercent 101 | hexes[ma[0],ma[1],12] = minf['dodge'] 102 | hexes[ma[0],ma[1],13] = minf['critical'] # critical prob 103 | hexes[ma[0],ma[1],14] = minf['synergy'][0] 104 | hexes[ma[0],ma[1],15] = minf['synergy'][1] 105 | if len(minf['synergy']) == 3: 106 | hexes[ma[0],ma[1],16] = minf['synergy'][2] 107 | else: 108 | hexes[ma[0],ma[1],16] = -1 109 | hexes[ma[0],ma[1],17] = int(mu[-1]) # level 110 | # index 18 is stunned time 111 | for c,m in enumerate(mitem): 112 | hexes[ma[0],ma[1],19+c] = m 113 | # index 25 is skill shield 114 | # index 26 is shield remain time 115 | # index 26 is skill own buff 116 | # index 27 is skill remain time 117 | # index 28.29 is point of hex(x,y) 118 | return hexes 119 | def _read_hexes(self,hexes): 120 | status = hexes[:,:,0] 121 | oppxy = np.where(status==-1) 122 | myxy = np.where(status==1) 123 | self.opparr = [(x,y) for x,y in zip(oppxy[0],oppxy[1])] 124 | self.myarr = [(x,y) for x,y in zip(myxy[0],myxy[1])] 125 | def _move(self,hexes,arr1,targ): 126 | ''' 127 | 1 tic에 1 move 가져감. 128 | ''' 129 | moved = a_star(hexes,arr1,targ) 130 | return moved 131 | def _fly_infil(self,hexes,arr,you): 132 | if you == 1: 133 | find = 7 134 | signal = -1 135 | else: 136 | find = 0 137 | signal = 1 138 | while hexes[find,arr[1],0] != 0: 139 | if find == arr[0]: 140 | break 141 | find += signal 142 | hexes[find,arr[1],:] = hexes[arr[0],arr[1],:] 143 | hexes[arr[0],arr[1],:] = 0 144 | return hexes 145 | def _one_champ_tic(self,hexes,attack_range,arr,you,opp,enemies,tic, 146 | void=False,sniper=False,pirate=False,starguard=False,protector=False, 147 | valkyrie=False,infiltrator=False,demolitionist=False): 148 | h_enemies = [[enemy[0]+round(enemy[1]/2+0.001),enemy[1]] for enemy in enemies] 149 | h_enemies = np.array(h_enemies) 150 | h_arr = [arr[0]+round(arr[1]/2+0.001),arr[1]] 151 | tiles = np.tile(np.array(h_arr),(len(h_enemies),1)) 152 | diff = abs(tiles[:,0]-h_enemies[:,0] - tiles[:,1] + h_enemies[:,1]) 153 | dx,dy = abs(tiles[:,0]-h_enemies[:,0]),abs(- tiles[:,1] + h_enemies[:,1]) 154 | dx,dy = np.reshape(dx,(-1,1)),np.reshape(dy,(-1,1)) 155 | diff = np.reshape(diff,(-1,1)) 156 | dist = np.hstack([dx,dy,diff]) 157 | dist = np.max(dist,axis=1) 158 | nearest_dist = np.min(dist) 159 | ind = np.argmin(dist) 160 | arrind = hexes[arr[0],arr[1],1] 161 | if hexes[arr[0],arr[1],18] > 0: 162 | return hexes,[arrind,'stunned',hexes[arr[0],arr[1],18],arrind] 163 | elif (tic == 0) and infiltrator: 164 | print('fly!') 165 | hexes = self._fly_infil(self,hexes,arr,you) 166 | attack_info = [arrind,'jump to',arr,arrind] 167 | return hexes,attack_info 168 | elif hexes[arr[0],arr[1],9] == 1: 169 | self.skill.arr = arr 170 | if demolitionist: 171 | self.skill.demol = arr 172 | hexes,torf,start_hexes = self.skill.cast(opp) 173 | self.start_hexes = start_hexes 174 | if torf: 175 | self._one_champ_tic(hexes,attack_range,arr,you,opp,enemies,tic, 176 | sniper=sniper,pirate=pirate,void=void,starguard=starguard, 177 | protector=protector,valkyrie=valkyrie,infiltrator=infiltrator) 178 | if starguard: 179 | if you == 1: 180 | self.mysyns['star_skilled'] += 1 181 | elif you == -1: 182 | self.oppsyns['star_skilled'] += 1 183 | if protector: 184 | if you == 1: 185 | self.mysyns['protector_skillcast'].append([arr[0],arr[1]]) 186 | elif you == -1: 187 | self.oppsyns['protector_skillcast'].append([arr[0],arr[1]]) 188 | attack_info = [arrind,'skill',arr,arrind] 189 | return hexes,attack_info 190 | elif attack_range >= nearest_dist: 191 | cprob = [1-hexes[arr[0],arr[1],13],hexes[arr[0],arr[1],13]] 192 | if hexes[arr[0],arr[1],13] > 1: 193 | cprob=[0,1] 194 | critical = np.random.choice([0,1],p=cprob) 195 | if valkyrie: 196 | if hexes[enemies[ind][0],enemies[ind][1],2] <= \ 197 | self.start_hexes[enemies[ind][0],enemies[ind][1],2] * 0.5: 198 | critical = 1 199 | damage = hexes[arr[0],arr[1],5] - hexes[enemies[ind][0],enemies[ind][1],7] 200 | damage += critical*(hexes[arr[0],arr[1],11]*(hexes[arr[0],arr[1],5])) 201 | if void: 202 | damage = hexes[arr[0],arr[1],5] 203 | if sniper: 204 | diff = abs(tiles[ind]-enemies[ind]) 205 | damage += hexes[arr[0],arr[1],5]*(sum(diff)-1) 206 | if damage < 0: 207 | damage = 0 208 | dprob = [hexes[enemies[ind][0],enemies[ind][1],12],1-hexes[enemies[ind][0],enemies[ind][1],12]] 209 | if hexes[enemies[ind][0],enemies[ind][1],12] > 1: 210 | dprob = [0,1] 211 | dodge = np.random.choice([0,1],p=dprob) 212 | damage = damage * dodge 213 | if hexes[enemies[ind][0],enemies[ind][1],25] > 0 : 214 | hexes[enemies[ind][0],enemies[ind][1],25] -= damage/tic*hexes[arr[0],arr[1],6] 215 | if hexes[enemies[ind][0],enemies[ind][1],25] < 0: 216 | hexes[enemies[ind][0],enemies[ind][1],2] -= -hexes[enemies[ind][0],enemies[ind][1],25] 217 | else: 218 | hexes[enemies[ind][0],enemies[ind][1],2] -= damage/tic*hexes[arr[0],arr[1],6] 219 | hexes = self._mana(hexes,arr,hit=True) 220 | hexes = self._mana(hexes,enemies[ind],hit=False) 221 | if hexes[enemies[ind][0],enemies[ind][1],2] == 0: 222 | hexes[enemies[ind][0],enemies[ind][1],2] = -1.333 223 | if hexes[enemies[ind][0],enemies[ind][1],2] < 0: 224 | if pirate: 225 | if you == 1: 226 | self.mysyns['pirate_kill'] += 1 227 | elif you == -1: 228 | self.oppsyns['pirate_kill'] += 1 229 | arrind = hexes[arr[0],arr[1],1] 230 | eneind = hexes[enemies[ind][0],enemies[ind][1],1] 231 | attack_info = copy.copy([eneind,damage/tic*hexes[arr[0],arr[1],6],arr,arrind]) 232 | return hexes,attack_info 233 | else: 234 | #print('enemies',enemies,'henemies',h_enemies) 235 | #print(find_name(int(hexes[arr[0],arr[1],1])),'h_arr',h_arr,'arr',arr) 236 | #print('dist',dist) 237 | #print('nearest_dist',nearest_dist) 238 | targ = enemies[ind] 239 | eneind = copy.copy(hexes[targ[0],targ[1],1]) 240 | attack_info = [eneind,0] 241 | moved = self._move(hexes,arr,targ) 242 | if str(moved) != str(arr): 243 | hexes[moved[0],moved[1],:] = hexes[arr[0],arr[1],:] 244 | self.start_hexes[moved[0],moved[1],:] = self.start_hexes[arr[0],arr[1],:] 245 | self.start_hexes[arr[0],arr[1],:] = 0 246 | hexes[arr[0],arr[1],:] = 0 247 | arrind = hexes[moved[0],moved[1],1] 248 | attack_info += [moved,arrind] 249 | attack_info = copy.copy(attack_info) 250 | return hexes,attack_info 251 | def _mana(self,hexes,arr,hit=True): 252 | ''' 253 | hit : 10 mana 254 | damaged by opp : 4 255 | if skill, next tic skill activate 256 | ''' 257 | cur_mana = hexes[arr[0],arr[1],3] 258 | tot_mana = self.start_hexes[arr[0],arr[1],3] 259 | nm = find_name(int(hexes[arr[0],arr[1],1])) 260 | if tot_mana == 0: 261 | hexes[arr[0],arr[1],9] = 1 262 | return hexes 263 | if hit: 264 | cur_mana += 5 * hexes[arr[0],arr[1],6] 265 | else: 266 | cur_mana += 2 267 | if cur_mana >= tot_mana: 268 | hexes[arr[0],arr[1],9] = 1 269 | cur_mana = 0 270 | hexes[arr[0],arr[1],3] = cur_mana 271 | return hexes 272 | def _is_who(self,hexes,arr,synergy): 273 | if (hexes[arr[0],arr[1],14]==synergy) or (hexes[arr[0],arr[1],15]==synergy)\ 274 | or (hexes[arr[0],arr[1],16]==synergy): 275 | is_who = True 276 | else: 277 | is_who = False 278 | return is_who 279 | def _syn_tic(self,hexes,syns,arr): 280 | torf = [False]*8 281 | if syns.is_sniper: 282 | torf[0] = self._is_who(hexes,arr,19) 283 | elif syns.is_pirate: 284 | torf[1] = self._is_who(hexes,arr,6) 285 | elif syns.is_void: 286 | torf[2] = self._is_who(hexes,arr,9) 287 | elif syns.is_starguard: 288 | torf[3] = self._is_who(hexes,arr,7) 289 | elif syns.is_protector: 290 | torf[4] = self._is_who(hexes,arr,18) 291 | elif syns.is_valkyrie: 292 | torf[5] = self._is_who(hexes,arr,18) 293 | elif syns.is_infil: 294 | torf[6] = self._is_who(hexes,arr,14) 295 | elif syns.is_demol: 296 | torf[7] = self._is_who(hexes,arr,13) 297 | return torf 298 | def _fight_tic(self,hexes,n,view=False,*kwargs): 299 | '''2 tic = 1 seconds''' 300 | tic = 2 301 | attack_infos = [] 302 | self.mysyns['pirate_kill'] = 0 303 | self.mysyns['star_skilled'] = 0 304 | self.mysyns['valkyrie_target'] = [] 305 | self.mysyns['protector_skillcast'] = [] 306 | self.oppsyns['pirate_kill'] = 0 307 | self.oppsyns['star_skilled'] = 0 308 | self.oppsyns['valkyrie_target'] = [] 309 | self.oppsyns['protector_skillcast'] = [] 310 | self.skill.tic = n 311 | tofill = abs(len(self.opparr)-len(self.myarr)) 312 | if len(self.opparr) > len(self.myarr): 313 | self.myarr += [None] * tofill 314 | else: 315 | self.opparr += [None] * tofill 316 | for oa,ma in zip(self.opparr,self.myarr): 317 | if not (oa == None): 318 | oa = list(oa) 319 | oar = hexes[oa[0],oa[1],4] 320 | mark = hexes[:,:,0] 321 | oxs,oys = np.where(mark==1) 322 | oa_enemies = np.array([[x,y] for x,y in zip(oxs,oys)]) 323 | if len(oa_enemies) == 0: 324 | pass 325 | else: 326 | osni,opir,ovoi,osta,opro,oval,oinf,odem = self._syn_tic(hexes,self.oppsyn_infos,oa) 327 | hexes,attack_info = self._one_champ_tic(hexes,oar,oa,-1,1,oa_enemies, 328 | tic,sniper=osni,pirate=opir,void=ovoi,starguard=osta,protector=opro, 329 | valkyrie=oval,infiltrator=oinf,demolitionist=odem) 330 | attack_infos.append(attack_info) 331 | if not (ma == None): 332 | ma = list(ma) 333 | mar = hexes[ma[0],ma[1],4] 334 | mark = hexes[:,:,0] 335 | mxs,mys=np.where(mark==-1) 336 | ma_enemies = np.array([[x,y] for x,y in zip(mxs,mys)]) 337 | if len(ma_enemies) == 0: 338 | pass 339 | else: 340 | msni,mpir,mvoi,msta,mpro,mval,minf,mdem = self._syn_tic(hexes,self.mysyn_infos,ma) 341 | hexes,attack_info = self._one_champ_tic(hexes,mar,ma,1,-1,ma_enemies, 342 | tic,sniper=msni,pirate=mpir,void=mvoi,starguard=msta,protector=mpro, 343 | valkyrie=mval,infiltrator=minf,demolitionist=mdem) 344 | attack_infos.append(attack_info) 345 | self._read_hexes(hexes) 346 | if view: 347 | self.accumulate() 348 | return hexes 349 | def _off_skill(self): 350 | self.cur_hexes[:,:,26] -= 1 351 | on_skill = np.where(self.cur_hexes[:,:,26]==1) 352 | onx,ony = on_skill 353 | for x,y in zip(onx,ony): 354 | self.skill.arr = [x,y] 355 | self.cur_hexes = self.skill.stop() 356 | def _off_stun(self): 357 | self.cur_hexes[:,:,18] -= 1 358 | def _die(self): 359 | health = self.cur_hexes[:,:,2] 360 | dies = np.where(health<0) 361 | diesx,diesy = dies 362 | self.mysyns['ds_died'] = 0 363 | self.oppsyns['ds_died'] = 0 364 | self.oppsyns['mech_died'] = [False,False] 365 | self.mysyns['mech_died'] = [False,False] 366 | for x,y in zip(diesx,diesy): 367 | who = self.cur_hexes[x,y,0] 368 | if who == -1: 369 | if (self.cur_hexes[x,y,14] == 3) or (self.cur_hexes[x,y,15] == 3): 370 | self.oppsyns['ds_died'] += 1 371 | if self.cur_hexes[x,y,1] == 100: 372 | self.oppsyns['mech_died'] = [True,[x,y]] 373 | self.opparr.remove((x,y)) 374 | elif who == 1: 375 | if (self.cur_hexes[x,y,14] == 3) or (self.cur_hexes[x,y,15] == 3): 376 | self.mysyns['ds_died'] += 1 377 | if self.cur_hexes[x,y,1] == 100: 378 | self.mysyns['mech_died'] = [True,[x,y]] 379 | self.myarr.remove((x,y)) 380 | self.cur_hexes[x,y,:] = 0 381 | def _end(self): 382 | ''' 383 | judge the round end & calcul the life change 384 | ''' 385 | myopp = self.cur_hexes[:,:,0] 386 | round_damage = [0,3,4,5,10,15,20] 387 | if (self.myarr == []) and (self.opparr == []): 388 | round = round_damage[int(self.cur_round[0])] 389 | if self.is_ai: 390 | return False,False,round 391 | return False,0,round 392 | if self.myarr == []: 393 | count = len(self.opparr) 394 | round = round_damage[int(self.cur_round[0])] 395 | if self.is_ai: 396 | return False,False,round 397 | return False,False,count+round 398 | elif self.opparr == []: 399 | if self.is_ai: 400 | return False,True,0 401 | count = len(self.myarr) 402 | round = round_damage[int(self.cur_round[0])] 403 | return False,True,count+round 404 | else: 405 | return True,None,0 406 | def _synergy(self,infos,syns,n): 407 | infos.tic = n 408 | infos.ds_died = syns['ds_died'] 409 | infos.mech_died = syns['mech_died'] 410 | infos.pirate_kill = syns['pirate_kill'] 411 | infos.star_skilled = syns['star_skilled'] 412 | infos.valkyrie_target = syns['valkyrie_target'] 413 | infos.protector_skillcast = syns['protector_skillcast'] 414 | infos.tic = n 415 | infos.hexes = self.cur_hexes 416 | infos.apply() 417 | self.cur_hexes = infos.hexes 418 | def fight(self,video=False,gui=False): 419 | notend = True 420 | n = 0 421 | self.mysyn_infos = Synergy(self.cur_hexes,self.start_hexes,self.mysyn,n,self.myarr, 422 | self.opparr) 423 | self.mysyn_infos.apply() 424 | self.cur_hexes = self.mysyn_infos.hexes 425 | self.oppsyn_infos = Synergy(self.cur_hexes,self.start_hexes,self.mysyn,n,self.opparr, 426 | self.myarr) 427 | self.oppsyn_infos.apply() 428 | self.cur_hexes = self.oppsyn_infos.hexes 429 | #copy_hexes = copy.copy(self.oppsyn_infos.start_hexes) 430 | #self.start_hexes = copy_hexes 431 | self.money = 0 432 | self.item = [] 433 | if gui: 434 | self.init_view() 435 | self.skill = Skill(self.cur_hexes,self.start_hexes,tic=n) 436 | self.skill.mywait = self.mywait 437 | self.skill.oppwait = self.oppwait 438 | while notend: 439 | self._off_skill() 440 | self._off_stun() 441 | if n != 0: 442 | self._synergy(self.mysyn_infos,self.mysyns,n) 443 | self._synergy(self.oppsyn_infos,self.oppsyns,n) 444 | self.cur_hexes = self._fight_tic(self.cur_hexes,n,view=gui) 445 | self._die() 446 | self.skill.hexes = self.cur_hexes 447 | self.skill.maxhexes = self.start_hexes 448 | notend,win,life_change = self._end() 449 | n += 1 450 | if n > 1000: 451 | self.cur_hexes[:,:,2] = 0 452 | if video: 453 | dir = './fig/{}'.format(self.cur_round) 454 | make_video(dir,dir+'/{}.avi'.format(self.cur_round)) 455 | return win,life_change 456 | def init_view(self): 457 | name = [] 458 | cost = [] 459 | is_exist = [] 460 | for champ,c in zip(self.my_queue,self.my_cost): 461 | if champ: 462 | name.append(champ) 463 | cost.append(c) 464 | is_exist.append(True) 465 | else: 466 | name += [None] 467 | cost += [None] 468 | is_exist.append(False) 469 | infos = self.infos() 470 | self.gui = GUI(60,70,cost,name,is_exist,infos,self.my_money,self.opp_money, 471 | title='{} vs {}'.format(self.myname,self.oppname),place_table=self.place_table) 472 | def accumulate(self): 473 | infos = self.infos() 474 | self.gui.infos = infos 475 | self.gui.update_champs(self.gui.game,infos) 476 | self.gui.root.update() 477 | time.sleep(0.02) 478 | def view(self): 479 | sefl.gui.root.mainloop() 480 | def infos(self): 481 | infos = dict() 482 | n = 0 483 | self._read_hexes(self.cur_hexes) 484 | for my in self.myarr: 485 | ind = self.cur_hexes[my[0],my[1],1] 486 | heal = int(self.cur_hexes[my[0],my[1],2]) 487 | mana = int(self.cur_hexes[my[0],my[1],3]) 488 | champ = find_name(int(ind)) 489 | infos[my] = [champ,1,self.cur_hexes[my[0],my[1],-1],heal,mana] 490 | n+=1 491 | for opp in self.opparr: 492 | ind = self.cur_hexes[opp[0],opp[1],1] 493 | heal = int(self.cur_hexes[opp[0],opp[1],2]) 494 | mana = int(self.cur_hexes[opp[0],opp[1],3]) 495 | champ = find_name(int(ind)) 496 | infos[opp] = [champ,-1,self.cur_hexes[opp[0],opp[1],-1],heal,mana] 497 | n+=1 498 | return infos 499 | -------------------------------------------------------------------------------- /app/fight/skill.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import copy 3 | class Skill: 4 | def __init__(self,hexes,maxhexes,arr=None,tic=0): 5 | self.hexes = hexes 6 | self.maxhexes = maxhexes 7 | self.arr = arr 8 | self.tic = tic 9 | self.skills = [None,self._zoe,self._ziggs,self._xayah,self._twistedfate,self._poppy, 10 | self._malphite,self._leona,self._khazix,self._jarvan_iv,self._graves, 11 | self._fiora,self._caitlyn,self._yasuo,self._xin_zhao,self._sona,self._shen, 12 | self._rakan,self._mordekaiser,self._lucian,self._kaisa,self._darius, 13 | self._blitzcrank,self._annie,self._ahri,self._vi,self._syndra,self._shaco, 14 | self._rumble,self._neeko,self._master_yi,self._lux,self._kassadin, 15 | self._karma,self._jayce,self._ezreal,self._ashe,self._wukong,self._velkoz, 16 | self._soraka,self._kayle,self._jinx,self._jhin,self._irelia,self._fizz, 17 | self._chogath,self._thresh,self._miss_fortune,self._lulu,self._gangplank, 18 | self._ekko,self._aurelion_sol,self._mech_garren] 19 | self.myskill = [] 20 | self.oppskill = [] 21 | ##champs 22 | #duration 23 | self.xayah = False 24 | self.shen = False 25 | self.annie = False 26 | self.gangplank = False 27 | #effect 28 | self.demol = False 29 | self.master_yi = False 30 | self.kayle = True 31 | self.jinx = False 32 | self.jinx_speed = True 33 | self.irel_kill = False 34 | self.ekko = False 35 | self.fly = 0 36 | self.syndra = 0 37 | def _find_target(self,enemies,min=True): 38 | sth = [self.arr[0]+int(round(self.arr[1]/2+0.001)),self.arr[1]] 39 | sth = np.tile(np.array(sth),(len(enemies),1)) 40 | enh = [[en[0]+int(round(en[1]/2+0.001)),en[1]] for en in enemies] 41 | d_list = [] 42 | for st,en in zip(sth,enh): 43 | d = np.max([abs(st[0]-en[0]),abs(st[1]-en[1]),abs(st[0]-en[0]-(st[1]-en[1]))]) 44 | d_list.append(d) 45 | ind = np.argmin(d_list) 46 | tx,ty = enemies[ind] 47 | return int(tx),int(ty) 48 | def _boundary(self,x,y,d1,d2): 49 | x1 = x+d1 50 | x2 = x+d2 51 | y1 = y+d1 52 | y2 = y+d2 53 | if (x+d1<0): 54 | x1 = 0 55 | elif (x+d2>6): 56 | x2 = 6 57 | if (y+d1<0): 58 | y1 = 0 59 | elif (y+d2>7): 60 | y2 = 7 61 | return int(x1),int(x2),int(y1),int(y2) 62 | def cast(self,enemy): 63 | ind = self.hexes[self.arr[0],self.arr[1],1] 64 | level = self.hexes[self.arr[0],self.arr[1],17] 65 | xy = np.where(self.hexes[:,:,0]==enemy) 66 | enemies = [[x,y] for x,y in zip(xy[0],xy[1])] 67 | self.myopp = self.hexes[self.arr[0],self.arr[1],0] 68 | if ind == 100: 69 | torf = self.skills[-1](int(level-1),enemies) 70 | else: 71 | torf = self.skills[int(ind)](int(level),enemies) 72 | self.hexes[self.arr[0],self.arr[1],9] = 0 73 | return self.hexes,torf,self.maxhexes 74 | def stop(self): 75 | ind = self.hexes[self.arr[0],self.arr[1],1] 76 | level = self.hexes[self.arr[0],self.arr[1],17] 77 | self.myopp = self.hexes[self.arr[0],self.arr[1],0] 78 | self.skills[int(ind)](int(level),None,stop=True) 79 | return self.hexes 80 | def _zoe(self,level,enemies,damage=[200,275,400],stun=[4,5,8],stop=False): 81 | target = np.argmax(self.hexes[:,:,2]) 82 | tx,ty = int(target//8),int(target%8) 83 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 84 | 1 == 1 85 | else: 86 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 87 | self.hexes[tx,ty,18] = stun[level] 88 | def _ziggs(self,level,enemies,damage=[250,325,550],stop=False): 89 | 90 | tx,ty = self._find_target(enemies) 91 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 92 | 1 == 1 93 | else: 94 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 95 | if self.demol: 96 | self.hexes[tx,ty,18] += 2 97 | def _xayah(self,level,enemies,speed=[1,1.25,1.5],duration=[8,8,8],stop=False): 98 | if stop: 99 | self.hexes[self.arr[0],self.arr[1],6] -= speed[level] 100 | else: 101 | self.hexes[self.arr[0],self.arr[1],6] += speed[level] 102 | self.hexes[self.arr[0],self.arr[1],26] = duration[level]+1 103 | def _twistedfate(self,level,enemies,damage=[200,300,500],stop=False): 104 | if stop: 105 | torf = 0 106 | for n,card in enumerate(self.card): 107 | if len(card) == 0: 108 | continue 109 | else: 110 | torf += len(card) 111 | tx,ty = card[0] 112 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 113 | 1 == 1 114 | else: 115 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 116 | self.card[n] = self.card[n][1:] 117 | if torf > 0: 118 | self.hexes[self.arr[0],self.arr[1],26] = 2 119 | else: 120 | card_move = [[-1,0],[-1,-1],[0,-1],[1,0],[1,1],[0,1]] 121 | card_xy = [] 122 | dir_count = [] 123 | eneind = self.hexes[enemies[0][0],enemies[0][1],0] 124 | for i in range(6): 125 | count = 0 126 | xy = [] 127 | axh,ayh = self.arr[0]+int(round(self.arr[1]/2+0.001)),self.arr[1] 128 | card = np.array([axh,ayh]) + np.array(card_move[i]) 129 | orig = [int(card[0]-round(card[1]/2+0.001)),card[1]] 130 | while True: 131 | orig = [int(card[0]-round(card[1]/2+0.001)),card[1]] 132 | if (orig[0] < 0) or (orig[0] > 6) or (orig[1] < 0) or \ 133 | (orig[1] > 7): 134 | dir_count.append(count) 135 | break 136 | if self.hexes[orig[0],orig[1],0] == eneind: 137 | count += 1 138 | xy.append(copy.deepcopy(orig)) 139 | card += np.array(card_move[i]) 140 | card_xy.append(xy) 141 | target = np.argmax(count) 142 | inds = [] 143 | for i in range(-1,2): 144 | if target+i == 7: 145 | inds.append(0) 146 | else: 147 | inds.append(target+i) 148 | self.card = [card_xy[i] for i in inds] 149 | torf = 0 150 | for n,card in enumerate(self.card): 151 | if len(card) == 0: 152 | continue 153 | else: 154 | torf += len(card) 155 | tx,ty = card[0] 156 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 157 | 1 == 1 158 | else: 159 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 160 | self.card[n] = self.card[n][1:] 161 | #print('card',self.card) 162 | self.hexes[self.arr[0],self.arr[1],26] = 2 163 | def _poppy(self,level,enemies,damage=[100,175,250],shield=[200,350,500],stop=False): 164 | tx,ty = self._find_target(enemies) 165 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 166 | 1 == 1 167 | else: 168 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 169 | self.hexes[self.arr[0],self.arr[1],25] += shield[level]/2 170 | def _malphite(self,level,enemies,shield=[0.4,0.45,0.5],stop=False): 171 | if self.tic == 0: 172 | self.hexes[self.arr[0],self.arr[1],2] += \ 173 | self.hexes[self.arr[0],self.arr[1],2]*shield[level] 174 | else: 175 | return True 176 | def _leona(self,level,enemies,shield=[40,80,120],stop=False): 177 | if stop: 178 | self.hexes[self.arr[0],self.arr[1],7] -= shield[level]/2 179 | self.hexes[self.arr[0],self.arr[1],8] -= shield[level]/2 180 | else: 181 | self.hexes[self.arr[0],self.arr[1],7] += shield[level]/2 182 | self.hexes[self.arr[0],self.arr[1],8] += shield[level]/2 183 | self.hexes[self.arr[0],self.arr[1],26] = 10 184 | 185 | def _khazix(self,level,enemies,damage=[175,250,400],bonus=[600,800,1350],stop=False): 186 | tx,ty = self._find_target(enemies) 187 | tiles = np.tile(np.array([tx,ty]),(len(enemies),1)) 188 | dist = np.max(abs(tiles-enemies),axis=1) 189 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 190 | 1 == 1 191 | else: 192 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 193 | nearest_dist = np.min(dist) 194 | if nearest_dist > 1: 195 | self.hexes[tx,ty,2] -= (bonus[level]-self.hexes[tx,ty,8])/2 196 | def _jarvan_iv(self,level,enemies,speed=[0.5,0.75,1],stop=False): 197 | if stop: 198 | 199 | for buffed in self.jarvan: 200 | x,y = np.where(self.hexes[:,:,-1]==int(buffed)) 201 | if len(x) == 0: 202 | continue 203 | self.hexes[int(x[0]),int(y[0]),6] -= speed[level] 204 | else: 205 | self.jarvan = [] 206 | us = self.hexes[self.arr[0],self.arr[1],0] 207 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-1,2) 208 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==us) 209 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 210 | for tx,ty in targets: 211 | self.hexes[x1+tx,y1+ty,6] += speed[level] 212 | self.jarvan.append(self.hexes[x1+tx,y1+ty,-1]) 213 | self.hexes[self.arr[0],self.arr[1],26] = 8 214 | def _graves(self,level,enemies,damage=[150,200,400],stun=[6,8,10],stop=False): 215 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 216 | speed = [self.hexes[x,y,6] for x,y in enemies] 217 | ind = np.argmax(speed) 218 | x1,y1,x2,y2 = self._boundary(enemies[ind][0],enemies[ind][1],-1,2) 219 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 220 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 221 | for tx,ty in targets: 222 | if (damage[level] - self.hexes[x1+tx,y1+ty,8])/2 < 0 : 223 | 1 == 1 224 | else: 225 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 226 | self.hexes[tx,ty,18] = stun[level] 227 | def _fiora(self,level,enemies,damage=[200,300,450],stun=[3,3,6],stop=False): 228 | if stop: 229 | if (damage[level] - self.hexes[self.fiora[0],self.fiora[1],8])/2 < 0: 230 | 1 == 1 231 | else: 232 | self.hexes[self.fiora[0],self.fiora[1],2] -= \ 233 | (damage[level] - self.hexes[self.fiora[0],self.fiora[1],8])/2 234 | self.hexes[self.fiora[0],self.fiora[1],18] = stun[level] 235 | self.hexes[self.arr[0],self.arr[1],7] -= 10000 236 | self.hexes[self.arr[0],self.arr[1],8] -= 10000 237 | else: 238 | self.hexes[self.arr[0],self.arr[1],26] = 4 239 | self.hexes[self.arr[0],self.arr[1],7] += 10000 240 | self.hexes[self.arr[0],self.arr[1],8] += 10000 241 | self.fiora = self._find_target(enemies) 242 | def _caitlyn(self,level,enemies,damage=[750,1500,3000],stop=False): 243 | if stop: 244 | if (damage[level] - self.hexes[self.caitlyn[0],self.caitlyn[1],8])/2 < 0 : 245 | 1 == 1 246 | else: 247 | self.hexes[self.caitlyn[0],self.caitlyn[1],2] -= (damage[level] -\ 248 | self.hexes[self.caitlyn[0],self.caitlyn[1],8])/2 249 | else: 250 | tiles = np.tile(np.array(self.arr),(len(enemies),1)) 251 | dist = np.max(abs(tiles-enemies),axis=1) 252 | nearest_dist = np.min(dist) 253 | ind = np.argmax(dist) 254 | self.caitlyn = enemies[ind] 255 | self.hexes[self.arr[0],self.arr[1],26] = 9 256 | def _yasuo(self,level,enemies,hit=[8,10,12],stop=False): 257 | tx,ty = self._find_target(enemies) 258 | self.hexes[tx,ty,2] -= (hit[level]*self.hexes[self.arr[0],self.arr[1],6]*\ 259 | self.hexes[self.arr[0],self.arr[1],5] - self.hexes[tx,ty,7])/2 260 | yasuo_move = np.array([[-1,0],[-1,-1],[0,-1],[1,0],[1,1],[0,1]]) 261 | torf = False 262 | txh,tyh = tx + int(round(ty/2+0.001)),ty 263 | while torf ==False: 264 | for yasuo in yasuo_move: 265 | mxh,myh = txh+yasuo[0],tyh+yasuo[1] 266 | orig = [int(mxh-round(myh/2+0.001)),myh] 267 | if (orig[0] < 0) or (orig[0] > 6) or (orig[1] < 0) or (orig[1] > 7): 268 | continue 269 | elif self.hexes[orig[0],orig[1],0] == 0: 270 | self.hexes[orig[0],orig[1],:] = self.hexes[self.arr[0],self.arr[1],:] 271 | self.hexes[self.arr[0],self.arr[1],:] = 0 272 | self.maxhexes[orig[0],orig[1],:] = self.maxhexes[self.arr[0],self.arr[1],:] 273 | self.maxhexes[self.arr[0],self.arr[1],:] = 0 274 | torf = True 275 | break 276 | torf =True 277 | def _xin_zhao(self,level,enemies,damage=[200,275,375],stop=False): 278 | if stop: 279 | tx,ty = self._find_target(self.xin_zhao) 280 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 281 | 1 == 1 282 | else: 283 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2# stop한다고 공격을 쉬지는 않기에 공격은 안넣음 284 | self.hexes[tx,ty,18] = 3 285 | else: 286 | self.xin_zhao = enemies 287 | self.hexes[self.arr[0],self.arr[1],26] = 3 288 | def _sona(self,level,enemies,healed=[2,3,4],heal=[100,150,200],stop=False): 289 | xy = np.where(self.hexes[:,:,0]==self.myopp) 290 | us = [[x,y] for x,y in zip(xy[0],xy[1])] 291 | if len(us) < healed[level]: 292 | toheal = len(us) 293 | else: 294 | toheal = healed[level] 295 | inds = np.random.choice(len(us),toheal,replace=False) 296 | selected = [us[i] for i in inds] 297 | for sel in selected: 298 | self.hexes[sel[0],sel[1],2] += heal[level] 299 | self.hexes[sel[0],sel[1],18] = 0 300 | if self.hexes[sel[0],sel[1],2] > self.maxhexes[sel[0],sel[1],2]: 301 | self.hexes[sel[0],sel[1],2] = self.maxhexes[sel[0],sel[1],2] 302 | def _shen(self,level,enemies,resist=[15,30,45],duration=[5,6,10],stop=False): 303 | if stop: 304 | self.shen_duration -= 1 305 | if self.shen_duration == 0: 306 | for buffed in self.shen: 307 | x,y = np.where(self.hexes[:,:,-1]==buffed) 308 | self.hexes[x,y,7] -= 10000 309 | self.hexes[x,y,8] -= resist[level] 310 | self.shen = [] 311 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-1,2) 312 | self.hexes[self.arr[0],self.arr[1],26] = 2 313 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==self.myopp) 314 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 315 | for tx,ty in targets: 316 | self.hexes[tx+x1,ty+y1,7] += 10000 317 | self.hexes[tx+x1,ty+y1,8] += resist[level] 318 | self.shen.append(self.hexes[tx+x1,ty+y1,-1]) 319 | self.hexes[self.arr[0],self.arr[1],26] = 2 320 | else: 321 | for buffed in self.shen: 322 | x,y = np.where(self.hexes[:,:,-1]==buffed) 323 | self.hexes[x,y,7] -= 10000 324 | self.hexes[x,y,8] -= resist[level] 325 | self.shen = [] 326 | else: 327 | self.shen = [] 328 | self.shen_duration = duration[level] 329 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-1,2) 330 | self.hexes[self.arr[0],self.arr[1],26] = 2 331 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==self.myopp) 332 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 333 | for tx,ty in targets: 334 | self.hexes[tx+x1,ty+y1,7] += 10000 335 | self.hexes[tx+x1,ty+y1,8] += resist[level] 336 | self.shen.append(self.hexes[tx+x1,ty+y1,-1]) 337 | def _rakan(self,level,enemies,damage=[175,250,400],stun=[3,3,3],stop=False): 338 | att_range = self.hexes[self.arr[0],self.arr[1],4] 339 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-att_range,att_range+1) 340 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 341 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 342 | targets = [[x+x1,y+y1] for x,y in zip(xy[0],xy[1])] 343 | if targets == []: 344 | pass 345 | else: 346 | tx,ty = self._find_target(targets) 347 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 348 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 349 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 350 | for tx,ty in targets: 351 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 352 | 1 == 1 353 | else: 354 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 355 | self.hexes[tx+x1,ty+y1,18] = stun[level] 356 | rakan = np.where(self.hexes[x1:x2,y1:y2,0]==0) 357 | rakan_candidates = [[x,y] for x,y in zip(rakan[0],rakan[1])] 358 | rakan = np.random.choice(len(rakan_candidates),1)[0] 359 | rakan = rakan_candidates[rakan] 360 | self.hexes[x1+rakan[0],y1+rakan[1],:] = \ 361 | self.hexes[self.arr[0],self.arr[1],:] 362 | self.hexes[self.arr[0],self.arr[1],:] = 0 363 | self.maxhexes[x1+rakan[0],y1+rakan[1],:] = \ 364 | self.maxhexes[self.arr[0],self.arr[1],:] 365 | self.maxhexes[self.arr[0],self.arr[1],:] = 0 366 | def _mordekaiser(self,level,enemies,shield=[350,500,800],damage=[50,75,125],stop=False): 367 | if stop: 368 | if self.hexes[self.arr[0],self.arr[1],25] < 0: 369 | 1 == 1 370 | else: 371 | enemy = self.hexes[self.moredekaiser[0][0],self.moredekaiser[0][1],0] 372 | self.hexes[self.arr[0],self.arr[1],26] = 2 373 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-1,2) 374 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 375 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 376 | for tx,ty in targets: 377 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 378 | 1 == 1 379 | else: 380 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 381 | else: 382 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 383 | self.hexes[self.arr[0],self.arr[1],25] += shield[level]/2 384 | self.hexes[self.arr[0],self.arr[1],26] = 2 385 | x1,y1,x2,y2 = self._boundary(self.arr[0],self.arr[1],-1,2) 386 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 387 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 388 | for tx,ty in targets: 389 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 390 | 1 == 1 391 | else: 392 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 393 | self.moredekaiser = enemies 394 | def _lucian(self,level,enemies,damage=[150,200,325],stop=False): 395 | tx,ty = self._find_target(enemies) 396 | atk = self.hexes[self.arr[0],self.arr[1],5]*self.hexes[self.arr[0],self.arr[1],6] 397 | if (atk - self.hexes[tx,ty,7])/2 < 0 : 398 | 1 == 1 399 | else: 400 | self.hexes[tx,ty,2] -= (atk - self.hexes[tx,ty,7])/2 401 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 402 | 1 == 1 403 | else: 404 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 405 | axh,ayh = self.arr[0]+int(round(self.arr[1]/2+0.001)),self.arr[1] 406 | move = [[-1,0],[-1,-1],[0,-1],[1,0],[1,1],[0,1]] 407 | n = 0 408 | while True: 409 | if n >= len(move): 410 | break 411 | mxh,myh = axh+move[n][0],ayh+move[n][1] 412 | mx,my = mxh - int(round(myh/2+0.001)),myh 413 | if (mx < 0) or (mx > 6) or (my < 0) or (my > 7): 414 | n+=1 415 | continue 416 | elif self.hexes[mx,my,0] == 0: 417 | self.hexes[mx,my,:] = self.hexes[self.arr[0],self.arr[1],:] 418 | self.hexes[self.arr[0],self.arr[1],:] = 0 419 | self.maxhexes[mx,my,:] = self.maxhexes[self.arr[0],self.arr[1],:] 420 | self.maxhexes[self.arr[0],self.arr[1],:] = 0 421 | break 422 | n+=1 423 | def _kaisa(self,level,enemies,hit=[4,6,9],stop=False): 424 | tiles = np.tile(np.array(self.arr),(len(enemies),1)) 425 | dist = np.max(abs(tiles-enemies),axis=1) 426 | inds = list(np.where(dist<=2)[0]) 427 | if len(inds) == 0: 428 | targets = [] 429 | else: 430 | targets = [enemies[int(i)] for i in inds] 431 | for t in targets: 432 | if (50*hit[level] - self.hexes[t[0],t[1],8])/2 < 0 : 433 | 1 == 1 434 | else: 435 | self.hexes[t[0],t[1],2] -= (50*hit[level] - self.hexes[t[0],t[1],8])/2 436 | def _darius(self,level,enemies,damage=[400,500,750],stop=False): 437 | while True: 438 | tx,ty = self._find_target(enemies) 439 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 440 | 1 == 1 441 | else: 442 | if 0.5 * self.maxhexes[tx,ty,2] > self.hexes[tx,ty,2]: 443 | self.hexes[tx,ty,2] -= (damage[level]-self.hexes[tx,ty,8])/2 444 | self.hexes[tx,ty,2] -= (damage[level]-self.hexes[tx,ty,8])/2 445 | if self.hexes[tx,ty,2] > 0: 446 | break 447 | enemies.remove([tx,ty]) 448 | self.hexes[tx,ty,:] = self.hexes[self.arr[0],self.arr[1],:] 449 | self.hexes[self.arr[0],self.arr[1],:] = 0 450 | self.maxhexes[tx,ty,:] = self.maxhexes[self.arr[0],self.arr[1],:] 451 | self.maxhexes[self.arr[0],self.arr[1],:] = 0 452 | if len(enemies) == 0: 453 | break 454 | def _blitzcrank(self,level,enemies,damage=[250,400,900],stop=False): 455 | tx,ty = self._find_target(enemies,min=False) 456 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 457 | 1 == 1 458 | else: 459 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 460 | self.hexes[tx,ty,18] = 2 461 | target = [[-1,0],[1,0],[0,-1],[0,1],[1,1],[-1,-1]] 462 | torf = False 463 | axh,ayh = self.arr[0] + int(round(self.arr[1]/2+0.001)),self.arr[1] 464 | while torf == False: 465 | for t in target: 466 | mxh,myh = axh+t[0],ayh+t[1] 467 | orig = np.array([int(mxh-round(myh/2+0.001)),myh]) 468 | if (orig[0] < 0) or (orig[0] > 6) or (orig[1] < 0) or \ 469 | (orig[1] > 7): 470 | continue 471 | elif self.hexes[orig[0],orig[1],0] == 0: 472 | self.hexes[orig[0],orig[1],:] = self.hexes[tx,ty,:] 473 | self.hexes[tx,ty,:] = 0 474 | self.maxhexes[orig[0],orig[1],:] = self.maxhexes[tx,ty,:] 475 | self.maxhexes[tx,ty,:] = 0 476 | torf = True 477 | break 478 | def _annie(self,level,enemies,damage=[150,200,300],shield=[270,360,540],stop=False): 479 | if stop: 480 | self.hexes[self.arr[0],self.arr[1],25] = 0 481 | else: 482 | self.hexes[self.arr[0],self.arr[1],25] += shield[level]/2 483 | self.hexes[self.arr[0],self.arr[1],26] = 9 484 | tx,ty = self._find_target(enemies) 485 | eneind = self.hexes[enemies[0][0],enemies[0][1],0] 486 | txh,tyh = tx + int(round(ty/2+0.001)),ty 487 | axh,ayh = self.arr[0]+int(round(self.arr[1]/2+0.001)),self.arr[1] 488 | move = [(-1,0),(-1,-1),(0,-1),(1,0),(1,1),(0,1)] 489 | move2 = [(-2,0),(-2,-2),(0,-2),(2,0),(2,2),(0,2)] 490 | move3 = [(-2,-1),(-1,-2),(1,-1),(2,1),(1,2),(-1,1)] 491 | diff = (axh-txh,ayh-tyh) 492 | corn = [] 493 | if (diff in move): 494 | ind = move.index(diff) 495 | elif (diff in move2): 496 | ind = move2.index(diff) 497 | elif diff in move3: 498 | ind = move3.index(diff) 499 | else: 500 | print(diff) 501 | print('annie',tx,ty,enemies,self.arr) 502 | leftright = [-1,1] 503 | dir = np.random.choice(leftright,1)[0] 504 | if dir + ind > 5: 505 | ind2 = 0 506 | else: 507 | ind2 = dir + ind 508 | dir2 = np.array(list(move[ind2])) 509 | dir1 = np.array(list(move[ind])) 510 | corn = [dir1,dir1*2,dir2,dir2*2,dir1+dir2] 511 | corn_h = [[axh+d[0],ayh+d[1]] for d in corn] 512 | corn_xy = [[h[0]-int(round(h[1]/2+0.001)),h[1]] for h in corn_h] 513 | for xy in corn_xy: 514 | if (xy[0] < 0) or (xy[0] > 6) or (xy[1] < 0) or (xy[1] > 7): 515 | continue 516 | elif self.hexes[xy[0],xy[1],0] == eneind: 517 | if (damage[level] - self.hexes[xy[0],xy[1],8])/2 < 0 : 518 | 1 == 1 519 | else: 520 | self.hexes[xy[0],xy[1],2] -= \ 521 | (damage[level] - self.hexes[xy[0],xy[1],8]) 522 | def _ahri(self,level,enemies,damage=[175*3,250*3,375*3],stop=False): 523 | '''타겟 스킬 대신 2배 늘려줌''' 524 | tx,ty = self._find_target(enemies) 525 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 526 | 1 == 1 527 | else: 528 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 529 | def _vi(self,level,enemies,damage=[400,600,1200],knock=[150,200,500],\ 530 | stun=[4,5,6],stop=False): 531 | tx,ty = self._find_target(enemies,min=False) 532 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 533 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 534 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 535 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 536 | for tx,ty in targets: 537 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 538 | 1 == 1 539 | else: 540 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 541 | self.hexes[tx,ty,18] = stun[level] 542 | '''경로에 knock damage 해야함 ''' 543 | def _syndra(self,level,enemies,damage=[80,120,200],stop=False): 544 | self.syndra += 3 545 | target = np.argmax(self.hexes[:,:,2]) 546 | tx,ty = target//8,target%8 547 | if (damage[level]*self.syndra - self.hexes[tx,ty,8])/2 < 0 : 548 | 1 == 1 549 | else: 550 | self.hexes[tx,ty,2] -= (damage[level]*self.syndra - self.hexes[tx,ty,8])/2 551 | def _shaco(self,level,enemies,percent=[2,2.25,2.5],stop=False): 552 | tx,ty = self._find_target(enemies) 553 | dd = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]] 554 | for d in dd: 555 | dx,dy = tx+d[0],ty+d[1] 556 | if (dx<0) or (dx>6) or (dy<0) or (dy>7): 557 | dd.remove(d) 558 | i = np.random.choice(len(dd),1)[0] 559 | x,y = dd[i][0],dd[i][1] 560 | damage = self.hexes[self.arr[0],self.arr[1],5]*self.hexes[self.arr[0],self.arr[1],6] 561 | self.hexes[self.arr[0],self.arr[1],:] = 0 562 | if (damage*percent[level]-self.hexes[tx,ty,7])/2 < 0 : 563 | 1 == 1 564 | else: 565 | self.hexes[tx,ty,2] -= (damage*percent[level]-self.hexes[tx,ty,7])/2 566 | '''move 나중에''' 567 | def _rumble(self,level,enemies,damage=[250,400,800],stop=False): 568 | ''' 569 | damage 나중에 원뿔? 570 | if self.demol: 571 | self.hexes[tx,ty,18] += 2 572 | ''' 573 | def _neeko(self,level,enemies,damage=[200,275,550],stun=[3,5,7],stop=False): 574 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 575 | xy = np.where(self.hexes[self.arr[0]-2:self.arr[0]+3, 576 | self.arr[1]-2:self.arr[1]+3,0]==enemy) 577 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 578 | for tx,ty in targets: 579 | if (damage[level] - self.hexes[tx,ty,8])/2 < 0 : 580 | 1 == 1 581 | else: 582 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 583 | self.hexes[tx,ty,18] = stun[level] 584 | def _master_yi(self,level,enemies,bonus=[75,100,200],heal=[0.08,0.1,0.15],stop=False): 585 | self.mater_yi = [bonus[level],heal[level]] 586 | def _lux(self,level,enemies,damage=[200,300,600],stun=[3,4,5],stop=False): 587 | '''damage 나중에 원뿔?''' 588 | def _kassadin(self,level,enemies,damage=[250,400,800],stun=[5,6,7],stop=False): 589 | tx,ty = self._find_target(enemies) 590 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 591 | '''damage 나중에 원뿔?''' 592 | def _karma(self,level,enemies,shield=[250,400,800],speed=[0.35,0.5,1],stop=False): 593 | if stop: 594 | x,y = np.where(self.hexes[:,:,-1]==self.karma) 595 | self.hexes[x,y,25] -= shield[level]/2 596 | self.hexes[x,y,6] -= speed[level] 597 | else: 598 | xy = np.where(self.hexes[:,:,0]==self.myopp) 599 | us = [[x,y] for x,y in zip(xy[0],xy[1])] 600 | tiles = np.tile(np.array(self.arr),(len(us),1)) 601 | dist = list(np.max(abs(tiles-us),axis=1)) 602 | if len(dist) != 1: 603 | dist.remove(0) 604 | ind = np.argmin(dist) 605 | self.hexes[us[ind][0],us[ind][1],25] += shield[level]/2 606 | self.hexes[us[ind][0],us[ind][1],6] += speed[level] 607 | self.karma = self.hexes[us[ind][0],us[ind][1],-1] 608 | self.hexes[self.arr[0],self.arr[1],26] = 9 609 | def _jayce(self,level,enemies,damage=[450,600,1200],stop=False): 610 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 611 | tx,ty = self._find_target(enemies) 612 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 613 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 614 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 615 | for tx,ty in targets: 616 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 617 | 1 == 1 618 | else: 619 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 620 | def _ezreal(self,level,enemies,damage=[200,300,600],stop=False): 621 | '''mana reaver characteristics changes to 50% decrease cur_mana''' 622 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 623 | t = np.random.choice(len(enemies),1)[0] 624 | tx,ty = enemies[t] 625 | x1,y1,x2,y2 = self._boundary(tx,ty,-2,3) 626 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 627 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 628 | for tx,ty in targets: 629 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 630 | 1 == 1 631 | else: 632 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 633 | self.hexes[tx+x1,ty+y1,3] = 0.5*self.hexes[tx+x1,ty+y1,3] 634 | def _ashe(self,level,enemies,damage=[250,350,700],stun=[4,4,4],stop=False): 635 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 636 | i = np.random.choice(len(enemies),1)[0] 637 | tx,ty= enemies[i] 638 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 639 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 640 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 641 | for tx,ty in targets: 642 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 643 | 1 == 1 644 | else: 645 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 646 | self.hexes[tx+x1,ty+y1,18] = stun[level] 647 | def _wukong(self,level,enemies,damage=[350,500,4000],stun=[4,4,10],stop=False): 648 | '''move 구현해야함''' 649 | def _velkoz(self,level,enemies,damage=[425,550,2000],stop=False): 650 | '''damage 나중에 원뿔?''' 651 | def _soraka(self,level,enemies,heal=[375,550,20000],stop=False): 652 | xy = np.where(self.hexes[:,:,0]==self.myopp) 653 | us = [[x,y] for x,y in zip(xy[0],xy[1])] 654 | for u in us: 655 | self.hexes[u[0],u[1],2] += heal[level] 656 | if self.hexes[u[0],u[1],2] > self.maxhexes[u[0],u[1],2]: 657 | self.hexes[u[0],u[1],2] = self.maxhexes[u[0],u[1],2] 658 | def _kayle(self,level,enemies,damage=[125,200,750],stop=False): 659 | if self.kayle: 660 | self.hexes[self.arr[0],self.arr[1],5] += damage[level] 661 | self.kayle = False 662 | def _jinx(self,level,enemies,speed=[0.6,0.75,1],damage=[100,175,750],stop=False): 663 | '''0mana''' 664 | if self.jinx >= 2: 665 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 666 | tx,ty = self._find_target(enemies) 667 | atk = self.hexes[self.arr[0],self.arr[1],5]*self.hexes[self.arr[0],self.arr[1],6] 668 | self.hexes[tx,ty,2] -= (atk - self.hexes[tx,ty,7])/2 669 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 670 | xy = np.where(self,hexes[x1:x2,y1:y2,0]==enemy) 671 | target = [[x,y] for x,y in zip(xy[0],xy[1])] 672 | for tx,ty in targets: 673 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 674 | 1 == 1 675 | else: 676 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 677 | elif (self.jinx >= 1) and (self.jinx_speed): 678 | self.hexes[self.arr[0],self.arr[1],6] += speed[level] 679 | self.jinx_speed = False 680 | def _jhin(self,level,enemies,percent=[2.44,3.44,44.44],stop=False): 681 | '''0mana''' 682 | if self.tic % 4 == 0: 683 | tx,ty = self._find_target(enemies) 684 | if (self.hexes[self.arr[0],self.arr[1],5]*percent[level]-self.hexes[tx,ty,7])/2 < 0: 685 | 1==1 686 | else: 687 | self.hexes[tx,ty,2] -= (self.hexes[self.arr[0],self.arr[1],5]*\ 688 | percent[level]-self.hexes[tx,ty,7])/2 689 | else: 690 | return True 691 | def _irelia(self,level,enemies,percent=[1.75,2.5,5],stop=False): 692 | while True: 693 | tx,ty = self._find_target(enemies) 694 | if (self.hexes[self.arr[0],self.arr[1],5]*percent[level]-self.hexes[tx,ty,7])/2 < 0: 695 | 1 == 1 696 | else: 697 | self.hexes[tx,ty,2] -= (self.hexes[self.arr[0],self.arr[1],5]*percent[level] \ 698 | - self.hexes[tx,ty,7])/2 699 | if self.hexes[tx,ty,2] > 0: 700 | break 701 | enemies.remove([tx,ty]) 702 | if len(enemies) == 0: 703 | break 704 | def _fizz(self,level,enemies,damage=[350,500,2000],stop=False): 705 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 706 | ind = np.random.choice(len(enemies),1)[0] 707 | tx,ty = enemies[ind] 708 | x1,y1,x2,y2 = self._boundary(tx,ty,-3,4) 709 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 710 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 711 | for tx,ty in targets: 712 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 713 | 1 == 1 714 | else: 715 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 716 | self.hexes[tx+x1,ty+y1,18] = 3 717 | def _chogath(self,level,enemies,damage=[150,250,2000],stun=[4,4,8],stop=False): 718 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 719 | ind = np.random.choice(len(enemies),1)[0] 720 | tx,ty = enemies[ind] 721 | x1,y1,x2,y2 = self._boundary(tx,ty,-3,4) 722 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 723 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 724 | for tx,ty in targets: 725 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 726 | 1 == 1 727 | else: 728 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 729 | self.hexes[tx+x1,ty+y1,18] = stun[level] 730 | def _thresh(self,level,enemies,mana=[25,50,200],units=[1,1,9],stop=False): 731 | if self.myopp == 1: 732 | wait_units = self.mywait 733 | else: 734 | wait_units = self.oppwait 735 | #units = np.random.choice(len(wait_units),units[level]) 736 | '''wait_unit 빈 곳 배치 해야함''' 737 | def _miss_fortune(self,level,enemies,damage=[0.6,0.8,9.99],stop=False): 738 | '''damage 나중에 원뿔?''' 739 | def _lulu(self,level,enemies,num=[2,4,12],bonus=[0.05,0.1,0.25],\ 740 | stun=[6,6,16],stop=False): 741 | if stop: 742 | for tx,ty,_ in self.lulu: 743 | self.hexes[tx,ty,7] += bonus[level]*self.hexes[tx,ty,7] 744 | self.hexes[tx,ty,8] += bonus[level]*self.hexes[tx,ty,8] 745 | else: 746 | tiles = np.tile(np.array(self.arr),(len(enemies),1)) 747 | dist = np.max(abs(tiles-enemies),axis=1) 748 | enemies = [[e[0],e[1],d] for e,d in zip(enemies,dist)] 749 | enemies = sorted(enemies,key = lambda enemy: enemy[2]) 750 | if num[level] > len(enemies): 751 | nums = len(enemies) 752 | else: 753 | nums = num[level] 754 | targets = enemies[:nums] 755 | self.hexes[self.arr[0],self.arr[1],26] = stun[level] + 1 756 | for tx,ty,_ in targets: 757 | self.hexes[tx,ty,7] -= bonus[level]*self.hexes[tx,ty,7] 758 | self.hexes[tx,ty,8] -= bonus[level]*self.hexes[tx,ty,8] 759 | self.lulu = targets 760 | def _gangplank(self,level,enemies,damage=[450,600,9001],stop=False): 761 | if stop: 762 | x1,y1,x2,y2 = self.gangpalnk 763 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 764 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 765 | for tx,ty in targets: 766 | if (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 < 0 : 767 | 1 == 1 768 | else: 769 | self.hexes[tx,ty,2] -= (damage[level] - self.hexes[tx,ty,8])/2 770 | if self.demol: 771 | self.hexes[tx,ty,18] += 2 772 | else: 773 | tx,ty = self._find_target(enemies) 774 | self.gangplank = [self._boundary(tx,ty,-3,4)] 775 | def _ekko(self,level,enemies,damage=[225,400,2000],stop=False): 776 | self.ekko = True 777 | for x,y in enemies: 778 | ad = self.hexes[self.arr[0],self.arr[1],5] - self.hexes[x,y,7] 779 | ap = damage[level] - self.hexes[x,y,8] 780 | if ad < 0: 781 | ad = 0 782 | if ap < 0: 783 | ap = 0 784 | self.hexes[x,y,2] -= (ad+ap)/2 785 | def _aurelion_sol(self,level,enemies,damage=[100,150,750],stop=False): 786 | self.fly += 3 787 | inds = np.random.choice(len(enemies),self.fly) 788 | for ind in inds: 789 | x,y = enemies[ind] 790 | if (damage[level] - self.hexes[x,y,8])/2 < 0 : 791 | 1 == 1 792 | else: 793 | self.hexes[x,y,2] -= (damage[level] - self.hexes[x,y,8])/2 794 | def _mech_garren(self,level,enemies,damage=[750,1250,1700],stun=2,stop=False): 795 | enemy = self.hexes[enemies[0][0],enemies[0][1],0] 796 | tx,ty = self._find_target(enemies) 797 | x1,y1,x2,y2 = self._boundary(tx,ty,-1,2) 798 | xy = np.where(self.hexes[x1:x2,y1:y2,0]==enemy) 799 | targets = [[x,y] for x,y in zip(xy[0],xy[1])] 800 | for tx,ty in targets: 801 | if (damage[level] - self.hexes[int(tx)+x1,int(ty)+y1,8])/2 < 0 : 802 | 1 == 1 803 | else: 804 | self.hexes[tx+x1,ty+y1,2] -= (damage[level] - self.hexes[tx+x1,ty+y1,8])/2 805 | self.hexes[tx+x1,ty+y1,18] = stun 806 | --------------------------------------------------------------------------------