def turn(gcb: Board): global external_memory gcb.set_params() my_snake = gcb.me enemies_ex = gcb.enemies pills = gcb.pills if enemies_ex == []: external_memory = None return random.choice(list(SnakeAction)) if not external_memory: for i, _ex in enumerate(enemies_ex): _ex['id'] = i else: for j, _ex in enumerate(enemies_ex): for i, prev_enm in enumerate(external_memory['enemies']): if _ex['coords'][1] == prev_enm['coords'][0]: _ex['id'] = prev_enm['id'] if prev_enm['evil_capacity'] > 0: _ex['evil_capacity'] = prev_enm['evil_capacity'] - 1 else: _ex['evil_capacity'] = 0 if _ex['coords'][0] in external_memory['pills']: _ex['evil_capacity'] = _ex['evil_capacity'] + 10 if external_memory['my_snake']['evil_capacity'] > 0: my_snake['evil_capacity'] = external_memory['my_snake'][ 'evil_capacity'] - 1 if my_snake['coords'][0] in external_memory['pills']: my_snake['evil_capacity'] = my_snake['evil_capacity'] + 10 external_memory = { 'enemies': enemies_ex.copy(), 'my_snake': my_snake.copy(), 'pills': pills } #print(external_memory) #if len(gcb.enemies)>0: if gcb.me: print(gcb.enemies) my_snake = mysnake.Snake(gcb) direction = my_snake.make_step() print('---------', direction, '---------') return direction else: return random.choice(list(SnakeAction))
def __init__(self): self.time = 0 # Количество пройденных тиков self.maxTime = 300 # Количество тиков в раунде self.numSnake = 0 # Количество других змеек на поле self.numEvilSnake = 0 # Количество злых змеек на поле self.snake = Snake() self.enemySnake = [] self.lastCourse = Pole(Board(""))
def is_good(gcb: Board, p: Point, rage, allow_stones, allow_body): a = gcb.get_element_at(p) #print('NEW EL:', a.get_char()) if not rage: if not allow_stones and not allow_body and a not in base_good_elements: return False if allow_stones and not allow_body and a not in base_good_elements + [ Element('STONE') ]: return False if allow_stones and allow_body and a not in base_good_elements + [ Element('STONE') ] + my_bodies: return False else: if a not in base_good_elements + [Element('STONE') ] + enemies_bodies + enemies_tails: return False next_steps = [ p.shift_top(1), p.shift_bottom(1), p.shift_left(1), p.shift_right(1) ] if not rage: if not allow_stones: s = np.count_nonzero([ gcb.get_element_at(x) in base_good_elements for x in next_steps ]) else: s = np.count_nonzero([ gcb.get_element_at(x) in base_good_elements + [Element('STONE')] for x in next_steps ]) else: s = np.count_nonzero([ gcb.get_element_at(x) in base_good_elements + [Element('STONE')] + enemies_tails + enemies_bodies + enemies_heads for x in next_steps ]) #print('s:', s) return s > 0
def main(): fileRoundOpen = 0 if emul == 1: #Load state f = open("pole.txt", "r") # Читаем данные доски strPole = f.readline() gcb = Board(strPole) f.close() turn(gcb) elif emul == 2: #Load state startStep = 0 # f = open("raunds/2020-05-29 13:16:23.298915.txt", "r") #На этой карте воспроизводится какой то косяк # f = open("/home/joefox/Documents/2020-05-30-15-00/codebattle-snakebattle-joefox/snakebattleclient/Проиграл на -110/2020-05-30 18:35:59.508320.txt", "r") #Столнулись два яростных червя #/home/joefox/data/nextcloud/Programming/competitions/codebattle-snakebattle-joefox/snakebattleclient/raunds/2020-05-31 17:09:37.519811.txt #В конце не убежал от яростных змей f = open( "/home/joefox/data/nextcloud/Programming/competitions/codebattle-snakebattle-joefox/snakebattleclient/raunds/2020-06-02 15:18:35.186056.txt", "r") # f = open("/home/joefox/data/nextcloud/Programming/competitions/codebattle-snakebattle-joefox/snakebattleclient/raunds/2020-05-31 16:52:43.514781.txt", "r") num = 0 for line in f: num = num + 1 if num == 1: if startStep == 0: gcb = Board(line) turn(gcb) else: startStep = startStep - 1 if num == 3: num = 0 f.close() # turn(gcb) # strPole = f.readline() # strPole = f.readline() else: gcb = GameClient( "http://codebattle-pro-2020s1.westeurope.cloudapp.azure.com/codenjoy-contest/board/player/tdakkyau1nxihybx7jrk?code=8348432615981863614&gameName=snakebattle" ) gcb.run(turn)
def on_message(self, ws, message): board = Board(message.lstrip("board=")) board.print_board() action = self.on_turn(board) self.__send(action.value)
def __call__(self, gcb: Board): try: board_str = gcb._line_by_line() src_gcb = Board(board_str) my_head = gcb.get_my_head() if my_head is None: print('my_head is None') if self.head is None: return SnakeAction.RIGHT if self.prev_action == SnakeAction.RIGHT: self.head = self.head.shift_right(1) if self.prev_action == SnakeAction.LEFT: self.head = self.head.shift_left(1) if self.prev_action == SnakeAction.UP: self.head = self.head.shift_top(1) if self.prev_action == SnakeAction.DOWN: self.head = self.head.shift_bottom(1) my_head = self.head #return SnakeAction.RIGHT else: self.head = my_head my_head_el = gcb.get_element_at(my_head) rage = my_head_el == Element('HEAD_EVIL') if rage: if self.prev_action == SnakeAction.RIGHT: my_head_el = Element('HEAD_RIGHT') if self.prev_action == SnakeAction.LEFT: my_head_el = Element('HEAD_LEFT') if self.prev_action == SnakeAction.UP: my_head_el = Element('HEAD_UP') if self.prev_action == SnakeAction.DOWN: my_head_el = Element('HEAD_DOWN') #print(my_head, my_head_el) gcb.assign_point(my_head, my_head_el) first_rage = False if rage and not self.prev_rage: first_rage = True self.ticks_rage = 9 self.ticks_rage -= 1 self.prev_rage = rage if self.ticks_rage <= 0: rage = False use_new = True #not rage #gcb.update_board(my_head, rage, self.prev_action) gcb.update_board(my_head, False, self.prev_action) if use_new: gcb.create_access_reprs(my_head) #my_head_el = gcb.get_element_at(my_head) if my_head_el not in good_positions and False: self.prev_action = get_same_direction(my_head_el) return self.prev_action else: if True: if use_new: if not rage: targets = gcb._find_all(Element('APPLE'), Element('FURY_PILL'), Element('GOLD')) else: print('rage: ', len(gcb._find_all(*enemies_bodies))) targets = gcb._find_all(Element('APPLE'), Element('FURY_PILL'), Element('GOLD'), Element('STONE'), *enemies_bodies) #targets = [t for t in targets if src_gcb.get_element_at(t) != Element('WALL')] if first_rage: pass #print('TARGETS:', targets) dists = [gcb.get_dist_to(t, rage) for t in targets] targets_with_dists = [ (t, d if gcb.get_element_at(t) != Element('FURY_PILL') else 0.66 * d, scores[gcb.get_element_at(t).get_char()]) for t, d in zip(targets, dists) if d != 666 ] targets_with_dists = [ tdc for tdc in targets_with_dists if tdc[1] < self.ticks_rage or gcb.get_element_at(tdc[0]) in [ Element('APPLE'), Element('FURY_PILL'), Element('GOLD') ] ] targets_with_dists.sort(key=itemgetter(1)) for tdc in targets_with_dists: if gcb.get_element_at(tdc[0]) in enemies_bodies: print('ENEMY FOUND:', tdc[1]) #targets_with_dists = targets_with_dists[:10] if rage: pass #print('targets_with_dists:', targets_with_dists) if len(targets_with_dists) > 0 and True: dist = targets_with_dists[0][1] targets_with_dists = [ td for td in targets_with_dists if td[1] == dist ] solution_found = False ps = [] for t, d, c in targets_with_dists: if gcb.get_element_at(t) in enemies_bodies: ps = list(gcb.get_next_step_to(t, rage)) if len(ps) > 0: solution_found = True break if not solution_found: targets_with_dists.sort(key=itemgetter(2)) #if rage: #print('targets_with_dists sorted by:', targets_with_dists) ne = 1 while True and ne <= 3: target = targets_with_dists[-ne] ne += 1 if rage: pass #print('TARGET:', target) ps = gcb.get_next_step_to(target[0], rage) ps = list(ps) if len(ps) > 0: break #ps = [x for x in ps if src_gcb.get_element_at(x) != Element('WALL')] if rage: pass #print('ps:', ps) if rage: pass #print(ps) if len(ps) > 0: random.shuffle(ps) p = ps[0] if gcb.get_element_at(p) == Element( 'FURY_PILL'): self.ticks_rage += 10 if my_head.shift_top(1) == p: self.prev_action = SnakeAction.UP return self.prev_action if my_head.shift_bottom(1) == p: self.prev_action = SnakeAction.DOWN return self.prev_action if my_head.shift_left(1) == p: self.prev_action = SnakeAction.LEFT return self.prev_action if my_head.shift_right(1) == p: self.prev_action = SnakeAction.RIGHT return self.prev_action else: print('use old algo:', targets_with_dists) res = [] for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, False): #print('GOOD:', act, 'RAGE:', rage) res.append( (action_index, get_score(gcb, new_point, rage))) if len(res) == 0: for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, True): #print('GOOD:', act, 'RAGE:', rage) res.append((action_index, get_score(gcb, new_point, rage))) if len(res) == 0: for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, True, True): #print('GOOD:', act, 'RAGE:', rage) res.append((action_index, get_score(gcb, new_point, rage))) random.shuffle(res) #print(rage, res) res.sort(key=itemgetter(1)) #print(rage, res) if len(res) == 0: for action_index in range(4): act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if gcb.get_element_at(new_point) != Element( 'WALL'): res.append((action_index, get_score(gcb, new_point, rage))) if len(res) == 0: return action_index = res[-1][0] self.df = self.df.append( { 'tick': self.tick, 'board': board_str, 'action': action_index }, ignore_index=True) self.df.to_csv(f'logs/log_new_{self.n}.csv', index=False) self.tick += 1 self.prev_action = actions[action_index] return self.prev_action except Exception as e: print('Exception', e) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) pass
def turn(gcb: Board): global fileRoundOpen global fileRound if emul == 0: #Save state f = open("pole.txt", "w") # Записываем данные доски f.write(gcb._string + "\n") f.write(gcb._size.__str__() + "\n") f.write(gcb._len.__str__() + "\n") f.close() else: gcb.print_board() timeStart = datetime.datetime.now() try: pole = Pole(gcb) except ValueError: print('Ошибка1') try: pole.read() # считываем данные с поля except ValueError: print('Ошибка2') if emul == 0: if pole.time == 1: fileRoundOpen = 1 fileRound = open("raunds/" + timeStart.__str__() + ".txt", "w") if fileRoundOpen == 1: # Записываем данные доски fileRound.write(gcb._string + "\n") fileRound.write(gcb._size.__str__() + "\n") fileRound.write(gcb._len.__str__() + "\n") if fileRoundOpen == 1 and pole.time < 1: fileRound.close() fileRoundOpen = 0 print("Finish " + datetime.datetime.now().__str__()) try: pole.printSnakesInfo() except ValueError: print('Ошибка3') firstAction = SnakeAction.RIGHT if pole.snake.slep == 0 or not (pole.snake.x == 0 and pole.snake.y == 0): # try: napravlenie = pole.fill() if napravlenie == Mapping.SNAKE_LEFT: firstAction = SnakeAction.LEFT elif napravlenie == Mapping.SNAKE_RIGHT: firstAction = SnakeAction.RIGHT elif napravlenie == Mapping.SNAKE_UP: firstAction = SnakeAction.UP elif napravlenie == Mapping.SNAKE_DOWN: firstAction = SnakeAction.DOWN # except ValueError: # print('Ошибка4') else: firstAction = SnakeAction.STOP # return random.choice(list(SnakeAction)) # point = gcb.get_point_by_shift(SnakeAction.UP) # wormHead = gcb.get_my_head() # firstAction = None # if pole.snake.x > 0: # # if isinstance(wormHead, Point): # print("head x = ", pole.snake.x,", y = ", pole.snake.y) # pole.full_map() # nextElement = pole.findElement(pole.snake.x, pole.snake.y) # if isinstance(nextElement, Point): # firstAction = goTo(pole, nextElement) # else: # print("Not find next element") # point = gcb.find_first_element(Element.get_char.STONE) # print(head) # nextElement = gcb.find_first_element(Element('APPLE'), Element('FURY_PILL'), # Element('GOLD'), Element('FLYING_PILL'), Element('FURY_PILL')) # if isinstance(nextElement, Point): # # el = gcb.get_element_at(nextElement) # print("element x = ", nextElement._x,", y = ", nextElement._y) if isinstance(firstAction, SnakeAction): nextAction = firstAction max = len(pole.snake.coordinates) if max > 1: x, y = pole.snake.coordinates[max - 1] el_tail = pole.get_element_at( pole._strpos2pt(pole._xy2strpos(x, y))) stone = 0 if el_tail == Element('TAIL_END_DOWN'): dx = 0 dy = +1 stone = 1 elif el_tail == Element('TAIL_END_LEFT'): dx = -1 dy = 0 stone = 1 elif el_tail == Element('TAIL_END_UP'): dx = 0 dy = -1 stone = 1 elif el_tail == Element('TAIL_END_RIGHT'): dx = +1 dy = 0 stone = 1 if stone == 1: el = pole.get_element_at( pole._strpos2pt(pole._xy2strpos(x + dx, y + dy))) if el == Element('ENEMY_HEAD_DOWN') or el == Element( 'ENEMY_HEAD_LEFT') or el == Element( 'ENEMY_HEAD_RIGHT') or el == Element( 'ENEMY_HEAD_UP'): # Бросим камень if nextAction == SnakeAction.RIGHT: nextAction == SnakeAction.ACT_RIGHT elif nextAction == SnakeAction.LEFT: nextAction == SnakeAction.ACT_LEFT elif nextAction == SnakeAction.UP: nextAction == SnakeAction.ACT_UP elif nextAction == SnakeAction.DOWN: nextAction == SnakeAction.ACT_DOWN else: nextAction = SnakeAction.RIGHT if pole.snake.x <= 0: nextAction = SnakeAction.STOP print("sent: " + nextAction.__str__()) # poleLastCourse = pole # nextAction = SnakeAction.LEFT timeFinish = datetime.datetime.now() raznica = timeFinish - timeStart print("Start " + timeStart.__str__() + ", finish " + timeFinish.__str__() + " === " + raznica.microseconds.__str__()) if emul == 2: time.sleep(0) return nextAction
def __call__(self, gcb: Board): try: board_str = gcb._line_by_line() #src_gcb = Board(board_str) my_head = gcb.get_my_head() if my_head is None: print('my_head is None') if self.head is None: return SnakeAction.RIGHT if self.prev_action == SnakeAction.RIGHT: self.head = self.head.shift_right(1) if self.prev_action == SnakeAction.LEFT: self.head = self.head.shift_left(1) if self.prev_action == SnakeAction.UP: self.head = self.head.shift_top(1) if self.prev_action == SnakeAction.DOWN: self.head = self.head.shift_bottom(1) my_head = self.head #return SnakeAction.RIGHT if self.prev_action == SnakeAction.RIGHT: my_head_el = Element('HEAD_RIGHT') if self.prev_action == SnakeAction.LEFT: my_head_el = Element('HEAD_LEFT') if self.prev_action == SnakeAction.UP: my_head_el = Element('HEAD_UP') if self.prev_action == SnakeAction.DOWN: my_head_el = Element('HEAD_DOWN') gcb.assign_point(my_head, my_head_el) rage = self.ticks_rage > 0 else: self.head = my_head my_head_el = gcb.get_element_at(my_head) rage = my_head_el == Element('HEAD_EVIL') if rage: if self.prev_action == SnakeAction.RIGHT: my_head_el = Element('HEAD_RIGHT') if self.prev_action == SnakeAction.LEFT: my_head_el = Element('HEAD_LEFT') if self.prev_action == SnakeAction.UP: my_head_el = Element('HEAD_UP') if self.prev_action == SnakeAction.DOWN: my_head_el = Element('HEAD_DOWN') #print(my_head, my_head_el) gcb.assign_point(my_head, my_head_el) first_rage = False if rage and not self.prev_rage: first_rage = True self.ticks_rage = RAGE_TICKS - 1 self.ticks_rage -= 1 self.prev_rage = rage if self.ticks_rage <= 0: rage = False use_new = True #not rage print_rage = False gcb.update_board(my_head, rage, self.prev_action) #gcb.update_board(my_head, False, self.prev_action) if use_new: gcb.create_access_reprs(my_head) #my_head_el = gcb.get_element_at(my_head) if my_head_el not in good_positions and False: self.prev_action = get_same_direction(my_head_el) return self.prev_action else: if True: if use_new: base_targets = [ Element('APPLE'), Element('FURY_PILL'), Element('GOLD') ] if not rage: targets = gcb._find_all(*base_targets) else: if print_rage: print( 'rage: ', len( gcb._find_all(*enemies_bodies, *enemies_heads))) targets = gcb._find_all(Element('STONE'), *enemies_bodies, *enemies_heads, *base_targets) if print_rage: print( 'STONES:', len([ t for t in targets if gcb.get_element_at(t) == Element( 'STONE') ])) dists = [gcb.get_dist_to(t, rage) for t in targets] els = [gcb.get_element_at(t) for t in targets] # targets_with_dists = [ # (t, d if e != Element('FURY_PILL') else 0.66*d, scores[e.get_char()], e ) # for t, d, e in zip(targets, dists, els) if d != 666 # and (d <= self.ticks_rage or e in base_targets) # ] targets_with_dists = [ (t, d, scores[e.get_char()], e) for t, d, e in zip(targets, dists, els) if d != 666 and ( d <= self.ticks_rage or e in base_targets) ] if print_rage: print( 'STONES:', len([ t[0] for t in targets_with_dists if t[-1] == Element('STONE') ])) next_steps = [ my_head.shift_top(1), my_head.shift_bottom(1), my_head.shift_left(1), my_head.shift_right(1) ] if print_rage: for p in next_steps: print( p, p.is_out_of_board(gcb._size), str(gcb.get_element_at(p)), #str(src_gcb.get_element_at(p)) ) next_steps_els = [(p, gcb.get_element_at(p)) for p in next_steps] #print('next_steps_els 1:', [ (p, str(e)) for p,e in next_steps_els]) next_steps_els = [(p, e) for p, e in next_steps_els if e != Element('WALL') and not p.is_out_of_board(gcb._size)] #print('next_steps_els 2:', [ (p, str(e)) for p,e in next_steps_els]) if not rage: next_steps_els = [ se for se in next_steps_els if se[1] not in enemies_bodies ] target_with_scores = { se[0]: 0.0 for se in next_steps_els } for t, d, s, e in targets_with_dists: ps = list(gcb.get_next_step_to(t, rage)) for p in ps: if p in target_with_scores: target_with_scores[p] += s / d #target_with_scores[p] += s/(d**1.5) #target_with_scores[p] += s/(d**4) #target_with_scores[p] += s/(d**2) target_with_scores_list = [ (k, v) for k, v in target_with_scores.items() ] target_with_scores_list.sort(key=itemgetter(1)) #print(f'target_with_scores_list {str(my_head_el)} :', target_with_scores_list) # targets_with_dists.sort(key=itemgetter(1)) # for tdc in targets_with_dists: # if gcb.get_element_at(tdc[0]) in enemies_bodies: # print('ENEMY FOUND:', tdc[1]) # #targets_with_dists = targets_with_dists[:10] # if rage: # pass # print('targets_with_dists:', targets_with_dists) if len(target_with_scores_list) > 0 and True: target = target_with_scores_list[-1][0] if gcb.get_element_at(target) == Element( 'FURY_PILL'): self.ticks_rage += RAGE_TICKS if my_head.shift_top(1) == target: self.prev_action = SnakeAction.UP return self.prev_action if my_head.shift_bottom(1) == target: self.prev_action = SnakeAction.DOWN return self.prev_action if my_head.shift_left(1) == target: self.prev_action = SnakeAction.LEFT return self.prev_action if my_head.shift_right(1) == target: self.prev_action = SnakeAction.RIGHT return self.prev_action else: print('use old algo:', targets_with_dists) res = [] for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, allow_stones=False, allow_body=False): #print('GOOD:', act, 'RAGE:', rage) res.append( (action_index, get_score(gcb, new_point, rage))) if len(res) == 0: for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, True): #print('GOOD:', act, 'RAGE:', rage) res.append((action_index, get_score(gcb, new_point, rage))) if len(res) == 0: for action_index in range(4): #action_index = random.randint(0,3) act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if is_good(gcb, new_point, rage, True, True): #print('GOOD:', act, 'RAGE:', rage) res.append((action_index, get_score(gcb, new_point, rage))) random.shuffle(res) #print(rage, res) res.sort(key=itemgetter(1)) #print(rage, res) if len(res) == 0: for action_index in range(4): act = actions[action_index] if is_opposite(act, my_head_el): continue if act == SnakeAction.UP: new_point = my_head.shift_top(1) elif act == SnakeAction.DOWN: new_point = my_head.shift_bottom(1) elif act == SnakeAction.LEFT: new_point = my_head.shift_left(1) elif act == SnakeAction.RIGHT: new_point = my_head.shift_right(1) if gcb.get_element_at(new_point) != Element( 'WALL'): res.append((action_index, get_score(gcb, new_point, rage))) if len(res) == 0: return action_index = res[-1][0] self.df = self.df.append( { 'tick': self.tick, 'board': board_str, 'action': action_index }, ignore_index=True) self.df.to_csv(f'logs/log_new_{self.n}.csv', index=False) self.tick += 1 self.prev_action = actions[action_index] return self.prev_action except Exception as e: print('Exception', e) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno) pass