如何使用Python在网格中创建10个随机的x,y坐标

4

我需要创建一个8x8的网格,并将10个硬币随机分布在网格上。我面临的问题是randint函数有时会生成相同的随机坐标,因此只有9或8个硬币被生成并放置在网格上。我该如何确保这不会发生?谢谢 :) 这是我的代码:

from random import randint

grid = []
#Create a 8x8 grid
for row in range(8):
    grid.append([])
    for col in range(8):
        grid[row].append("0")

#create 10 random treasure chests
    #problem is that it might generate the same co-ordinates and therefore not enough coins
for coins in range(10):
    c_x = randint(0, len(grid)-1)
    c_y = randint(0, len(grid[0])-1)
    while c_x == 7 and c_y == 0:
           c_x = randint(0, len(grid)-1)
           c_y = randint(0, len(grid[0])-1)
    else:
        grid[c_x][c_y] = "C"

for row in grid:
print(" ".join(row))

我已经包含了一个while/else - 因为在网格的左下角不能有硬币。


算法必须扩展到更高的维度,还是保持8x8网格和10个硬币不变? 到目前为止,给出的答案对于您的情况是有效的答案,但如果您计划放置更多的硬币或具有更高维度的网格,则可能需要不同的方法。 - Patrik H
嗨@PatrikH,是的,网格将在程序后面有选项来扩展大小并包含更多的硬币。如果我在一个函数中创建网格并用参数/参数替换8,那么这应该可以工作,对吧?;/ - Miss SJ
是的,那个方法可行。然而,对于你的问题,答案的质量取决于问题的领域。像你的8x8网格示例这样较小的问题规模,算法的复杂度并不重要,但对于更大的网格,它将显著限制你的选择。到目前为止我看到的答案在增加网格大小时表现不佳。 - Patrik H
4个回答

6
你只有64个案例,所以你可以将所有坐标生成为元组(x,y),然后使用random.sample来直接获得10个唯一元素,这样你就不必检查或重新绘制。
import random
from itertools import product

g = [['0' for _ in range(8)] for _ in range(8)]

coord = list(product(range(8), range(8)))
for coins in random.sample(coord, 10):
    g[ coins[0] ][ coins[1] ] = 'C'

for row in g:
    print(' '.join(row))

5

您希望生成10个随机的唯一坐标?

您可以使用集合进行验证:

cords_set = set()
while len(cords_set) < 10:
    x, y = 7, 0
    while (x, y) == (7, 0): 
        x, y = randint(0, len(grid) - 1), randint(0, len(grid[0]) - 1)
    # that will make sure we don't add (7, 0) to cords_set
    cords_set.add((x, y))

这将生成一个由元组组成的集合,表示 (x,y) 坐标。 print(cords_set) 的几个示例输出:
{(5, 6), (7, 6), (4, 4), (6, 3), (7, 4), (6, 2), (3, 6), (0, 4), (1, 7), (5, 2)}

{(7, 3), (1, 3), (2, 6), (5, 5), (4, 6), (3, 0), (0, 7), (2, 0), (4, 1), (6, 5)}

{(1, 2), (1, 3), (6, 7), (3, 3), (4, 5), (4, 4), (6, 0), (1, 0), (2, 5), (2, 4)}

然后:for coords in cords_set: grid[coords[0]][coords[1]] = 'C' - Ma0
@Ev.Kounis 是的,我相信 OP 会自己意识到这一点 :) - DeepSpace
谢谢@DeepSpace,我不知道set(),这应该解决问题!我还是个新手 :) - Miss SJ

1
你可以在 while 循环中添加另一个检查,以确保当前选择的坐标上没有硬币。顺便说一下,通过直接更改 randint 的范围来匹配你的需求,也可以避免你已经进行的检查。
或者你可以生成所有可能的 7*7=49 个坐标(消除不需要的坐标),然后使用 np.random.choice 函数随机选择 10 个不同的坐标。

谢谢@polku - 在您的建议之后,我也进行了一些研究,并发现intertools.combinations_with_replacement或intertools.permutations也可以帮助生成49个唯一坐标 :) - Miss SJ
哦,实际上它们不起作用!哈哈 - 我刚刚读了更多关于它们的内容... - Miss SJ

0

请看下面的代码:

from random import randint

grid = []
#Create a 8x8 grid
for row in range(8):
    grid.append([])
    for col in range(8):
        grid[row].append("0")

for coins in range(10):
    c_x = randint(0, len(grid)-1)
    c_y = randint(0, len(grid[0])-1)
    while grid[c_x][c_y] == "C":
        c_x = randint(0, len(grid) - 1)
        c_y = randint(0, len(grid[0]) - 1)
    grid[c_x][c_y] = "C"

在生成坐标后,您需要检查该位置是否已经有'C'。如果有,则重新绘制并重新检查。如果没有,则分配一个'C'并绘制下一个。

如果有帮助,请告诉我 ☺


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接