从数组中生成随机非重复样本

时间:2014-11-08 08:03:45

标签: python

我制作了战舰游戏,我现在需要确保计算机不会在同一地点两次攻击。

我的想法是将每个镜头的坐标存储在一个变量中,每当有新镜头时它就会被添加,然后我只需检查并检查当前镜头是否在变量中

这是我拍摄的代码:

if playerNumber == "1":

        eg.msgbox("Player " + str(playerNumber) + " your shot.")

        hit=False

        shotX=eg.enterbox("Enter the x-coordinate for your shot (1-5): ")
        shotY=eg.enterbox("Enter the y-coordinate for your shot (1-5): ")

    else:

        eg.msgbox("The computer will now attack!")

        hit=False
        shotX=str(random.randint(1,5))
        shotY=str(random.randint(1,5))

        eg.msgbox ("The computer shot at " + str(shotX) + ", " + str(shotY) + "")

我确保计算机选择列表中没有的东西的想法是使用一个循环,它一直选择一个镜头,直到它选择的那个已经被选中。

让电脑开枪的实际代码是:

hit = haveShot("2", p1ship1, p1ship2 , player2Board)

    if hit:
        p2 = p2 + 1
        eg.msgbox("The Computer has " + str(p2) + " points and Player 1 has " + str(p1) + " points")
        if p2 == 2:    
            eg.msgbox("Unlucky, The computer won. Press enter to continue")
            if platform.system() == "Windows": # ONLY PLAY SOUNDS IF ON WINDOWS OS
                finish()
            break

谢谢!

3 个答案:

答案 0 :(得分:0)

我首先用语言无关的方式回答。

一种非常有效的方法是保留所有可能位置的顺序列表(在您的情况下为5x5 = 25个位置),在该列表中使用单个随机选择,然后从列表中删除位置。这可以帮助您远离当我到达已经进入的位置时该做什么

Python实现:

首先生成职位列表:

positions = [ (i, j) for i in range(1,6) for j in range(1,6) ]

然后获取一个随机位置并将其从列表中删除

index = random.randrange(len(positions))
shotX, shotY = positions[index]
del positions[index]

编辑:

作为证据,它应该分叉:

>>> import random
>>> positions = [ (i, j) for i in range(1,6) for j in range(1,6)]
>>> for i in range(25):
    index = random.randrange(len(positions))
    print positions[index]
    del positions[index]


(5, 5)
(5, 4)
(1, 4)
(1, 2)
(3, 3)
(1, 1)
(4, 1)
(4, 4)
(5, 1)
(4, 2)
(2, 2)
(2, 4)
(2, 3)
(2, 1)
(3, 2)
(3, 5)
(1, 5)
(5, 3)
(5, 2)
(4, 3)
(4, 5)
(1, 3)
(3, 4)
(2, 5)
(3, 1)
>>> print positions
[]

答案 1 :(得分:-1)

你可以记录所有射击的日志:

# during initialization
fired = set()
# ... skipping to the interesting part ...
eg.msgbox("The computer will now attack!")
while True:
    shotX = random.randint(1,5)
    shotY = random.randint(1,5)
    if (shotX, shotY) not in fired:
        break # OK, no need to look any further
    # else try another shot...
eg.msgbox ("The computer shot at {0}, {1}".format(shotX, shotY))
fired.add((shotX, shotY))

我还将shotXshotY保持为整数(例如,如果要在矩阵中查找索引,则可能需要使用它们。

答案 2 :(得分:-1)

你可以使用n个目标的随机排列,并从这个随机置换列表中射击目标。请使用random.shuffle,如下所示。我已经显示了在5的范围内随机生成的非重复的样本输出。使用此混洗列表进行定位,而无需检查您是否已经拍摄此照片。

>>> s=list(range(5))
>>> s
    [0, 1, 2, 3, 4]
>>> random.shuffle(s)
>>> s
    [3, 4, 2, 1, 0]
>>> s
    [3, 4, 2, 1, 0]
>>> random.shuffle(s)
>>> s
    [4, 0, 2, 1, 3]
>>> random.shuffle(s)
>>> s
    [2, 1, 3, 0, 4]