in textworld/generator/world.py [0:0]
def _process_rooms(self) -> None:
for fact in self.facts:
if not self.kb.types.is_descendant_of(fact.arguments[0].type, 'r'):
continue # Skip non room facts.
room = self._get_room(fact.arguments[0])
room.add_related_fact(fact)
if fact.name.endswith("_of"):
# Handle room positioning facts.
exit = reverse_direction(fact.name.split("_of")[0])
dest = self._get_room(fact.arguments[1])
dest.add_related_fact(fact)
assert exit not in room.exits
room.exits[exit] = dest
# Handle door link facts.
for fact in self.facts:
if fact.name != "link":
continue
src = self._get_room(fact.arguments[0])
door = self._get_object(fact.arguments[1])
dest = self._get_room(fact.arguments[2])
door.add_related_fact(fact)
src.content.append(door)
exit_found = False
for exit, room in src.exits.items():
if dest == room:
src.doors[exit] = door
exit_found = True
break
if not exit_found:
# Need to position both rooms w.r.t. each other.
src_free_exits = [exit for exit in DIRECTIONS if exit not in src.exits]
for exit in src_free_exits:
r_exit = reverse_direction(exit)
if r_exit not in dest.exits:
src.exits[exit] = dest
dest.exits[r_exit] = src
src.doors[exit] = door
exit_found = True
break
# Relax the Cartesian grid constraint.
if not exit_found:
# Need to position both rooms w.r.t. each other.
src_free_exits = [exit for exit in DIRECTIONS if exit not in src.exits]
dest_free_exits = [exit for exit in DIRECTIONS if exit not in dest.exits]
if len(src_free_exits) > 0 and len(dest_free_exits) > 0:
exit = src_free_exits[0]
r_exit = dest_free_exits[0]
src.exits[exit] = dest
dest.exits[r_exit] = src
src.doors[exit] = door
exit_found = True
if not exit_found: # If there is still no exit found.
raise NoFreeExitError("Cannot connect {} and {}.".format(src, dest))