def init_view(self): name = [] cost = [] is_exist = [] for champ,c in zip(self.my_queue,self.my_cost): if champ: name.append(champ) cost.append(c) is_exist.append(True) else: name += [None] cost += [None] is_exist.append(False) infos = self.infos() self.gui = GUI(60,70,cost,name,is_exist,infos,self.my_money,self.opp_money, title='{} vs {}'.format(self.myname,self.oppname),place_table=self.place_table)
class Fight: ''' ''' def __init__(self,my,opp,cur_round): myskill = None self.cur_round = cur_round # first agent info self.myunits = my.fight_units self.mynum = my.fight_num self.myarr = my.fight_arrange self.myitems = my.fight_items self.mysyn = my.player_synergy self.myinfo = my.fight_infos self.myname = my.name # second agent info self.oppunits = opp.fight_units self.oppnum = opp.fight_num self.opparr = [(6-oa[0],7-oa[1]) for oa in opp.fight_arrange] self.oppitems = opp.fight_items self.oppsyn = opp.player_synergy self.oppinfo = opp.fight_infos self.oppname = opp.name hexes1 = np.zeros((7,8,34)) hexes2 = np.zeros((7,8,34)) self.start_hexes = self._assign_hexes(hexes1,self.mynum,self.myarr,self.myitems, self.mysyn,self.myinfo,self.oppnum,self.opparr,self.oppitems,self.oppsyn, self.oppinfo,max=True) self.cur_hexes = self._assign_hexes(hexes2,self.mynum,self.myarr,self.myitems, self.mysyn,self.myinfo,self.oppnum,self.opparr,self.oppitems,self.oppsyn, self.oppinfo,max=False) self.mysyns = dict() self.oppsyns = dict() self.mywait = my.wait_units self.oppwait = opp.wait_units def _assign_hexes(self,hexes,mynum,myarr,myitems,mysyn,myinfo, oppnum,opparr,oppitems,oppsyn,oppinfo,max=True): ''' ''' if max: mana = 1 else: mana = 0 n = 0 for ou,on,oa,oitem,oinf in zip(self.oppunits,oppnum,opparr,oppitems,oppinfo): n += 1 hexes[oa[0],oa[1],-1] = n hexes[oa[0],oa[1],0] = -1 hexes[oa[0],oa[1],1] = on print(find_name(on),oinf['mana'][mana],mana) hexes[oa[0],oa[1],2] = oinf['health'] hexes[oa[0],oa[1],3] = oinf['mana'][mana] hexes[oa[0],oa[1],4] = oinf['attack_range'] hexes[oa[0],oa[1],5] = oinf['attack_damage'] hexes[oa[0],oa[1],6] = oinf['attack_speed'] hexes[oa[0],oa[1],7] = oinf['armor'] hexes[oa[0],oa[1],8] = oinf['magical_resistance'] # index 9 is is_skill # index 10 is sklll damage - config hexes[oa[0],oa[1],11] = 0.5 hexes[oa[0],oa[1],12] = oinf['dodge'] hexes[oa[0],oa[1],13] = oinf['critical'] hexes[oa[0],oa[1],14] = oinf['synergy'][0] hexes[oa[0],oa[1],15] = oinf['synergy'][1] if len(oinf['synergy']) == 3: hexes[oa[0],oa[1],16] = oinf['synergy'][2] else: hexes[oa[0],oa[1],16] = -1 hexes[oa[0],oa[1],17] = int(ou[-1]) # index 18 is stunned time for c,o in enumerate(oitem): hexes[oa[0],oa[1],19+c] = o # index 25 is skill shield # index 26 is shield remain time # index 26 is skill own buff # index 27 is skill remain time for mu,mn,ma,mitem,minf in zip(self.myunits,mynum,myarr,myitems,myinfo): n += 1 hexes[ma[0],ma[1],-1] = n hexes[ma[0],ma[1],0] = 1 hexes[ma[0],ma[1],1] = mn print(find_name(mn),minf['mana'][mana],mana) hexes[ma[0],ma[1],2] = minf['health'] hexes[ma[0],ma[1],3] = minf['mana'][mana] hexes[ma[0],ma[1],4] = minf['attack_range'] hexes[ma[0],ma[1],5] = minf['attack_damage'] hexes[ma[0],ma[1],6] = minf['attack_speed'] hexes[ma[0],ma[1],7] = minf['armor'] hexes[ma[0],ma[1],8] = minf['magical_resistance'] # index 9 is is_skill # index 10 is sklll damage - config hexes[ma[0],ma[1],11] = 0.5 # critical damagepercent hexes[ma[0],ma[1],12] = minf['dodge'] hexes[ma[0],ma[1],13] = minf['critical'] # critical prob hexes[ma[0],ma[1],14] = minf['synergy'][0] hexes[ma[0],ma[1],15] = minf['synergy'][1] if len(minf['synergy']) == 3: hexes[ma[0],ma[1],16] = minf['synergy'][2] else: hexes[ma[0],ma[1],16] = -1 hexes[ma[0],ma[1],17] = int(mu[-1]) # level # index 18 is stunned time for c,m in enumerate(mitem): hexes[ma[0],ma[1],19+c] = m # index 25 is skill shield # index 26 is shield remain time # index 26 is skill own buff # index 27 is skill remain time return hexes def _read_hexes(self,hexes): status = hexes[:,:,0] oppxy = np.where(status==-1) myxy = np.where(status==1) self.opparr = [(x,y) for x,y in zip(oppxy[0],oppxy[1])] self.myarr = [(x,y) for x,y in zip(myxy[0],myxy[1])] def _move(self,hexes,arr1,targ): ''' 1 tic에 1 move 가져감. todo : 지능적 움직임 ''' moved = copy.copy(arr1) diff = targ - arr1 absdiff = abs(diff) ind = np.argmax(absdiff) if diff[ind] < 0: moved[ind] -= 1 if hexes[moved[0],moved[1],0] != 0: moved[ind] += 1 elif diff[ind] == 0: print('error!',targ,arr1) else: moved[ind] += 1 if hexes[moved[0],moved[1],0] != 0: moved[ind] -= 1 return moved def _fly_infil(self,hexes,arr,you): if you == 1: find = 7 signal = -1 else: find = 0 signal = 1 while hexes[find,arr[1],0] != 0: if find == arr[0]: break find += signal hexes[find,arr[1],:] = hexes[arr[0],arr[1],:] hexes[arr[0],arr[1],:] = 0 return hexes def _one_champ_tic(self,hexes,attack_range,arr,you,opp,enemies,tic, void=False,sniper=False,pirate=False,starguard=False,protector=False, valkyrie=False,infiltrator=False): print(len(enemies),arr) tiles = np.tile(np.array(arr),(len(enemies),1)) dist = np.max(abs(tiles-enemies),axis=1) nearest_dist = np.min(dist) ind = np.argmin(dist) arrind = hexes[arr[0],arr[1],1] if hexes[arr[0],arr[1],18] > 0: return hexes,[arrind,'stunned',hexes[arr[0],arr[1],18],arrind] elif (tic == 0) and infiltrator: print('fly!') hexes = self._fly_infil(self,hexes,arr,you) attack_info = [arrind,'jump to',arr,arrind] return hexes,attack_info elif hexes[arr[0],arr[1],9] == 1: #print('{} cast skill!'.format(find_name(int(hexes[arr[0],arr[1],1])))) self.skill.arr = arr hexes,torf = self.skill.cast(opp) if torf: self._one_champ_tic(hexes,attack_range,arr,you,opp,enemies,tic, sniper=sniper,pirate=pirate,void=void,starguard=starguard, protector=protector,valkyrie=valkyrie,infiltrator=infiltrator) if starguard: if you == 1: self.mysyns['star_skilled'] += 1 elif you == -1: self.oppsyns['star_skilled'] += 1 if protector: if you == 1: self.mysyns['protector_skillcast'].append([arr[0],arr[1]]) elif you == -1: self.oppsyns['protector_skillcast'].append([arr[0],arr[1]]) attack_info = [arrind,'skill',arr,arrind] return hexes,attack_info elif attack_range >= nearest_dist: cprob = [1-hexes[arr[0],arr[1],13],hexes[arr[0],arr[1],13]] if hexes[arr[0],arr[1],13] > 1: cprob=[0,1] critical = np.random.choice([0,1],p=cprob) damage = hexes[arr[0],arr[1],5] - hexes[enemies[ind][0],enemies[ind][1],7] damage += critical*(hexes[arr[0],arr[1],11]*(hexes[arr[0],arr[1],5])) if void: damage = hexes[arr[0],arr[1],5] if sniper: diff = abs(tiles[ind]-enemies[ind]) damage += hexes[arr[0],arr[1],5]*(sum(diff)-1) if damage < 0: damage = 0 dprob = [hexes[enemies[ind][0],enemies[ind][1],12],1-hexes[enemies[ind][0],enemies[ind][1],12]] if hexes[enemies[ind][0],enemies[ind][1],12] > 1: dprob = [0,1] dodge = np.random.choice([0,1],p=dprob) damage = damage * dodge #print('{} attack! damage : {}, {}'.format(\ # find_name(int(hexes[arr[0],arr[1],1])),damage,hexes[enemies[ind][0],enemies[ind][1],2])) #print('shield {}'.format(hexes[enemies[ind][0],enemies[ind][1],25])) if hexes[enemies[ind][0],enemies[ind][1],25] > 0 : hexes[enemies[ind][0],enemies[ind][1],25] -= damage/tic*hexes[arr[0],arr[1],6] if hexes[enemies[ind][0],enemies[ind][1],25] < 0: hexes[enemies[ind][0],enemies[ind][1],2] -= -hexes[enemies[ind][0],enemies[ind][1],25] else: hexes[enemies[ind][0],enemies[ind][1],2] -= damage/tic*hexes[arr[0],arr[1],6] hexes = self._mana(hexes,arr,hit=True) hexes = self._mana(hexes,enemies[ind],hit=False) if hexes[enemies[ind][0],enemies[ind][1],2] == 0: hexes[enemies[ind][0],enemies[ind][1],2] = -1.333 if hexes[enemies[ind][0],enemies[ind][1],2] < 0: if pirate: if you == 1: self.mysyns['pirate_kill'] += 1 elif you == -1: self.oppsyns['pirate_kill'] += 1 arrind = hexes[arr[0],arr[1],1] eneind = hexes[enemies[ind][0],enemies[ind][1],1] attack_info = copy.copy([eneind,damage/tic*hexes[arr[0],arr[1],6],arr,arrind]) return hexes,attack_info else: #print('{} move!'.format(find_name(int(hexes[arr[0],arr[1],1])))) targ = enemies[ind] eneind = copy.copy(hexes[targ[0],targ[1],1]) attack_info = [eneind,0] moved = self._move(hexes,arr,targ) if moved != arr: hexes[moved[0],moved[1],:] = hexes[arr[0],arr[1],:] self.start_hexes[moved[0],moved[1],:] = self.start_hexes[arr[0],arr[1],:] self.start_hexes[arr[0],arr[1],:] = 0 hexes[arr[0],arr[1],:] = 0 #hexes[arr[0],arr[1],26] = -tic-1 arrind = hexes[moved[0],moved[1],1] attack_info += [moved,arrind] attack_info = copy.copy(attack_info) return hexes,attack_info def _mana(self,hexes,arr,hit=True): ''' hit : 10 mana damaged by opp : 4 if skill, next tic skill activate ''' cur_mana = hexes[arr[0],arr[1],3] tot_mana = self.start_hexes[arr[0],arr[1],3] nm = find_name(int(hexes[arr[0],arr[1],1])) #print('{} mana refill {}/{}'.format(nm,cur_mana,tot_mana)) if tot_mana == 0: hexes[arr[0],arr[1],9] = 1 return hexes if hit: cur_mana += 5 * hexes[arr[0],arr[1],6] else: cur_mana += 2 if cur_mana >= tot_mana: hexes[arr[0],arr[1],9] = 1 cur_mana = 0 hexes[arr[0],arr[1],3] = cur_mana return hexes def _is_who(self,hexes,arr,synergy): if (hexes[arr[0],arr[1],14]==synergy) or (hexes[arr[0],arr[1],15]==synergy)\ or (hexes[arr[0],arr[1],16]==synergy): is_who = True else: is_who = False return is_who def _syn_tic(self,hexes,syns,arr): torf = [False]*7 if syns.is_sniper: torf[0] = self._is_who(hexes,arr,19) elif syns.is_pirate: torf[1] = self._is_who(hexes,arr,6) elif syns.is_void: torf[2] = self._is_who(hexes,arr,9) elif syns.is_starguard: torf[3] = self._is_who(hexes,arr,7) elif syns.is_protector: torf[4] = self._is_who(hexes,arr,18) elif syns.is_valkyrie: torf[5] = self._is_who(hexes,arr,18) elif syns.is_infil: torf[6] = self._is_who(hexes,arr,14) return torf def _fight_tic(self,hexes,n,draw=False,view=False,*kwargs): '''2 tic = 1 seconds''' tic = 2 attack_infos = [] self.mysyns['pirate_kill'] = 0 self.mysyns['star_skilled'] = 0 self.mysyns['valkyrie_target'] = [] self.mysyns['protector_skillcast'] = [] self.oppsyns['pirate_kill'] = 0 self.oppsyns['star_skilled'] = 0 self.oppsyns['valkyrie_target'] = [] self.oppsyns['protector_skillcast'] = [] self.skill.tic = n tofill = abs(len(self.opparr)-len(self.myarr)) if len(self.opparr) > len(self.myarr): self.myarr += [None] * tofill else: self.opparr += [None] * tofill for oa,ma in zip(self.opparr,self.myarr): if not (oa == None): oa = list(oa) oar = hexes[oa[0],oa[1],4] mark = hexes[:,:,0] oxs,oys = np.where(mark==1) oa_enemies = np.array([[x,y] for x,y in zip(oxs,oys)]) osni,opir,ovoi,osta,opro,oval,oinf = self._syn_tic(hexes,self.oppsyn_infos,oa) hexes,attack_info = self._one_champ_tic(hexes,oar,oa,-1,1,oa_enemies, tic,sniper=osni,pirate=opir,void=ovoi,starguard=osta,protector=opro, valkyrie=oval,infiltrator=oinf) attack_infos.append(attack_info) if not (ma == None): ma = list(ma) mar = hexes[ma[0],ma[1],4] mark = hexes[:,:,0] mxs,mys=np.where(mark==-1) ma_enemies = np.array([[x,y] for x,y in zip(mxs,mys)]) msni,mpir,mvoi,msta,mpro,mval,minf = self._syn_tic(hexes,self.mysyn_infos,ma) hexes,attack_info = self._one_champ_tic(hexes,mar,ma,1,-1,ma_enemies, tic,sniper=msni,pirate=mpir,void=mvoi,starguard=msta,protector=mpro, valkyrie=mval,infiltrator=minf) attack_infos.append(attack_info) self._read_hexes(hexes) if draw: self.visualize(hexes,n,attack_infos) if view: self.accumulate() return hexes def _off_skill(self): self.cur_hexes[:,:,26] -= 1 on_skill = np.where(self.cur_hexes[:,:,26]==1) onx,ony = on_skill #print(self.cur_hexes[:,:,26]) #print(self.cur_hexes[:,:,0]) #print(self.cur_hexes[:,:,-1]) for x,y in zip(onx,ony): self.skill.arr = [x,y] #print('stop!',self.skill.arr) self.cur_hexes = self.skill.stop() def _off_stun(self): self.cur_hexes[:,:,18] -= 1 def _die(self): health = self.cur_hexes[:,:,2] dies = np.where(health<0) diesx,diesy = dies self.mysyns['ds_died'] = 0 self.oppsyns['ds_died'] = 0 self.oppsyns['mech_died'] = [False,False] self.mysyns['mech_died'] = [False,False] for x,y in zip(diesx,diesy): who = self.cur_hexes[x,y,0] if who == -1: if (self.cur_hexes[x,y,14] == 3) or (self.cur_hexes[x,y,15] == 3): self.oppsyns['ds_died'] += 1 if self.cur_hexes[x,y,1] == 100: self.oppsyns['mech_died'] = [True,[x,y]] self.opparr.remove((x,y)) elif who == 1: if (self.cur_hexes[x,y,14] == 3) or (self.cur_hexes[x,y,15] == 3): self.mysyns['ds_died'] += 1 if self.cur_hexes[x,y,1] == 100: self.mysyns['mech_died'] = [True,[x,y]] self.myarr.remove((x,y)) self.cur_hexes[x,y,:] = 0 def _end(self): ''' judge the round end & calcul the life change ''' myopp = self.cur_hexes[:,:,0] round_damage = [0,3,4,5,10,15,20] if self.myarr == []: count = len(self.opparr) round = round_damage[int(self.cur_round[0])] return False,False,count+round elif self.opparr == []: count = len(self.myarr) round = round_damage[int(self.cur_round[0])] return False,True,count+round else: return True,None,0 def _synergy(self,infos,syns,n): infos.tic = n infos.ds_died = syns['ds_died'] infos.mech_died = syns['mech_died'] infos.pirate_kill = syns['pirate_kill'] infos.star_skilled = syns['star_skilled'] infos.valkyrie_target = syns['valkyrie_target'] infos.protector_skillcast = syns['protector_skillcast'] infos.tic = n infos.hexes = self.cur_hexes infos.apply() self.cur_hexes = infos.hexes def fight(self,video=False): notend = True n = 0 self.mysyn_infos = Synergy(self.cur_hexes,self.start_hexes,self.mysyn,n,self.myarr, self.opparr) self.mysyn_infos.apply() self.cur_hexes = self.mysyn_infos.hexes self.oppsyn_infos = Synergy(self.cur_hexes,self.start_hexes,self.mysyn,n,self.opparr, self.myarr) self.oppsyn_infos.apply() self.cur_hexes = self.oppsyn_infos.hexes #copy_hexes = copy.copy(self.oppsyn_infos.start_hexes) #self.start_hexes = copy_hexes self.money = 0 self.item = [] self.init_view() self.skill = Skill(self.cur_hexes,self.start_hexes,tic=n) self.skill.mywait = self.mywait self.skill.oppwait = self.oppwait while notend: self._off_skill() self._off_stun() if n != 0: self._synergy(self.mysyn_infos,self.mysyns,n) self._synergy(self.oppsyn_infos,self.oppsyns,n) self.cur_hexes = self._fight_tic(self.cur_hexes,n,draw=False,view=True) self._die() self.skill.hexes = self.cur_hexes self.skill.maxhexes = self.start_hexes notend,win,life_change = self._end() n += 1 if n > 1000: self.cur_hexes[:,:,2] = 0 print('my pirate money {}'.format(self.mysyn_infos.pirate_money)) print('my pirate money {}'.format(self.mysyn_infos.pirate_item)) print('enemy pirate money {}'.format(self.oppsyn_infos.pirate_money)) print('enemy pirate money {}'.format(self.oppsyn_infos.pirate_item)) if video: dir = './fig/{}'.format(self.cur_round) make_video(dir,dir+'/{}.avi'.format(self.cur_round)) return win,life_change def visualize(self,hexes,n,attack_infos): if not os.path.exists('./fig/{}'.format('ROUND_'+self.cur_round)): os.mkdir('./fig/{}'.format('ROUND_'+self.cur_round)) if not os.path.exists('./fig/{}/{}vs{}'.format('ROUND_'+self.cur_round,self.myname,self.oppname)): os.mkdir('./fig/{}/{}vs{}'.format('ROUND_'+self.cur_round,self.myname,self.oppname)) fn = (4 - len(str(n)))*'0' + str(n) imgname = './fig/{}/{}vs{}/frame_{}.jpg'.format('ROUND_'+self.cur_round,self.myname,self.oppname,fn) draw_chess(hexes,self.start_hexes,imgname,attack_infos) def init_view(self): name = [] cost = [] is_exist = [] for champ,c in zip(self.my_queue,self.my_cost): if champ: name.append(champ) cost.append(c) is_exist.append(True) else: name += [None] cost += [None] is_exist.append(False) infos = self.infos() self.gui = GUI(60,70,cost,name,is_exist,infos,self.my_money,self.opp_money, title='{} vs {}'.format(self.myname,self.oppname),place_table=self.place_table) def accumulate(self): infos = self.infos() self.gui.infos = infos self.gui.update_champs(self.gui.game,infos) self.gui.root.update() time.sleep(0.05) def view(self): sefl.gui.root.mainloop() def infos(self): infos = dict() n = 0 self._read_hexes(self.cur_hexes) for my in self.myarr: ind = self.cur_hexes[my[0],my[1],1] heal = int(self.cur_hexes[my[0],my[1],2]) mana = int(self.cur_hexes[my[0],my[1],3]) champ = find_name(int(ind)) infos[my] = [champ,1,self.cur_hexes[my[0],my[1],-1],heal,mana] n+=1 for opp in self.opparr: ind = self.cur_hexes[opp[0],opp[1],1] heal = int(self.cur_hexes[opp[0],opp[1],2]) mana = int(self.cur_hexes[opp[0],opp[1],3]) champ = find_name(int(ind)) infos[opp] = [champ,-1,self.cur_hexes[opp[0],opp[1],-1],heal,mana] n+=1 return infos