所以,我正在制作一个基于文本的世界生成器作为业余爱好项目,我正试图找到一种方法来最小化我拥有的变量。以下是一段代码示例。
import time, random
class WorldGen(object):
def generate():
wo1 = random.randint(1, len(WO))-1
#This list of variables continues to wo38
print WO[wo1], #So on and so forth to WO[wo38]
time.sleep(0.5)
generate()
start = WorldGen()
start.generate()
基本上,我在这里问的问题是:如何以任何方式缩短38个变量的列表,例如循环或类似的东西?如果我没有提供足够的信息,请说明您可能需要了解的更多信息。以下是输出示例。
# o o o ~ * * ~
* o # ~ ~ ~ ~ ~
这不是整个输出的外观,但这是构成世界的文本的关键。 (这就是我所说的文字符号)
# = Tree
~ = Water
* = Sand
o = Land
表示单词部分的这些文本符号放在这样的列表中。
WO = ["~", "*", "o", "#"]
希望这是对文字符号的充分解释。
答案 0 :(得分:9)
每当你有编号的变量名时,请考虑使用list,tuple或dict:
def generate():
wo = list()
for i in range(38):
wo.append(random.randint(1, len(WO))-1)
print WO[wo[i]],
如果编号变量的顺序与通常一样重要,则使用元组或列表。如果对象是不可变的,请使用元组。如果需要对对象进行变异,请使用列表。
因此,在上面,您将拥有一个列表wo1
,而不是变量wo38
,...,wo
,而项目wo[0]
,..., wo[37]
。
小提示:使变量名称非常清晰。避免使用仅大写字母不同的变量名称,例如wo
和WO
。名字越相似,就越容易拥有一个高级时刻"并输入错误的一个。 data
和date
总是惹恼我。此外,编写一些在发声后很容易理解的代码也很不错 - 可能对你不重要,但对某些人来说可能非常重要。
要生成随机世界,您可以使用列表列表来保存"文本符号" (地形):
import random
terrain = ["~", "*", "o", "#"]
def generate():
""" Generate a random board represented by a list of lists """
num_rows, num_cols = 3, 38
board = [[random.choice(terrain) for col in range(num_cols)]
for row in range(num_rows)]
return board
def show(board):
print('\n'.join([' '.join(row) for row in board]))
board = generate()
show(board)
打印像
这样的东西* * # ~ * o * o o * o * # ~ * ~ * * * * * o * o ~ * ~ o ~ * * * * o o # * #
o ~ ~ # ~ # * ~ # * ~ o # o ~ # ~ * # o ~ # ~ * o * # ~ ~ o # o o ~ ~ * o ~
o # # o * o ~ # * o ~ # ~ o ~ # * ~ ~ ~ # * o * # ~ ~ * o ~ ~ o * # * # # *
上面,电路板是使用嵌套的list comprehensions生成的。
row = [random.choice(terrain) for col in range(num_cols)]
相当于
row = list()
for col in range(num_cols):
row.append(random.choice(terrain))
它主要只是一种较短的语法。
另一个小提示:我通常发现将打印语句与计算分开会更好。电路板的生成是一个计算。电路板的印刷应在其他地方进行。我使用show
函数打印电路板,generate
生成电路板。这种职责分离将在重构代码时提供更大的灵活性,并且可以更好地控制何时执行这些操作。
要生成无限数量的行,我会使用generator function:
import random
import time
terrain = ["~", "*", "o", "#"]
def generate():
""" Generate a random board represented by a list of lists """
num_cols = 38
while True:
yield [random.choice(terrain) for col in range(num_cols)]
def show(board):
for row in generate():
print(' '.join(row))
time.sleep(0.5)
board = generate()
show(board)
更简单的方法是在while循环中调用print
:
while True:
print(' '.join([random.choice(terrain) for col in range(num_cols)]))
但是在颂扬将计算与印刷分开的优点之后,我觉得有必要向您展示发电机功能解决方案。
答案 1 :(得分:2)
想要它的人的源代码:
# -*- coding: utf-8
#Infinite world generator
#Thanks to unutbu for the concepts shown here.
import random, time, console
terrain = ["*", "#", "~", "~", "~", "o", "o", "o",
"*", "~", "~", "~", "~", "o", "o", "o",
"*", "~", "~", "~", "~", "o", "o", "o"]
def generate():
num_cols = 30
while True:
yield [random.choice(terrain) for col in range(num_cols)]
def show(board):
for row in generate():
print "|", (' '.join(row)), "|"
time.sleep(0.6)
def key():
print "Key:"
print "o = Landmass"
print "# = Tree"
print "* = Sand"
print "~ = Water"
def menu():
print "InfWorldGen v1.0.1"
print "Type gen."
start = raw_input("> ")
if start == "gen":
console.clear()
key()
print "[" + "=" * 61 + "]"
board = generate()
show(board)
menu()
感谢大多数概念的unutbu。
答案 2 :(得分:0)
@unutbu这是一个更短的方法,但它仍然做同样的事情:
import random, time
terrain = [
"#", "o", "~", "*"
]
while True:
world_tile = random.randint(1, len(terrain))-1
print terrain[world_tile],
time.sleep(0.1)
答案 3 :(得分:0)
这是一种甚至更短的方法。
import random
while True:
print(' '.join([random.choice(['#','o','~','*'])),
它无缝地工作,只有三行代码。