首页 > 解决方案 > 随机化列表列表而不重叠

问题描述

我正在为游戏战舰制作一个随机化游戏板(由十个列表中的十个列表表示)的函数。我目前的功能是在代表船只的板上随机放置数字。我的功能还确保船只不会绕着棋盘的边缘循环并出现在另一侧,以及随机生成船只的方向。然而,我的功能未能实现的是确保“船”不会相互重叠。我一直无法想出一个解决方案,尽管我确信它是一个非常简单的解决方案。有没有办法实现我的目标?

import random
l = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]

for a in range(1, 5):
    p = random.randrange(0, 10, 1)
    o = random.randrange(0, 10, 1)
    #the p and o variables determine the coordinates of the starting point
    r = random.randrange(1, 3)
    #the r variable randomizes orientation of the ship
    if r == 1:
        for n in range(1, 7 - a):
            #the function uses the length of the ship to determine whether or not 
            #the ship will go off the end of the board
            if o < 6 - a:
                l[p][(6 - a) - n] = 6 - a
            else:
                l[p][o-n] = 6 - a
    else:
        for e in range(1, 7 - a):

            if p < 6-a:
                l[(6-a) - e][o] = 6-a
            else:
                l[p - e][o] = 6-a
for v in range(0, len(l)):
    print(l[v])

输出示例:

[0, 3, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 3, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 3, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 4, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 4, 0, 0, 5, 5, 5, 5, 5, 0]
[0, 4, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 4, 0, 0, 0, 0, 0, 0, 2, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 2, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

重叠输出(五艘船被三艘船覆盖):

[0, 0, 0, 0, 5, 5, 5, 5, 3, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 3, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 3, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[2, 2, 0, 0, 0, 0, 0, 0, 0, 0]
[4, 4, 4, 4, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

标签: python2d-games

解决方案


冒着使事情过于复杂的风险,我建议采用面向对象的方法。可以修改您的方法,但我发现它很快就会变得混乱。

place函数中,我们组装了一个locations要放置的列表以制作船。然后我们检查那里是否已经有任何船只grid[y][x] != 0。如果是这样,我们需要generate为位置和旋转重新随机值,然后我们可以place再次尝试。

import random

GRID_WIDTH, GRID_HEIGHT = 10, 10  # constants representing width and height of the board
grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]  # generate a 10x10 grid of 0's


class Ship:
    def __init__(self, length):
        self.length = length
        self.x, self.y, self.horizontal = None, None, None
        self.generate()

    def generate(self):  # randomize position and rotation
        self.x = random.randint(0, GRID_WIDTH-self.length)
        self.y = random.randint(0, GRID_HEIGHT-self.length)
        self.horizontal = random.choice([True, False])
        self.place()

    def place(self):  # place ship on the grid
        locations = []
        if self.horizontal:
            for x in range(self.x, self.x+self.length):
                locations.append((x, self.y))
        else:  # if vertical
            for y in range(self.y, self.y+self.length):
                locations.append((self.x, y))
        for x, y in locations:
            if grid[y][x] != 0:  # if occupied, regenerate whole ship
                self.generate()
                return
        for x, y in locations:  # actually place ship now
            grid[y][x] = self.length


ships = []
for ship_length in range(2, 6):
    ships.append(Ship(ship_length))

for row in grid:  # print the board
    print(row)

# for row in grid:  # print the board without 0's
#     print(str(row).replace('0', ' '))

如果您对代码有任何疑问,请告诉我。


推荐阅读