Ejemplo n.º 1
0
def paint(program, start_color):
    # type: (NewProgram, int) -> Tuple[int, PaintedArea]
    '''
    Run a painting program on the robot
    '''
    directions = [Direction(0, -1), Direction(1, 0), Direction(0, 1), Direction(-1, 0)]
    painted_area = defaultdict(lambda: defaultdict(lambda: -1))
    painted_area[0][0] = start_color
    position = Point(0, 0)
    direction = 0
    pointer = 0
    relative_base = 0
    while pointer != -1:
        current_color = max(painted_area[position.y][position.x], 0)
        program, output, pointer, relative_base = run_program(program, [current_color], pointer, True, relative_base)
        painted_area[position.y][position.x] = output[0]
        if output[1] == 1:
            direction = (direction + 1) % len(directions)
        else:
            direction = (direction - 1) % len(directions)

        position.x = position.x + directions[direction].x
        position.y = position.y + directions[direction].y

    nb_painted = 0
    for y in painted_area:
        for x in painted_area[y]:
            if painted_area[y][x] > -1:
                nb_painted += 1

    return nb_painted, painted_area
Ejemplo n.º 2
0
def play(program, fps=0):
    # type: (NewProgram, int) -> int
    '''
    Play the game until it ends
    '''
    program[0] = 2
    pointer = 0
    relative_base = 0
    input = []
    game_map = None
    while pointer != -1:
        program, output, pointer, relative_base = run_program(
            program, input, pointer, True, relative_base)
        game_map = update_game_map(output, game_map)
        if fps:
            print_game_map(game_map)
            sleep(1 / fps)
        paddle_pos = find_object(game_map, 3)
        ball_pos = find_object(game_map, 4)
        if (ball_pos is None or paddle_pos is None):
            input = [0]
            continue
        input = [(ball_pos.x > paddle_pos.x) - (ball_pos.x < paddle_pos.x)]
    if fps:
        print_game_map(update_game_map(output, game_map))
    return game_map[Point(-1, 0)]
Ejemplo n.º 3
0
def display_map(shield_map, vacuum_state=(Point(-1, -1), 0), intersections=[]):
    # type: (ShieldMap, Tuple[Point, int], List[int]) -> None
    '''
    Prints the map in text mode
    '''
    max_x = max([p.x for p in shield_map if shield_map[p] is not None])
    max_y = max([p.y for p in shield_map if shield_map[p] is not None])

    for y in range(0, max_y + 1):
        for x in range(0, max_x + 1):
            pos = Point(x, y)
            value = shield_map[Point(x, y)] if pos != vacuum_state[0] else vacuum_state[1]
            if pos in intersections:
                value = ord('O')
            sys.stdout.write(chr(value))
        print('')
Ejemplo n.º 4
0
def display_beam(affected_points, start_x=0, start_y=0):
    height = max(p.y for p in affected_points)
    width = max(p.x for p in affected_points)
    for y in range(start_y, height):
        for x in range(start_x, width):
            sys.stdout.write('#' if Point(x, y) in affected_points else '.')
        print('')
Ejemplo n.º 5
0
def get_affected_points(program, width=50, height=50):
    affected_points = set()
    for y in range(0, height):
        for x in range(0, width):
            if get_status(x, y, program):
                affected_points.add(Point(x, y))
    return affected_points
Ejemplo n.º 6
0
def build_map(cells):
    # type: (List[int]) -> Tuple[ShieldMap, Tuple[Point, int]]
    '''
    Converts the camera output to a structured map
    '''
    vacuum_state = (Point(-1, -1), 0)
    shield_map = defaultdict(lambda: 0)
    x = 0
    y = 0
    for cell in cells:
        if cell == 10:
            y += 1
            x = 0
            continue
        pos = Point(x, y)
        if cell in directions_ascii:
            vacuum_state = (pos, cell)
            cell = 35
        shield_map[pos] = cell
        x += 1

    return shield_map, vacuum_state
Ejemplo n.º 7
0
def build_map(program):
    # type: (Program) -> Tuple[SectionMap, SectionMap, Point]
    '''
    Builds the section map by keeping the wall to the right
    '''
    section_map = defaultdict(lambda: -2, {Point(0, 0): 3})
    distance_map = defaultdict(lambda: sys.maxsize, {Point(0, 0): 0})

    pointer = 0
    relative_base = 0
    direction = 1
    position = Point(0, 0)
    oxygen_system_location = None

    while pointer != -1:
        program, output, pointer, relative_base = run_program(
            program, [direction + 1], pointer, True, relative_base)
        result = output[0]
        if result == 0:
            section_map[position + directions[direction]] = -1
            # Droid hit a wall, change the direction to keep the wall on the right
            direction = next_direction[direction]
        else:
            position += directions[direction]
            section_map[position] = max(section_map[position], result)
            distance_map[position] = min(
                [distance_map[position + directions[i]]
                 for i in range(0, 4)]) + 1
            if result == 2:
                oxygen_system_location = position
            # Droid didn't hit a wall, go back to the previous direction to keep the wall on the right
            direction = next_direction.index(direction)
        # Back to the start and all direction from the start are known, the map is completed
        if position == Point(0, 0) and section_map[directions[
                0]] != -2 and section_map[directions[1]] != -2 and section_map[
                    directions[2]] != -2 and section_map[directions[3]] != -2:
            break
    return section_map, distance_map, oxygen_system_location
