#python #2d-games
#python #2d-игры
Вопрос:
Я создаю функцию, которая рандомизирует игровое поле (представленное списком из десяти списков по десять) для игры battleship. в настоящее время моя функция выполняет случайное размещение чисел на доске, представляющих корабли. Моя функция также гарантирует, что корабли не зацикливаются на краю доски и не появляются на другой стороне, а также случайным образом генерирует ориентацию кораблей. однако моей функции не удается добиться того, чтобы «корабли» не накладывались друг на друга. У меня возникли проблемы с поиском решения, хотя я уверен, что оно довольно простое. есть ли способ достичь моей цели?
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]
Комментарии:
1. можете ли вы привести пример вывода для платы размером 4 * 4?
2. Возможно, включите комментарии в свой код, чтобы люди могли лучше его понять. По крайней мере, объясните, что такое a, p, o и r. Или еще лучше — используйте описательные имена переменных
3. Что вы подразумеваете под «перекрывающимися» кораблями?
4. Перед размещением корабля проверьте каждое целевое поле, есть ли уже корабль. Если это так, повторите попытку с новой случайной позицией.
Ответ №1:
Рискуя чрезмерно усложнить ситуацию, я предлагаю объектно-ориентированный подход. Можно изменить ваш метод, но я нахожу, что он быстро запутывается.
В 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', ' '))
Дайте мне знать, если у вас возникнут какие-либо вопросы о коде.