def order_graph(): """Creates an item order graph, which is an order in which the items may be picked up and a set of tentative paths to do that""" g = basicgraph.BasicGraph() order = item_order.order() g.add_node("START") current = "START" current_items = item_set.ItemSet() for item_name in order: # first, BFS from current to find a candidate entrance finished, offers = g.BFS(current) # Choose the entrance at random entrance = random.choice(list(finished)) path = basicgraph.bfs_path(offers, current, entrance) # Add items along the path for a, b in pairwise(path): g.update_edge_lambda(a, b, [current_items.copy()], operator.add) # Choose the exit at random from among the existing nodes exit = random.choice(list(g.nodes.keys())) # Add the new node g.add_node(item_name) g.add_edge(entrance, item_name, data=[current_items.copy()]) current_items = current_items.add(item_name) g.add_edge(item_name, exit, data=[current_items.copy()]) return order, g
def embed_room_graph(room_graph, subroom_graph, min_entrance_size, max_entrance_size): """Embed the room graph into the subroom graph, resulting in a new graph which is the graph that will actually be searched over during subroom generation.""" # Key - subroom_id, value - list of nodes belonging to that subroom # Used to create a subgraph when building the subroom subroom_nodes = collections.defaultdict(list) # The subrooms which the graph embedding actually uses # Used to calculate the subrooms which are completely unused. used_subrooms = set() g = basicgraph.BasicGraph() for node1, node2 in room_graph.get_edges(): itemset = room_graph.get_edge_data(node1, node2) #TODO: randomized DFS? finished, offers = subroom_graph.DFS(node1, node2) path = basicgraph.bfs_path(offers, node1, node2) current_node = None for first, second in zip(path, path[1:]): if first in room_graph: # First is an obstacle node # Copy the data: the rectangle of actual tiles that this obstacle represents #TODO: might only want the last two entries: the target squares if first not in g: g.add_node(first, data=subroom_graph.nodes[first].data) current_node = first elif second in room_graph: # Second is an obstacle node if second not in g: g.add_node(second, data=subroom_graph.get_data[second]) current_node = second else: # edge between two subroom nodes edge_fs = subroom_graph.get_edge_data(first, second) edge_sf = subroom_graph.get_edge_data(second, first) fs_name = str(first) + "-" + str(second) sf_name = str(second) + "-" + str(first) # Add a node for the exit to the old subroom and the entrance to the new one if fs_name not in g: # subroom interface nodes should only be added two at a time assert sf_name not in g # Choose a place to break the wall between the two subrooms #TODO: Decide the type of each entrance based on what items are available e = edge_fs.add_entrance(min_entrance_size, max_entrance_size) # Create a node in the first subroom g.add_node(fs_name, data=e) subroom_nodes[first].append(fs_name) used_subrooms.add(first) # Create a node in the second subroom g.add_node(sf_name, data=e) subroom_nodes[second].append(sf_name) used_subrooms.add(second) # Regardless of what type of node, connect them up # TODO: update edge append instead! g.add_edge_append(current_node, fs_name, data=itemset) g.add_edge_append(fs_name, sf_name, data=itemset) current_node = fs_name return g, subroom_nodes, used_subrooms
def __init__(self, start_subroom, walls, obstacles): #TODO: how to represent cross-room adjacencies? #TODO: are "walls" actually used? self.subroom_id_counter = 0 self.recycle_ids = [] self.walls = walls self.obstacles = obstacles self.g = basicgraph.BasicGraph() self.new_subroom(start_subroom)
def __init__(self, cmap, size, room_id, pos, graph=None): self.enemies = [] self.plms = [] self.doors = [] self.items = [] if graph is None: self.graph = basicgraph.BasicGraph() else: self.graph = graph self.cmap = cmap self.size = size self.room_id = room_id self.pos = pos self.up_scroll = 0x70 self.down_Scroll = 0xa0
def subroom_adjacency_graph(subroom_leaves): g = basicgraph.BasicGraph() # Add a node for each subroom and each obstacle that holds the target region of the obstacle for leaf in subroom_leaves: leaf_name = str(leaf.id) g.add_node(leaf_name) # Add an edge between each obstacle and the leaf that contains it. for o in leaf.obstacles: g.add_node(o.name, data=o) g.add_edge(leaf_name, o.name) g.add_edge(o.name, leaf_name) # Once all the subrooms have been added, produce the adjacencies for leaf in subroom_leaves: for neighbor_adj in leaf.adj: leaf_name = str(leaf.id) other_name = str(neighbor_adj.get_other_id(leaf.id)) g.add_edge(leaf_name, other_name, data=neighbor_adj) return g