Stack Overflow Asked on January 4, 2021
I’m making a function that randomizes a gameboard (represented by a list of ten lists of ten) for the game battleship. what my function does currently is randomly place numbers on the board representing ships. My function also makes sure that the ships don’t loop around the edge of the board and appear on the other side, as well as randomly generating the orientation of the ships. what my function fails to achieve however is making sure that the "ships" don’t overlap onto each other. I’ve been having trouble coming up with a solution, though I’m sure its a pretty simple one. is there a way to achieve my goal?
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])
Output example:
[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]
Output with overlap (the five ship is covered by the three ship):
[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]
At the risk of over-complicating things, I suggest an object oriented approach. It is possible to modify your method, but I find it gets messy fast.
In the place
function, we assemble a list of locations
to place in order to make the ship. We then check if there is any ship already located there grid[y][x] != 0
. If so, we need to re-generate
random values for the position and rotation, then we can try to place
again.
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', ' '))
Let me know if you have any questions about the code.
Correct answer by mazore on January 4, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP