def move(self, direction: Direction, board: Board): self.last_direction = direction _, dx, dy = direction._dir nx = self.x + dx ny = self.y + dy next_element = board.get_at((nx, ny)) self.set_perk(next_element)
def act_analyzer(self, act: Act, next_point: tuple, board: Board) -> Act: if self.remote_act: d = self.explosion_radius points = {self.last_act} add_empties_around(board, self.last_act, points, dx=d, dy=d) if self.immune_time <= 1 and self.point in points: return Act.none for point in points: if board.get_at(point) in [ Element('OTHER_BOMBERMAN'), Element('MEAT_CHOPPER'), Element('OTHER_BOMB_BOMBERMAN') ]: self.act_of_remove_act() return Act.before if self.last_act_time > 5: self.act_of_remove_act() return Act.before return Act.none if act != Act.none: # can place bomb if self.count_time == 0: if self.last_act is not None: return Act.none # remote if self.remote_value > 0: self.remote_value -= 1 self.remote_act = True # setup last_act if act == Act.before: self.last_act = self.point if act == Act.after: self.last_act = next_point self.last_act_time = 0 return act else: return Act.none
class DirectionSolver: def __init__(self): self.me = Me() self.board: Optional[Board] = None self.graphic: Optional[Graphic] = None self.estimation: Optional[Estimation] = None self.next_point: Optional[tuple] = None self.direction: Optional[Direction] = None self.act: Optional[Act] = None def get(self, board_string): try: print('\n\n') self.board = Board(board_string) self.graphic = Graphic(self.board) self.estimation = Estimation(self.board) self.act = Act.none self.get_me() self.logic() self.act_logic() self.act = self.me.act_analyzer(self.act, self.next_point, self.board) self.direction = self.point_to_direction(self.next_point) self.me.move(self.direction, self.board) self.die_check() self.graphic.global_text = self.me.str() self.graphic.save() command = self.create_answer() print(f'Sending Command {command}') return command except Exception as e: print(e) return 'STOP' def get_me(self): x, y = self.board.find_bomberman() self.me.tick(x, y) print(self.me.str()) # p = (me.y + 3) * self.board._size + me.x # self.board._string = self.board._string[:p] + '1' + self.board._string[p + 1:] def make_np(self, lax, lay): npx, npy = self.me.point if lax > npx: npx -= 1 elif lax < npx: npx += 1 if lay > npy: npy -= 1 elif lay < npy: npy += 1 return npx, npy def logic(self): predictor = Predictor(self.board, self.me) predictor.run(self.me.point) print('\nPREDICTION:') predictor.print() proposal = predictor.proposal() print('\nPROPOSAL:') next_point_estimation = {} for next_point, points in proposal.items(): estimation = self.estimation.estimate(points, next_point) direction = self.point_to_direction(next_point) if direction == Direction('STOP'): estimation *= DIRECTION_STOP_K if direction == self.me.last_direction.inverted(): estimation *= DIRECTION_INVERTED_K next_point_estimation[next_point] = estimation print( f'{direction.to_string()}: {round(estimation, 5)}: {points} - {len(points)}' ) self.next_point = self.me.point if len(next_point_estimation) > 0: self.next_point = max(next_point_estimation, key=next_point_estimation.get) self.draw(predictor, next_point_estimation) def act_logic(self): before = self.estimation.estimate_act(self.me.point, self.me.explosion_radius) after = self.estimation.estimate_act(self.next_point, self.me.explosion_radius) if before >= after and before >= ESTIMATION_ACK_MIN_SCORE: self.act = Act.before elif after >= ESTIMATION_ACK_MIN_SCORE: self.act = Act.after # act check with predictor if self.act != Act.none: act_point = self.me.point if self.act == Act.before else self.next_point board = self.board.copy() board.set_at(act_point, Element('BOMB_TIMER_4')) # self.graphic = Graphic(board) act_predictor = Predictor(board, self.me) act_predictor.run(self.next_point, meat_chopper_d=2) if len(act_predictor.tree[PREDICTOR_DEEP]) == 0: self.act = Act.none if self.act == Act.before: proposal = act_predictor.proposal() if self.next_point not in proposal.keys(): self.act = Act.none # nx, ny = self.next_point # self.graphic.set_color(nx, ny, 'violet') # self.next_point = max(proposal, key=lambda key: len(proposal.get(key))) def draw(self, predictor: Predictor, next_point_estimation: dict): for deep, tree_level in enumerate(predictor.tree): if deep == 0: continue color = 'red' if deep == PREDICTOR_DEEP else 'orange' for possibility in tree_level: x, y = possibility.point self.graphic.set_color(x, y, color) for possibility in predictor.tree[PREDICTOR_DEEP]: x, y = possibility.point estimation = self.estimation.estimate_one(x, y) text = str(round(estimation, 1)) self.graphic.set_text(x, y, text) for (x, y), estimation in next_point_estimation.items(): self.graphic.set_color(x, y, 'blue') self.graphic.set_text(x, y, str(round(estimation, 2)), append=False) def die_check(self): state = self.board.get_at(self.me.point) if state == Element('DEAD_BOMBERMAN'): self.me = Me() def point_to_direction(self, next_point: tuple) -> Direction: nx, ny = next_point x, y = self.me.point dx = nx - x dy = ny - y if dx + dy == 0: return Direction('STOP') elif dy == -1: return Direction('UP') elif dy == 1: return Direction('DOWN') elif dx == -1: return Direction('LEFT') elif dx == 1: return Direction('RIGHT') def create_answer(self) -> str: command = self.direction.to_string() if self.act == Act.before: command = 'ACT, ' + command if self.act == Act.after: command = command + ', ACT' return command
def is_empty(board: Board, x: int, y: int) -> bool: return board.get_at((x, y)) in ALL_EMPTY