Reputation: 43
I've got a function that builds a random number of object instances. For the sake of demonstrating the general idea, we're going to pretend that this is an algorithm to build a series of nethack-like rooms.
The requirements are such that I won't know how many instances there will be in advance; these are generated randomly and on-the-fly.
As a brief note: I am fully aware that the following code is nonfunctional, but it should (hopefully!) demonstrate my aims.
import random
class Levelbuild(object):
def __init__(self):
self.l1 = dict({0:'a',1:'b',2:'c',3:'d',4:'e',5:'f',6:'g',7:'h',8:'i'})
# Pick a random number between 4 and 9.
for i in range(random.randint(4,9)):
self.l1[i] = Roombuilder()
If we assume that the chosen random integer is 5, the ideal result would be 5 Roombuilder() instances; labeled a, b, c, d, and e, respectively.
Is there a simple way of doing this? Is there a way to do this period?
--Edit--
A giant "thank you" to Nick ODell for his answer. This isn't a complete copy/paste-- but it's a variation that works for what I need;
import random
class Room(object):
def __init__(self):
self.size = (5,5)
class Level(object):
def __init__(self):
roomnames = ['a','b','c','d','e','f','g','h','i']
self.rooms = {}
for i in range(random.randint(4, 9)):
self.rooms[roomnames[i]] = Room()
Rather than build each "room" by hand, I can now...
test = Level()
print test.rooms['a'].size
>>> (5,5)
Upvotes: 3
Views: 672
Reputation: 88987
As another answer for a more general solution (mainly as a companion to Nick ODell's answer, if you want to handle any number of names, it's a pretty simply solution with an infinite generator:
import string
import itertools
def generate_names(characters):
for i in itertools.count(1):
for name in itertools.product(characters, repeat=i):
yield "".join(name)
You can then use it as you would any other generator:
>>>print(dict(zip(generate_names(string.ascii_lowercase), range(30))))
{'aa': 26, 'ac': 28, 'ab': 27, 'ad': 29, 'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 12, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v': 21, 'y': 24, 'x': 23, 'z': 25}
If you need to generate actual names, then you have a few choices. If you need a real word, pick from a dictionary file (most Linux users have one in /usr/share/dict
). If you need word-like things, then I have actually written a Python script to generate such 'words' using Markov Chains, which is available under the GPL. Naturally, you'd have to check these for uniqueness.
Upvotes: 0
Reputation: 25220
import string
import random
class Levelbuild(object):
def __init__(self,min_room_count,max_room_count):
rooms_temp = [new RoomBuilder() for i in range(random.randint(min_room_count,max_room_count))]
self.l1 = dict(zip(string.ascii_lowercase, rooms_temp))
Note: This will fail silently if given more than 26 rooms.
Upvotes: 3
Reputation: 48546
You're pretty close, actually. You don't need a dict; just use a list. (And, by the way, {...}
is already a dict, so wrapping it in dict()
doesn't do anything.)
roomnames = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
self.rooms = []
for i in range(random.randint(4, 9)):
self.rooms.append(Roombuilder(roomnames[i]))
For what it's worth, putting builder
in the name of a class is kind of funky. The objects are rooms, right? So the type should just be Room
.
Upvotes: 0