Ejemplo n.º 1
0
def teleporting_bomb(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    damage_radius = kwargs.get('damage_radius')
    target_coord = Point(kwargs.get('target_coordinates'))
    target_tile = kwargs.get('target_tile')

    results = []

    if not target_tile.explored:
        results.append({
            'consumed':
            False,
            'message':
            Message("You cannot target a tile you haven't explored yet.",
                    libtcod.yellow)
        })
        return results

    if libtcod.map_is_in_fov(fov_map, target_coord.x, target_coord.y):
        results.append({
            'consumed':
            True,
            'message':
            Message(
                f'The teleporting bomb explodes in a radius of {damage_radius} tiles!',
                libtcod.orange)
        })

    else:
        results.append({
            'consumed':
            True,
            'message':
            Message(f'You hear a distant explosion!', libtcod.orange)
        })

    for entity in [x for x in entities if x.fighter]:
        distance = target_coord.distance_to(entity.get_coordinates())
        if distance <= damage_radius:
            # 4 : decay constant
            # TODO: put into a constant file OR pass it as an argument
            final_damage = int(
                round(damage / (1 + (distance * 4 / damage_radius))))
            if libtcod.map_is_in_fov(fov_map, entity.x, entity.y):
                results.append({
                    'message':
                    Message(
                        f'The {entity.name} gets burned for {final_damage} hit points.',
                        libtcod.orange)
                })
            results.extend(entity.fighter.take_damage(final_damage))

    return results
Ejemplo n.º 2
0
def turtle_art(data):
    scaled_data = rescale(data)
    biggest_x = max([len(x) for x in data])
    x_scale = DISPLAY_SIZE_X / biggest_x

    playground = turtle.Screen()
    turtly = turtle.Turtle(visible=False)

    playground.screensize(DISPLAY_SIZE_X, DISPLAY_SIZE_Y)
    turtly.speed('fastest')

    origin = Point(-DISPLAY_SIZE_X / 2, -DISPLAY_SIZE_Y / 2)

    pt = origin
    length_pt = Point(0, 0)

    for curve_number, curve in enumerate(scaled_data):
        print(f'Drawing curve n°{curve_number}/{len(scaled_data)}', end='\r')
        length_multiplier = 1

        turtle.tracer(0, 0)
        turtly.penup()
        turtly.setpos(origin.x, origin.y)
        turtly.pendown()
        pt = origin

        for i, y in enumerate(curve):
            last_pt = pt
            last_length_pt = length_pt
            pt = Point(i * x_scale + origin.x,
                       data[curve_number][i] + origin.y)
            length_pt = Point(i * x_scale + origin.x, y + origin.y)

            length = distance(length_pt, last_length_pt) * length_multiplier

            rotation_angle = get_rotation_angle(last_pt, pt)

            if int(data[curve_number][i]) % 2 == 0:
                rotation_angle *= 1
                turtly.left(rotation_angle)
                turtly.forward(length)
                turtly.right(rotation_angle)
            else:
                rotation_angle *= 2
                turtly.right(rotation_angle)
                turtly.forward(length)
                turtly.left(rotation_angle)

            length_multiplier *= 0.999999

        turtle.update()

    print('')
    print('Done !')
    playground.exitonclick()
Ejemplo n.º 3
0
def guided_rocket(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    damage = kwargs.get('damage')
    damage_radius = kwargs.get('damage_radius')
    target_coor = Point(kwargs.get('target_coordinates'))

    results = []

    if not libtcod.map_is_in_fov(fov_map, target_coor.x, target_coor.y):
        results.append({
            'consumed':
            False,
            'message':
            Message('You cannot target a tile outside your field of view.',
                    libtcod.yellow)
        })
        return results

    results.append({
        'consumed':
        True,
        'message':
        Message(
            f'The guided rocket explodes in a radius of {damage_radius} tiles!',
            libtcod.orange)
    })

    for entity in [x for x in entities if x.fighter]:
        distance = target_coor.distance_to(entity.get_coordinates())
        if distance <= damage_radius:
            # 4 : decay constant
            # TODO: put into a constant file OR pass it as an argument
            final_damage = int(
                round(damage / (1 + (distance * 4 / damage_radius))))
            if libtcod.map_is_in_fov(fov_map, entity.x, entity.y):
                results.append({
                    'message':
                    Message(
                        f'The {entity.name} gets burned for {final_damage} hit points.',
                        libtcod.orange)
                })
            results.extend(entity.fighter.take_damage(final_damage))

    return results
Ejemplo n.º 4
0
    def get_possible_movement(self, actor):
        possible_movement = []
        # This is done so tiles can be highlighted in amber for allies
        # and red for enemies
        actors_position = {(p.x, p.y): p for p in self.actors}

        if actor.movement_left == 0 and not actor.has_attacked:

            to_check =[Point(x+actor.x, y+actor.y) for x in range(-1,2) for y in range(-1,2)
                                                   if ((x != 0 or y != 0) and dst_euc(Point(x,y)) <= 1)]

            for tc in to_check:

                if ((tc.x, tc.y) in actors_position.keys()):
                    if actors_position[(tc.x, tc.y)].blocks:
                        if actors_position[(tc.x, tc.y)].team != actor.team:
                            possible_movement.append({'mov': tc, 'valid':'enemy'})

            return possible_movement



        # compute the possible movement
        possible_movement = [Point(x+actor.x, y+actor.y) for x in range(-actor.movement_left, actor.movement_left+1)
                                                         for y in range(-actor.movement_left, actor.movement_left+1)
                                                         if ((x != 0 or y != 0) and dst_euc(Point(x,y)) <= actor.movement_left)]

        # Eliminate out of bounds movements
        possible_movement = [{'mov':pm, 'valid':'true'} for pm in possible_movement
                             if (pm.x > -1 and pm.x < self.gamemap.w
                             and pm.y > -1 and pm.y < self.gamemap.h)]

        for pm in possible_movement:

            x = pm['mov'].x
            y = pm['mov'].y

            if ((x, y) in actors_position.keys()):
                if actors_position[(x, y)].blocks:
                    if actors_position[(x, y)].team != actor.team:
                        pm['valid'] = 'enemy'
                    else:
                        pm['valid'] = 'false'

        return possible_movement
Ejemplo n.º 5
0
    def check_under_mouse(self):
        self.under_mouse = None

        mx = blt.state(blt.TK_MOUSE_X)
        my = blt.state(blt.TK_MOUSE_Y)
        off_mouse = Point(floor((mx / TERRAIN_SCALE_X) - self.map_offset.x),
                                     floor((my / TERRAIN_SCALE_Y) - self.map_offset.y))

        for a in self.actors:
            if a != self.unit_turn and a.x == off_mouse.x and a.y == off_mouse.y:
                self.under_mouse = a
Ejemplo n.º 6
0
 def __init__(self, source):
     if not isinstance(source, str):
         source = source.read()
     maze = []
     self.adit = []
     for ln in source.splitlines():
         maze.append(list(ln.strip()))
         for i, ch in enumerate(ln):
             if ch == '@':
                 self.adit.append(Point(i, len(maze) - 1))
     self.maze = maze
     self.size = len(maze)
Ejemplo n.º 7
0
def part1():
    ship = Point(0, 0)
    facing = deltas['E']
    for ln in data:
        direc = ln[0]
        dist = int(ln[1:])
        if direc in 'NESW':
            ship += deltas[direc] * dist
        elif direc in 'L':
            count = dist // 90
            for i in range(count):
                facing = facing.left()
        elif direc in 'R':
            count = dist // 90
            for i in range(count):
                facing = facing.right()
        elif direc == 'F':
            ship += facing * dist
        if DEBUG:
            print(ln, ship)
    return ship.mandist()
Ejemplo n.º 8
0
    def mouse_check(self, coordinates):
        # Useful for map related stuff
        offseted_coordinates = Point(floor((coordinates[0] / TERRAIN_SCALE_X) - self.map_offset.x),
                                     floor((coordinates[1] / TERRAIN_SCALE_Y) - self.map_offset.y))

        # Moving on an empty case if there are some movement left
        if self.unit_turn.movement_left > 0 and point_in(offseted_coordinates, [x['mov'] for x in self.highlighted_cases if x['valid'] == 'true']):

            self.unit_turn.movement_left -= dst_man(Point(self.unit_turn.x, self.unit_turn.y),
                                                    Point(offseted_coordinates.x,  offseted_coordinates.y))

            message = f'Moved from {chr(self.unit_turn.x + 65)}{self.unit_turn.y} to {chr(offseted_coordinates.x + 65)}{offseted_coordinates.y}'

            self.unit_turn.x = offseted_coordinates.x
            self.unit_turn.y = offseted_coordinates.y

            self.message_queue.append(message)

        # Attacking an enemy
        elif point_in(offseted_coordinates, [x['mov'] for x in self.highlighted_cases if x['valid'] == 'enemy']):
            other_actor = [a for a in self.actors if Point(a.x, a.y) == offseted_coordinates][0]

            # If we're close enough
            if dst_man(Point(self.unit_turn.x, self.unit_turn.y), Point(other_actor.x, other_actor.y)) == 1:
                self.message_queue.append(self.unit_turn.attack(other_actor))

                # The unit lose half (floored) of its remaining movement
                self.unit_turn.movement_left = floor(self.unit_turn.movement_left / 2)

        # Ending turn
        elif coordinates in [(x, TERMINAL_SIZE_Y - 6) for x in range(TERMINAL_SIZE_X - 8, TERMINAL_SIZE_X)]:
            self.game_state = 'end_turn'
Ejemplo n.º 9
0
    def return_data_as_points(self, rescaled=False):
        list_of_points = []

        data_to_use = self.all_curves
        x_scale_to_use = self.x_scale

        if rescaled:
            data_to_use = self.rescaled_curves
            x_scale_to_use = self.rescaled_x_scale

        for curve in data_to_use:
            curve_as_points = []
            for i, pt in enumerate(curve):
                curve_as_points.append(Point(x_scale_to_use[i], pt))
            list_of_points.append(curve_as_points)

        return list_of_points
Ejemplo n.º 10
0
def confuse(*args, **kwargs):
    caster = args[0]
    entities = kwargs.get('entities')
    fov_map = kwargs.get('fov_map')
    target_coord = Point(kwargs.get('target_coordinates'))

    results = []

    if not libtcod.map_is_in_fov(fov_map, target_coord.x, target_coord.y):
        results.append({
            'consumed':
            False,
            'message':
            Message(f"You cannot target a tile you haven't explored yet.",
                    libtcod.orange)
        })
        return results

    for entity in entities:
        if entity.ai and entity.x == target_coord.x and entity.y == target_coord.y:
            confused_ai = ConfusedAI(entity.ai, 10)
            confused_ai.owner = entity
            entity.ai = confused_ai

            results.append({
                'consumed':
                True,
                'message':
                Message(f"The {entity.name} starts behaving weirdly...",
                        libtcod.violet)
            })
            break

    else:
        results.append({
            'consumed':
            False,
            'message':
            Message(f"There's no targetable entity at this location.",
                    libtcod.orange)
        })

    return results
Ejemplo n.º 11
0
    def __init__(self, gamemap=GameMap()):
        self.actors = []
        self.turn_to_take = []

        self.gamemap = gamemap
        self.highlighted_cases = []

        self.event_queue = []
        self.message_queue = []

        self.unit_turn = None

        self.re_render = True

        self.under_mouse = None

        self.map_offset = Point(MAP_PANEL.x, MAP_PANEL.y)

        self.init_game()

        self.game_state = 'menu'
        self.game_state = 'playing'
Ejemplo n.º 12
0
    def take_turn(self, target, fov_map, game_map, entities):
        results = []

        m = self.owner

        if self.number_of_turns > 0:
            random_x = m.x + randint(0, 2) - 1
            random_y = m.y + randint(0, 2) - 1

            if random_x != m.x and random_y != m.y:
                m.move_towards(Point(random_x, random_y), game_map, entities)

            self.number_of_turns -= 1

        else:
            m.ai = self.previous_ai
            results.append({
                'message':
                Message(f'The {m.name} is no longer confused.', libtcod.red)
            })

        return results
Ejemplo n.º 13
0
def part2():
    ship = Point(0, 0)
    waypt = Point(10, -1)
    for ln in data:
        direc = ln[0]
        dist = int(ln[1:])
        if direc in 'NESW':
            waypt += deltas[direc] * dist
        elif direc in 'L':
            count = dist // 90
            for i in range(count):
                waypt = waypt.left()
        elif direc in 'R':
            count = dist // 90
            for i in range(count):
                waypt = waypt.right()
        elif direc == 'F':
            ship += waypt * dist
        if DEBUG:
            print(ln, ship, waypt)
    return ship.mandist()
Ejemplo n.º 14
0
    def __init__(self, source):
        if not isinstance(source, str):
            source = source.read()
        maze = [ln for ln in source.splitlines()]

        self.maze = maze
        self.w = w = len(maze[3])
        self.h = h = len(maze)

        gates = {}
        paths = {}

        for y in range(h):
            for x in range(w):
                if maze[y][x] == '.':
                    for check in (maze[y][x - 2:x], maze[y][x + 1:x + 3],
                                  maze[y - 2][x] + maze[y - 1][x],
                                  maze[y + 1][x] + maze[y + 2][x]):
                        if check.isalpha():
                            pt = Point(x, y)
                            print(check, pt)
                            if check in gates:
                                paths[pt] = gates[check]
                                gates[pt] = check
                                paths[gates[check]] = pt
                            else:
                                gates[check] = pt
                                gates[pt] = check

        self.gates = gates
        self.paths = paths
        self.start = self.gates['AA']
        self.goal = self.gates['ZZ']

        self.outer = set(pt for pt in paths
                         if (pt.x in (2, w - 3) or pt.y in (2, h - 3)))
        self.inner = set(self.paths) - self.outer
Ejemplo n.º 15
0
from tools import eval
import time


def minDist(arr, n):
    if (n == 1): return -1
    min = eval(arr[0], arr[1])
    for i in range(n):
        for j in range(n):
            if min > eval(arr[i], arr[j]) and i != j:
                min = eval(arr[i], arr[j])
    return min


n = int(input("size of array: "))
array = []
for i in range(n):
    x = num.random.rand(2) * 100
    A = Point(x[0], x[1])
    array.append(A)
    for j in range(len(array)):
        temp = array[j]
        cur = array[i]
        if cur.x < temp.x:
            array[j] = cur
            array[i] = temp

print("%.8f" % minDist(array, n))
print(time.process_time_ns())
print(time.process_time())
Ejemplo n.º 16
0
  ###.#.#                           #.###.#  
RE....#.#                           #......RF
  ###.###        X   X       L      #.#.#.#  
  #.....#        F   Q       P      #.#.#.#  
  ###.###########.###.#######.#########.###  
  #.....#...#.....#.......#...#.....#.#...#  
  #####.#.###.#######.#######.###.###.#.#.#  
  #.......#.......#.#.#.#.#...#...#...#.#.#  
  #####.###.#####.#.#.#.#.###.###.#.###.###  
  #.......#.....#.#...#...............#...#  
  #############.#.#.###.###################  
               A O F   N                     
               A A D   M                     
"""

movements = (Point(0, -1), Point(0, 1), Point(-1, 0), Point(1, 0))

# Find the key points.


class Maze(object):
    def __init__(self, source):
        if not isinstance(source, str):
            source = source.read()
        maze = [ln for ln in source.splitlines()]

        self.maze = maze
        self.w = w = len(maze[3])
        self.h = h = len(maze)

        gates = {}
Ejemplo n.º 17
0
    def make_map(self, max_rooms, room_min_size, room_max_size, map_width,
                 map_height, player, entities):
        self.rooms = []
        num_rooms = 0

        center_last_room = Point()

        for r in range(max_rooms):
            # random width and height
            w = randint(room_min_size, room_max_size)
            h = randint(room_min_size, room_max_size)
            # random position without going out of the boundaries of the map
            x = randint(0, map_width - w - 1)
            y = randint(0, map_height - h - 1)

            # "Rect" class makes rectangles easier to work with
            new_room = Rect(x, y, w, h)

            # run through the other rooms and see if they intersect with this one
            for other_room in self.rooms:
                if new_room.intersect(other_room):
                    break

            else:
                # this means there are no intersections, so this room is valid

                # "paint" it to the map's tiles
                self.create_room(new_room)

                # center coordinates of new room, will be useful later
                (new_x, new_y) = new_room.center()

                center_last_room = Point(new_x, new_y)

                if num_rooms == 0:
                    # this is the first room, where the player starts at
                    player.x = new_x
                    player.y = new_y

                else:
                    # all rooms after the first:
                    # connect it to the previous room with a tunnel

                    # center coordinates of previous room
                    (prev_x, prev_y) = self.rooms[num_rooms - 1].center()

                    # flip a coin (random number that is either 0 or 1)
                    if randint(0, 1) == 1:
                        # first move horizontally, then vertically
                        self.create_h_tunnel(prev_x, new_x, prev_y)
                        self.create_v_tunnel(prev_y, new_y, new_x)
                    else:
                        # first move vertically, then horizontally
                        self.create_v_tunnel(prev_y, new_y, prev_x)
                        self.create_h_tunnel(prev_x, new_x, new_y)

                # finally, append the new room to the list
                self.rooms.append(new_room)
                num_rooms += 1

        stairs_comp = Stairs(self.current_level + 1)
        down_stairs = Entity('Stairs',
                             center_last_room.x,
                             center_last_room.y,
                             '>',
                             libtcod.white,
                             render_order=RenderOrder.STAIRS,
                             stairs=stairs_comp)
        entities.append(down_stairs)
Ejemplo n.º 18
0
def part1():
    # Find the robot.

    robot = Point(maze.maze[-1].find('^'), len(maze.maze)-1)
    lastturn = robot

    # Robot starts facing north.

    facing = Point(0,-1) 

    crossings = set()
    turns = []
    while 1:
        #  If we are facing empty space, turn.
        if maze[robot+facing] == '.':
            if robot != lastturn:
                turns.append( robot.dist(lastturn) )
            if maze[robot+facing.left()] == '#':
                facing = facing.left()
                turns.append( "L" )
            elif maze[robot+facing.right()] == '#':
                facing = facing.right()
                turns.append( "R" )
            else:
                # End of the scaffold.
                break
            lastturn = robot
            robot += facing

        # Otherwise, look for a crossing.
        else:
            if maze[robot+facing.left()] == '#' and maze[robot+facing.right()] == '#':
                crossings.add( robot )
            robot += facing

        if TRACE:
            print( robot )
    # We return the set of crossings and the record of turns.
    return crossings, turns
Ejemplo n.º 19
0
def get_rotation_angle(A, B):
    C = Point(B.x, A.y)
    return asin(distance(B, C) / distance(A, B)) * 180 / pi
Ejemplo n.º 20
0
N3
F7
R90
F11""".splitlines()

from pprint import pprint

DEBUG = 'debug' in sys.argv

if 'test' in sys.argv:
    data = test
else:
    data = open('day12.txt').read().split('\n')[:-1]

deltas = {
    'N': Point(0, -1),
    'E': Point(1, 0),
    'S': Point(0, 1),
    'W': Point(-1, 0)
}

# N and E are negative.


def part1():
    ship = Point(0, 0)
    facing = deltas['E']
    for ln in data:
        direc = ln[0]
        dist = int(ln[1:])
        if direc in 'NESW':