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
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()
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
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
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
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)
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()
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'
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
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
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'
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
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()
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
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())
###.#.# #.###.# 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 = {}
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)
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
def get_rotation_angle(A, B): C = Point(B.x, A.y) return asin(distance(B, C) / distance(A, B)) * 180 / pi
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':