Python 尝试生成5个随机项目,有时生成4个 随机导入 twoDimMap=[“H”、“-”、“-”、“-”、“-”、“-”]、[“-”、“-”、“-”、“-”、“-”、“-”], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"]] 项目=0 而items
有时Python 尝试生成5个随机项目,有时生成4个 随机导入 twoDimMap=[“H”、“-”、“-”、“-”、“-”、“-”]、[“-”、“-”、“-”、“-”、“-”、“-”], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"]] 项目=0 而items,python,random,Python,Random,有时randrange(0,5)会多次返回相同的内容,因此会重新分配某个点 这可以通过与类型一起生成坐标并仅在该点当前未被占用时执行循环的其余部分来解决。这也将消除对单独(0,0)测试用例的需要。您只检查播放器是否被覆盖,而不是对象是否被覆盖,您应该首先获得随机坐标,然后检查是否有内容 import random twoDimMap = [["H", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"], [
randrange(0,5)
会多次返回相同的内容,因此会重新分配某个点
这可以通过与类型一起生成坐标并仅在该点当前未被占用时执行循环的其余部分来解决。这也将消除对单独(0,0)测试用例的需要。您只检查播放器是否被覆盖,而不是对象是否被覆盖,您应该首先获得随机坐标,然后检查是否有内容
import random
twoDimMap = [["H", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"],
["-", "-", "-", "-", "-", "-"], ["-", "-", "-", "-", "-", "-"]]
items = 0
while items <= 4:
test = random.randrange(0, 3)
if test == 0:
twoDimMap[random.randrange(0, 5)][random.randrange(0, 5)] = "S"
if test == 1:
twoDimMap[random.randrange(0, 5)][random.randrange(0, 5)] = "R"
if test == 2:
twoDimMap[random.randrange(0, 5)][random.randrange(0, 5)] = "*"
# I couldn't think of an easier way to do this
if twoDimMap[0][0] != "H":
twoDimMap[0][0] = "H"
items -= 1
items += 1
print(twoDimMap)
while items生成的项目较少,因为有时会再次生成相同的坐标。避免这种情况的一种方法是在分配项目之前检查该位置是否已经有项目。这样,你也可以解决更换英雄的问题
while items <= 4:
x = random.randrange(0, 5)
y = random.randrange(0, 5)
if twoDimMap[x][y] == '-':
twoDimMap[x][y] = random.choice('SR*')
items += 1
随机导入
twoDimMap=[“H”、“-”、“-”、“-”、“-”、[“-”、“-”、“-”、“-”、[“-”、“-”、“-”、“-”、“-”、“-”、“-”、[“-”、“-”、“-”、“-”、[“-”、“-”、“-”、“-”、“-”、[“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-”、“-
项目=0
项目列表=['S','R','*']
虽然项目由于问题空间很小,只生成三个保证唯一的项目可能不是一个糟糕的主意
random.sample(collection,n)
保证n
来自collection
的非重复随机结果random.choice(collection)
从collection
中提供一个随机元素,为了避免覆盖以前放置的项目,您可以使用random.sample
,它将从输入样本中拾取随机项目,而无需替换
随机
模块中还有其他几个方便的功能
我已经重写了您的代码,并将其转换为一个函数,可以生成任意大小、数量和类型的矩形贴图
valid_locations = (tup for tup in itertools.product(range(5), repeat=2) if tup != (0, 0))
items = ["S", "R", "*"]
choices = [(random.choice(items), loc) for loc in random.sample(valid_locations, 3)]
for item, (x, y) in choices:
twoDimMap[y][x] = item
我们使用模运算将1到36范围内的数字位置值转换为6×6网格上的x,y坐标。这是计算机图形学中非常常见和有用的操作
import random
def make_map(width, height, number_of_items, items='SR*'):
"""Create a map with the Hero in top left corner
and random items spread around"""
# build an empty map using a nested list comprehension
game_map = [['-' for x in range(width)] for y in range(height)]
# place the hero at coordinates 0, 0
game_map[0][0] = 'H'
# possible item positions, excluding 0, where the hero is.
positions = range(1, width * height)
# loop over n random choices from the available positions
for pos in random.sample(positions, number_of_items):
# convert pos to x, y coordinates using modular arithmetic
x, y = pos % width, pos // width
# select a random item to and place it at coordinates x, y
game_map[y][x] = random.choice(items)
return game_map
# generate a map. You can change the input arguments to vary size and items
game_map = make_map(6, 6, 5)
# convert the nested list to one string and print
print('\n'.join(''.join(line) for line in game_map))
这是一个非常常见的操作,python有一个内置函数,您可以使用它来完成这项工作
x, y = pos % width, pos // width
我不会解释所有代码,但我鼓励您通读答案,并尝试理解每一行是如何工作的。你可以从阅读别人对你自己解决的问题的解决方案中学到很多东西。如果你的地图不太大,你可以使用它
“生成的项目比其他时间少”是什么意思?我需要在列表twoDimMap中放置5个项目,其中放置较少项目的示例如下:[['H'、'-'、'S'、'-'、'-'、'-'、['-'、'-'、'-'、'-'、'-'、[''''-'、[''-'、'-'、'-'、'-'、'-'、'-'、'-'、'-'、'-'、'-'、''-'、'-'、'-'、'-'、''-'、'-'、'''-'、'''-'、'-'、'''''-'、'-'、'-'、'-''''''-'-''''''-''''''-,['-', '-', '-', '-', '-', '-']]不要试图在评论中解释更多内容。你知道,你可以一直在你的帖子中解释。这可能是由于多次随机获取相同的x,y坐标造成的。我打赌你生成了5个,但其中一个覆盖了以前的一个。因此,首先测试你的新项目的内容是否为-
。虽然这个答案很好,但给出一种解决方法会更可取或者,除非这些if
s会发生其他事情,否则您可以对范围(5)中的项目执行twoDimMap[x][y]=random.choice('SR*')
。此外,也可以对范围(5)中的项目执行
…那么你就不能忘记增加计数器。我看到的唯一问题是,如果你得到相同的x
和y
,那么for
的解决方案也需要而在内部生成不重复的对象ed坐标。啊…很好的观点…仍然可以简化如果
s虽然…也许只是让test=random.choice('SR*')
然后在单个ifI中分配test
,我想你应该可以直接跳到:choices=((random.choice(items),divmod(pos,5))用于random.sample中的pos(范围(1,25),5))
。@JonClements true,避免了(0,0)的巨大工作
有了这一点,但看到这一点显然更符合逻辑。是的…如果H不是第一个或最后一个-它不起作用…但是…@JonClements,但它非常整洁:D
import random
def make_map(width, height, number_of_items, items='SR*'):
"""Create a map with the Hero in top left corner
and random items spread around"""
# build an empty map using a nested list comprehension
game_map = [['-' for x in range(width)] for y in range(height)]
# place the hero at coordinates 0, 0
game_map[0][0] = 'H'
# possible item positions, excluding 0, where the hero is.
positions = range(1, width * height)
# loop over n random choices from the available positions
for pos in random.sample(positions, number_of_items):
# convert pos to x, y coordinates using modular arithmetic
x, y = pos % width, pos // width
# select a random item to and place it at coordinates x, y
game_map[y][x] = random.choice(items)
return game_map
# generate a map. You can change the input arguments to vary size and items
game_map = make_map(6, 6, 5)
# convert the nested list to one string and print
print('\n'.join(''.join(line) for line in game_map))
x, y = pos % width, pos // width
y, x = divmod(pos, width)
twoDimMap = [list(line) for line in """\
H-----
------
------
------
------
------""".split("\n")]
width, height = len(twoDimMap[0]), len(twoDimMap)
allLocations = [(x, y) for x in range(width) for y in range(height) if (x, y) != (0, 0)]
for x, y in random.sample(allLocations, 5):
case = random.randrange(3)
twoDimMap[y][x] = "SR*"[case]