Example #1
0
def main_rendered(screen: Any, program: List[int]) -> None:
    '''
    Navigate through the maze to find the end and display progress on screen.
    '''
    curses.curs_set(0)

    # A dict, keyed on coordinates, with the number of times each direction has been traversed
    exploration_history: Dict[Tuple[int, int], int] = defaultdict(lambda: 0)

    # A dict, keyed on coordinates, with the character to render for that location
    maze_map: Dict[Tuple[int, int], str] = defaultdict(lambda: UNKNOWN)

    current_location: Tuple[int, int] = (0, 0)
    status: int = None  # used to store result of the last instruction
    exploration_history[current_location] += 1
    maze_map[current_location] = START

    robot = IntcodeComputer(program)

    steps = 0

    while True:

        render_scene(screen, current_location, maze_map)

        direction_to_move = get_next_direction(current_location,
                                               exploration_history)

        status = robot.run_until_input_required(direction_to_move)[0]

        if status == HIT_WALL:
            exploration_history[destination_coordinate(
                current_location, direction_to_move)] = LARGE_NUMBER
            maze_map[destination_coordinate(current_location,
                                            direction_to_move)] = WALL
        elif status == MOVED:
            current_location = destination_coordinate(current_location,
                                                      direction_to_move)
            exploration_history[current_location] += 1
            if maze_map[current_location] == UNKNOWN:
                maze_map[current_location] = PATH
        else:  # GOAL
            current_location = destination_coordinate(current_location,
                                                      direction_to_move)
            exploration_history[current_location] += 1
            maze_map[current_location] = GOAL

        steps += 1

        time.sleep(1 / REFRESH_RATE)

        if steps % 100 == 0 and is_exploration_complete(maze_map):
            break

    serialize_maze(maze_map, 'day15_maze_map.json')

    render_scene(screen, (0, 0), maze_map)
    screen.addstr(0, 0, ('{:^' + str(NX) + 's}').format('MAZE MAPPED!'))
    screen.getch()
Example #2
0
class ArcadeCabinet(object):
    tile_rendering = {

        0: ' ',  # Blank
        1: '$',  # Wall
        2: '#',  # Block
        3: '-',  # Paddle
        4: 'o'   # Ball

    }
    
    def __init__(self, screen: Any, program: List[int], free_play: bool=True) -> None:
        if free_play:
            tmp = program.copy()
            tmp[0] = 2 
        else:
            tmp = program.copy()
        self.score: int = 0
        self.paddle_x_position = -1
        self.ball_x_position = -1
        self.computer = IntcodeComputer(tmp)
        self.screen = screen
        initial_screen = self.computer.run_until_input_required()
        self.render_screen(initial_screen)
        curses.curs_set(0)
        
    def render_screen(self, tiles: List[int]) -> None:

        for i in range(0, len(tiles), 3):

            if tiles[i] == -1 and tiles[i+1] == 0:
                new_score = tiles[i+2]
                if new_score > self.score:
                    self.score = new_score
                self.screen.addstr(0, 0, f'Score: {self.score:>10}')

            else:
                self.screen.addch(
                    tiles[i+1] + 1,
                    tiles[i],
                    self.tile_rendering[tiles[i+2]]
                )

                if tiles[i+2] == 3:
                    self.paddle_x_position = tiles[i]
                if tiles[i+2] == 4:
                    self.ball_x_position = tiles[i]

        self.screen.refresh()

    def game_loop(self, bot_player: bool=False) -> None:

        while True:
            if not bot_player:
                key = self.screen.getch()
                if key == curses.KEY_LEFT:
                    input_value = -1
                elif key == curses.KEY_RIGHT:
                    input_value = 1
                else:
                    input_value = 0
            else:
                diff = self.ball_x_position - self.paddle_x_position
                if diff > 0:
                    input_value = 1
                elif diff < 0:
                    input_value = -1
                else:
                    input_value = 0
                time.sleep(0.01)
            
            tiles = self.computer.run_until_input_required(input_value)

            if tiles is None:
                self.screen.addstr(18, 13, f'GAME OVER')
                self.screen.addstr(19, 13, f'SCORE: {self.score}')
                key = self.screen.getch()
                break
            else:
                self.render_screen(tiles)