Reputation: 130
I'd like to create a building map of sorts where each room has dictionary containing a north, south, east and west populated from rooms randomly picked from a list (think old school text adventures).
So as an example:
random_rooms = [class_room,hall,entrance]
room_A.directions = {"North":random.choice(random_rooms),"East":random.choice(random_rooms),"South":random.choice(random_rooms),"West":random.choice(random_rooms)}
However, I'd like to populate that so that it matches up as a building would. So if room_A is set first, and has room_B set to the north, then room_B has room_A placed south.
So:
room_A.directions = {"North":room_B,"East":None,"South":None,"West":None}
room_B.directions = {"North":None,"East":None,"South":room_A,"West":None}
I'm not sure what the best way to go about this. I'm not worried about what order things are placed, just as long as a room doesn't end up being both to the North AND South of another room.
Upvotes: 0
Views: 1520
Reputation: 111
You might want to have a matrix encodes coordinates of roomA
, roomB
,...etc. In this way their relative location can be defined as-is so you don't need to worry about collisions. For example:
import numpy as np
rooms = np.arange(4) # 0, 1, 2, 3 stands for 4 rooms/roometypes/whatever
room_arrangement = np.random.shuffle(tmp).reshape(2,2) # reshape into a 2x2 grid
Rooms allocated into room_arrangement
, use the numbers to refer to room objects or strings. If you need the rooms be arrange sparsely i.e. they can scatter to anywhere, plug some 0 into the rooms
array, and change the next line to reshape(m, n)
where m*n==np.sum(rooms.shape)
.
btw it's a good idea to check out how people model Go game as matrices. Basics are the same as above: 1) define the ground board you are going to work on, 2) plug labels into the ground board, 3)when necessary, link the labels to objects you are interested in (simple case: dictionary, dataframe entries; slight complicated case: define classes). Generally data are encoded in the matrices, and dictionary/class instances handle the metadata/special rules part.
Upvotes: 1
Reputation: 559
This seems like a great time to start using classes. With a class you will be able to handle whats connected to each room, and through which direction. Heres a simple example.
class Room(object):
def __init__(self, name=None):
self.name = str(name)
self.matching_direction = { "N": "S", "S": "N", "W": "E", "E": "W"}
self.open_walls = ["N", "S", "E", "W"]
self.connected_rooms = {}
def connect_room(self, room_obj=None, room_obj_exit=None):
"""
Connect two rooms if able.
Params:
room_obj: Room(Object)
room_obj_exit: Direction(String)
Return: Bool
"""
try:
opposite_direction = self.matching_direction[room_obj_exit]
if opposite_direction not in self.open_walls:
print "{} door is occupied by {}".format(opposite_direction, self.connected_rooms[opposite_direction].name)
return False
if room_obj_exit not in room_obj.open_walls:
print "{} is occupied by {}".format(room_obj_exit, room_obj.connected_rooms[room_obj_exit].name)
return False
self.connected_rooms[opposite_direction] = room_obj
room_obj.connected_rooms[room_obj_exit] = self
self.open_walls.remove(opposite_direction)
room_obj.open_walls.remove(room_obj_exit)
return True
except Exception as e:
print e
return False
def explore_door(self, direction=None):
"""
Try to move to another Room
Return : Room(Object)
"""
try:
if direction in self.connected_rooms:
print "The {} Door is open to {}".format(direction, self.connected_rooms[direction].name)
return self.connected_rooms[direction]
else:
print "The {} Door is locked".format(direction)
except Exception as e:
print e
return False
Here some usage:
room_one = Room(name="Room One")
room_two = Room(name="Room Two")
room_three = Room(name="Room Three")
room_one.connect_room(room_obj=room_two, room_obj_exit="N")
room_two.connect_room(room_obj=room_three, room_obj_exit="E")
room_three.connect_room(room_obj=room_one, room_obj_exit="S")
room_one.explore_door(direction="N")
room_one.explore_door(direction="S")
room_one.explore_door(direction="E")
room_one.explore_door(direction="W")
Output:
S is occupied by Room Two
The N Door is locked
The S Door is open to Room Two
The E Door is locked
The W Door is locked
Upvotes: 0
Reputation: 427
It sounds like what you are actually looking for is more of a coordinate mapping system than a directional map. For this you want to create a grid array. Your array would then consist of your layout (e.g. a 4x4 grid area could either be a 4x4 matrix, or a simple 16 unit array).
Assuming an #x# matrix:
If room[0][3] = random.choice(random_rooms) your only concern would be to make sure that all rooms are connected (add a pass filter to go back over and if [0][0] for example == a valid room, than [0][1] must, or [1][0] must, which would fill in the gaps connecting all rooms.
Upvotes: 0