Ejemplo n.º 8
0
def update_game_map(output, game_map=None):
    # type: (List[int], GameMap) -> GameMap
    '''
    Updates the game map with the program's output
    '''
    if game_map is None:
        game_map = defaultdict(lambda: 0)
    for i in range(0, len(output) // 3):
        x = output[3 * i]
        y = output[3 * i + 1]
        value = output[3 * i + 2]
        game_map[Point(x, y)] = value

    return game_map
Ejemplo n.º 9
0
def print_map(section_map, droid_position):
    # type: (SectionMap, Point) -> None
    '''
    Prints the map in text mode.
    '''
    if sys.platform == 'win32':
        os.system('cls')
    else:
        os.system('clear')

    xs = [p.x for p in section_map]
    min_x, max_x = min(xs), max(xs)
    ys = [p.y for p in section_map]
    min_y, max_y = min(ys), max(ys)

    symbols = {-2: '░', -1: '█', 1: ' ', 2: '●', 3: '¤', 4: '☺'}
    for y in range(min_y, max_y + 1):
        for x in range(min_x, max_x + 1):
            if Point(x, y) == droid_position:
                sys.stdout.write(symbols[4])
            else:
                value = section_map[Point(x, y)]
                sys.stdout.write(symbols[value])
        print('')
Ejemplo n.º 10
0
def find_closest_n_square(program, n=100):
    beam_starts = {n-1: 0}
    y = n
    while True:
        x = beam_starts[y-1]
        beam_starts[y] = x
        while x < 2 * y: # there are some lines without beam at the begining so we limit the number of position to test even if beam is not found
            if get_status(x, y, program):
                beam_starts[y] = x
                # Are other corners of the square in the beam ?
                if y > n and get_status(x + n - 1, y, program) and get_status(x, y - n + 1, program) and get_status(x + n - 1, y - n + 1, program):
                    return Point(x, y - n + 1)
                break
            x += 1
        y += 1
Ejemplo n.º 11
0
def print_game_map(game_map):
    # type: (GameMap) -> None
    '''
    Print the game map in text mode
    '''
    if sys.platform == 'win32':
        os.system('cls')
    else:
        os.system('clear')
    symbols = [' ', '█', '░', '▬', '●']
    max_x = max([p.x for p in game_map])
    max_y = max([p.y for p in game_map])
    print(f'Score: {game_map[Point(-1, 0)]}')
    for y in range(0, max_y + 1):
        for x in range(0, max_x + 1):
            value = game_map[Point(x, y)]
            sys.stdout.write(symbols[value])
        print('')
Ejemplo n.º 12
0
def checks_d17p2():
    cells = [
        35, 35, 35, 35, 35, 35, 35, 46, 46, 46, 35, 35, 35, 35, 35, 10,
        35, 46, 46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 35, 10,
        35, 46, 46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 35, 10,
        46, 46, 46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 35, 10,
        46, 46, 46, 46, 46, 46, 35, 46, 46, 46, 35, 35, 35, 46, 35, 10,
        46, 46, 46, 46, 46, 46, 35, 46, 46, 46, 46, 46, 35, 46, 35, 10,
        35, 35, 35, 35, 35, 35, 35, 35, 35, 46, 46, 46, 35, 46, 35, 10,
        46, 46, 46, 46, 46, 46, 35, 46, 35, 46, 46, 46, 35, 46, 35, 10,
        46, 46, 46, 46, 46, 46, 35, 35, 35, 35, 35, 35, 35, 35, 35, 10,
        46, 46, 46, 46, 46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 10,
        46, 46, 46, 46, 35, 35, 35, 35, 35, 35, 35, 35, 35, 46, 46, 10,
        46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 46, 46, 46, 10,
        46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 46, 46, 46, 10,
        46, 46, 46, 46, 35, 46, 46, 46, 35, 46, 46, 46, 46, 46, 46, 10,
        46, 46, 46, 46, 35, 35, 35, 35, 35, 46, 46, 46, 46, 46, 46, 10
    ]
    system_map, _ = build_map(cells)
    vacuum_state = (Point(0, 6), ord('^'))
    instructions = generate_instructions(system_map, vacuum_state)
    assert instructions == 'R,8,R,8,R,4,R,4,R,8,L,6,L,2,R,4,R,4,R,8,R,8,R,8,L,6,L,2'
Ejemplo n.º 13
0
import ast, os
import sys
from collections import defaultdict
from typing import Dict, Tuple

from Day10 import Point
from Day9 import run_program, Program

SectionMap = Dict[Point, int]

directions = [Point(0, -1), Point(0, 1), Point(-1, 0), Point(1, 0)]
next_direction = [
    2, 3, 1, 0
]  # next_direction[i] is the direction to take if the droid hit the wall when moving in
# direction i. This keeps the wall to the right.


def print_map(section_map, droid_position):
    # type: (SectionMap, Point) -> None
    '''
    Prints the map in text mode.
    '''
    if sys.platform == 'win32':
        os.system('cls')
    else:
        os.system('clear')

    xs = [p.x for p in section_map]
    min_x, max_x = min(xs), max(xs)
    ys = [p.y for p in section_map]
    min_y, max_y = min(ys), max(ys)