+class Room:
+ def __init__(self, coordinates, region):
+ """
+ """
+ self.coordinates = [coordinates]
+ self.region = region
+ self.max_connections = 1
+ self.passages = []
+ self.tunnels = []
+
+ def is_linked(self):
+ """
+ Check if the room is linked to another room
+ :return: Whether the room has any links or not
+ """
+ return len(self.passages) + len(self.tunnels) > 0
+
+ def add_coords(self, coordinates):
+ """
+ Add a new region into an existing room
+ :param coordinates: region coordinates to be added to room
+ :return:
+ """
+ self.coordinates.append(coordinates)
+
+ def connect_rooms(self, other_rooms):
+ """ Find the nearest rooms to this room
+ :param other_rooms: list of Rooms objects that we are searching
+ :return:
+ """
+ distance = []
+ other_tile = []
+ this_tile = []
+ target_rooms = []
+ for coord in self.coordinates:
+ for room in other_rooms:
+ if self == room:
+ continue
+ for new_coord in room.coordinates:
+ distance.append(
+ math.sqrt((coord[0] - new_coord[0]) ** 2 +
+ (coord[1] - new_coord[1]) ** 2))
+ other_tile.append(new_coord)
+ this_tile.append(coord)
+ target_rooms.append(room)
+
+ sorted_indices = [i[0] for i in sorted(enumerate(distance),
+ key=lambda x:x[0])]
+ for index in sorted_indices:
+ if len(self.passages) + len(self.tunnels) >= self.max_connections:
+ break
+ if not target_rooms[index].is_linked():
+ self.link_passage(this_tile[index], other_tile[index])
+ target_rooms[index].link_passage(
+ other_tile[index], this_tile[index])
+
+ def link_passage(self, local_tile, foreign_tile):
+ """ Link a passage between two rooms
+ :param local_tile: tile in this room to which we wish to link
+ :param foreign_tile: tile in another room to which we wish to link
+ :return:
+ """
+ self.passages.append([local_tile, foreign_tile])
+
+ def render_region(self, coords, room_dist, region_size, tile_map, x, y):
+ """ Check if a region is in this room and return the required tiles
+ :param coords: Coordinates of the region that we wish to render
+ :param room_dist: Tile separation distance from other rooms
+ :param region_size: Region size in tiles
+ :param tile_map: Tile map to update
+ :param x: X coordinate
+ :param y: Y coordinate
+ :return:
+ """
+ if coords in self.coordinates:
+ x_pre_room_dist = room_dist
+ x_post_room_dist = region_size - room_dist
+ y_pre_room_dist = room_dist
+ y_post_room_dist = region_size - room_dist
+ if [x - 1, y] in self.coordinates:
+ y_pre_room_dist = 0
+ if [x + 1, y] in self.coordinates:
+ y_post_room_dist = region_size
+ if [x, y - 1] in self.coordinates:
+ x_pre_room_dist = 0
+ if [x, y + 1] in self.coordinates:
+ x_post_room_dist = region_size
+
+ for ht in range(y_pre_room_dist, y_post_room_dist):
+ for wt in range(x_pre_room_dist, x_post_room_dist):
+ tile_map[(x * region_size) + ht][(y * region_size) + wt] =\
+ str(self.region)
+ for p in self.passages:
+ print(p)
+ x_regions = p[0][0] - p[1][0]
+ y_regions = p[0][1] - p[1][1]
+ if p[0][0] < p[1][0]:
+ x_direction = -1
+ elif p[0][0] < p[1][0]:
+ x_direction = 0
+ else:
+ x_direction = 1
+ if p[0][1] < p[1][1]:
+ y_direction = -1
+ elif p[0][1] < p[1][1]:
+ y_direction = 0
+ else:
+ y_direction = 1
+ for ht in range(0, region_size, x_direction):
+ tile_map[(p[0][0] * region_size) + int(region_size / 2)]\
+ [(p[0][1] * region_size) + int(region_size / 2) + ht] = 'p'
+ for wt in range(0, y_regions, y_direction):
+ tile_map[(p[0][0] * region_size) + int(region_size / 2) + wt]\
+ [(p[0][1] * region_size) + int(region_size / 2)] = 'p'
+
+
+def random_cardinal():
+ """Return a random cardinal direction for random walks."""
+ return random.choice([(0, 1), (0, -1), (1, 0), (-1, 0)])
+
+