def visit(self, game_board: GameBoard): point_data = self.determine_steps(self._start_point, game_board) for point, data in point_data.items(): game_board.set_cell( point, CellDataType.STEP, StepData(self._point_type, self._point_id, data['distance'], data['nodes']))
def visit(self, game_board: GameBoard): bresenham_path = self.bresenham(self._you_snake_head['x'], self._you_snake_head['y'], self._food['x'], self._food['y']) steps, safe_path = self.safe_direct_snake_path(game_board, bresenham_path) for cell in safe_path: game_board.set_cell((cell['x'], cell['y']), CellDataType.DESIRED_PATH, SimpleData(steps))
class JazzSnake: def __init__(self, game_data): self._game_data = game_data self._point_direction_lookup = RelativePoint.get_point_direction_lookup( (game_data['you']['head']['x'], game_data['you']['head']['y'])) layer_factory = LayerFactory(game_data) self._board = GameBoard(game_data['board']['height'], game_data['board']['width']) self._board.accept_layers( layer_factory.create_your_head_layer(), layer_factory.create_snake_listener_layer(), layer_factory.create_goal_layer(), layer_factory.create_boundary_layer(), layer_factory.create_low_risk_zones_layer(), layer_factory.create_available_area_path_layer(), layer_factory.create_steps_from_point_layer(), layer_factory.create_snake_layer(), # layer_factory.create_direct_path_layer(), layer_factory.create_paths_layer()) # self._board.print() def calculate_move(self) -> str: paths = self._board.get_paths() if not paths: print("No paths!!! :(") return "up" self.print_paths(paths) best_direction = self._point_direction_lookup[paths[0]['points'][0]] print(f"MOVE: {best_direction}") return best_direction def print_paths(self, paths): table = Texttable() table.set_max_width(400) table.set_cols_align(['l' for _ in range(8)]) table.set_cols_valign(['t' for _ in range(8)]) table.header([ 'direction', 'goal', 'point_type', 'point_id', 'distance', 'points', 'scores', 'final_score' ]) for path in paths: table.add_row([ self._point_direction_lookup[path['points'][0]], path['goal_type'], path['point_type'], path['point_id'], path['distance'], '\n'.join(map(str, path['points'])), '\n'.join(map(str, path['scores'])), path['final_score'] ]) print(table.draw())
def visit(self, game_board: GameBoard): min_width = 0 max_width = game_board.get_width() min_height = 0 max_height = game_board.get_height() for x in range(min_width, max_width): for y in range(min_height, max_height): if x in (min_width, max_width - 1) or y in (min_height, max_height - 1): game_board.set_cell( (x, y), CellDataType.DEATH_THREAT_LEVEL, DeathThreatData(DeathThreatLevel.SMALL))
def __init__(self, game_data): self._game_data = game_data self._point_direction_lookup = RelativePoint.get_point_direction_lookup( (game_data['you']['head']['x'], game_data['you']['head']['y'])) layer_factory = LayerFactory(game_data) self._board = GameBoard(game_data['board']['height'], game_data['board']['width']) self._board.accept_layers( layer_factory.create_your_head_layer(), layer_factory.create_snake_listener_layer(), layer_factory.create_goal_layer(), layer_factory.create_boundary_layer(), layer_factory.create_low_risk_zones_layer(), layer_factory.create_available_area_path_layer(), layer_factory.create_steps_from_point_layer(), layer_factory.create_snake_layer(), # layer_factory.create_direct_path_layer(), layer_factory.create_paths_layer())
def visit(self, game_board: GameBoard): for goal in game_board.get_goals(): for step in game_board.get_cell_steps(goal['point']).steps_data: for path_scorer in self._path_scorers: if path_scorer.can_score_path(step, goal['type'], self._you['id']): path_follower = PathFollower(game_board, goal['type'], step.point_type, step.point_id, step.distance, self._you, path_scorer) path = path_follower.score_path(goal['point']) if path['distance'] == 0: print(f"Unexpected path distance of zero for {goal} and {path}") else: game_board.add_path(path_follower.score_path(goal['point']))
def safe_direct_snake_path(game_board: GameBoard, bresenham_path) -> (int, []): steps = 0 path = [] previous = None for current in bresenham_path: if previous is None: previous = current continue difference = (current['x'] + current['y']) - (previous['x'] + previous['y']) if abs(difference) == 2: increment = int(copysign(1, difference)) options = [{ 'x': previous['x'] + increment, 'y': previous['y'] }, { 'x': previous['x'], 'y': previous['y'] + increment }] safe_options = [] for option in options: if game_board.get_cell_death_threat( (option['x'], option['y'])).is_cell_safe(): safe_options.append(option) if len(safe_options) == 0: return 0, [] steps += 1 path.extend(safe_options) if not game_board.get_cell_death_threat( (current['x'], current['y'])).is_cell_safe(): return 0, [] steps += 1 path.append(current) return steps, path
def visit(self, game_board: GameBoard): cell_area = self.CellArea(game_board) neighbour_points = RelativePoint.get_neighbour_points( (self._you_snake_head['x'], self._you_snake_head['y'])) point_id = 0 for neighbour_point in neighbour_points: cell_count = len(cell_area.collect(neighbour_point)) score = game_board.get_total_cells() - cell_count + 1000 path = { 'goal_type': None, 'point_type': PointType.AVAILABLE_AREA, 'point_id': 'area-' + str(point_id), 'distance': cell_count, 'points': [neighbour_point], 'scores': [score], 'final_score': score } game_board.add_path(path) point_id = point_id + 1
def determine_steps(self, start_point: (), game_board: GameBoard) -> dict: frontier = Queue() frontier.put(start_point) point_data = dict() point_data[start_point] = {'distance': 0, 'nodes': []} while not frontier.empty(): current_point = frontier.get() for next_point in RelativePoint.get_neighbour_points( current_point): next_distance = point_data[current_point]['distance'] + 1 # TODO hack to keep snake tail calc working. snake tail goes backwards to death threat future stuff doesn't work cell_safe_distance = None if self._point_type == PointType.SNAKE_TAIL else next_distance if next_point not in point_data \ and game_board.get_cell_death_threat(next_point).is_cell_safe(cell_safe_distance): frontier.put(next_point) point_data[current_point]['nodes'].append(next_point) point_data[next_point] = { 'distance': next_distance, 'nodes': [current_point] } return point_data
def find_lowest_overlapping_points(self, game_board: GameBoard, snake1_id, snake2_id): lowest_distance = game_board.get_width() * game_board.get_height() points = [] for x in range(game_board.get_width()): for y in range(game_board.get_height()): snake1_step = game_board.get_cell_steps( (x, y)).get(PointType.SNAKE_HEAD, snake1_id) snake2_step = game_board.get_cell_steps( (x, y)).get(PointType.SNAKE_HEAD, snake2_id) if snake1_step is not None and snake2_step is not None and snake1_step.distance == snake2_step.distance: if snake1_step.distance == lowest_distance: lowest_distance = snake1_step.distance points.append((x, y)) elif snake1_step.distance < lowest_distance: lowest_distance = snake1_step.distance points = [(x, y)] return points
def visit(self, game_board: GameBoard): head_x = self._snake['head']['x'] head_y = self._snake['head']['y'] game_board.set_cell((head_x, head_y), CellDataType.DEATH_THREAT_LEVEL, DeathThreatData(DeathThreatLevel.SUICIDE)) if self._you['id'] != self._snake['id'] and self._you[ 'length'] <= self._snake['length']: for head_direction in RelativePoint.get_neighbour_points( (head_x, head_y)): game_board.set_cell( head_direction, CellDataType.DEATH_THREAT_LEVEL, DeathThreatData(DeathThreatLevel.EXTREME, 1)) snake_body = self._snake['body'] for i in range(self._snake['length'] - 1): game_board.set_cell((snake_body[i]['x'], snake_body[i]['y']), CellDataType.DEATH_THREAT_LEVEL, DeathThreatData(DeathThreatLevel.SUICIDE, self._snake['length'] - i))
def visit(self, game_board: GameBoard): for food_item in self._food: food_point = (food_item['x'], food_item['y']) game_board.add_goal({'type': GoalType.FOOD, 'point': food_point}) game_board.set_cell(food_point, CellDataType.FOOD, SimpleData(True)) tail = self._you['body'][-1] game_board.add_goal({ 'type': GoalType.TAIL, 'point': (tail['x'], tail['y']) }) half_width = int(game_board.get_width() / 2) half_height = int(game_board.get_height() / 2) width_rand = randrange(int(-half_width / 2), int(half_width / 2)) height_rand = randrange(int(-half_height / 2), int(half_height / 2)) game_board.add_goal({ 'type': GoalType.CENTER, 'point': (half_width + width_rand, half_height + height_rand) }) if self._you['length'] < 8: quarter_width = int(game_board.get_width() / 4) quarter_height = int(game_board.get_height() / 4) quarter_width_rand = randrange(int(-half_width / 4), int(half_width / 4)) quarter_height_rand = randrange(int(-half_height / 4), int(half_height / 4)) game_board.add_goal({ 'type': GoalType.CENTER, 'point': (quarter_width + quarter_width_rand, quarter_height + quarter_height_rand) }) game_board.add_goal({ 'type': GoalType.CENTER, 'point': ((quarter_width * 3) + quarter_width_rand, quarter_height + quarter_height_rand) }) game_board.add_goal({ 'type': GoalType.CENTER, 'point': (quarter_width + quarter_width_rand, (quarter_height * 3) + quarter_height_rand) }) game_board.add_goal({ 'type': GoalType.CENTER, 'point': ((quarter_width * 3) + quarter_width_rand, (quarter_height * 3) + quarter_height_rand) }) else: for snake in self._snakes: if snake['length'] < self._you['length']: points = self.find_lowest_overlapping_points( game_board, self._you['id'], snake['id']) for point in points: game_board.add_goal({ 'type': GoalType.HEAD_ATTACK, 'point': point })
def visit(self, game_board: GameBoard): your_head = self._you['head'] game_board.set_cell((your_head['x'], your_head['y']), CellDataType.YOUR_HEAD, SimpleData(True))