Recently, I've been working on a battleship game for my CS2 class. The focus of this project is to create a board game using arrays, and I decided to create a battleship. I have most of the code, but I cannot figure out how to get ships to get randomly generated on a 10x10 array without the ships being...
A. The wrong length B. Looping around the array
Below is the function I currently have.
def createShips(board):
shipLen = [5,4,3,3,2]
shipAvalible = 5
directionposibilities = ["vertical", "horizontal"]
j = 0
for i in range(shipAvalible):
boatMade = False
#REGULAR VAR STATMENTS
direction = random.choice(directionposibilities)
col = randint(0,9)
row = randint(0,9)
while boatMade == False:
if direction == "vertical":
buildCount = 0
if col int(shipLen[i]) <= 11:
colission = False
for i in range(0, int(shipLen[i])):
buildCount = 1
if board[int(row-i)][int(col)-1] == "X":
if colission:
pass
else:
colission = True
if colission:
col = randint(0,9)
row = randint(0,9)
else:
for j in range(buildCount):
board[int(row-j)][int(col)-1] = "X"
boatMade = True
else:
col = randint(0,9)
row = randint(0,9)
if direction == "horizontal":
if col int(shipLen[i]) <= 10:
colission = False
buildCount = 0
for i in range(0, int(shipLen[i])):
buildCount = 1
if board[int(row)][int(col) i-1] == "X":
if colission:
pass
else:
colission = True
if colission:
col = randint(0,9)
row = randint(0,9)
else:
for j in range(buildCount):
board[int(row)][int(col) j-1] = "X"
boatMade = True
else:
col = randint(0,9)
row = randint(0,9)
shipAvalible = shipAvalible - 1
return(board)
board = [["■"] * 10 for x in range(10)]
print(createShips(board))
If you have any idea why this may not work please let me know!
P.S. I am using another function that prints the array nicely, if you would like that for convenience, it is seen below:
def showBoard(board):
print(" A B C D E F G H I J")
print(" ------------------------------")
rownumb = 1
for r in board:
if rownumb == 10:
space = ""
else:
space = " "
print("%d|%s|" % (rownumb, space "|".join(r)))
rownumb = 1
CodePudding user response:
Edit: @Eumel was a bit faster and said it better here
First of all, you have a inner and outer loop with the variable i, which might not actually interfere but it makes it harder to read the code. Consider renaming one of the variables.
When you create a vertical ship, you check the col rather than the row for index error, and does so against a value of 11 instead of your board size 10.
In the vertical case you build the ship "backwards" from the selected position, even though you checked that your board could fit the ship in the positive direction (And you place it in a column to the left). These negative values makes it such that your ships can wrap around.
In the horizontal case you are indexing a bit strange again where board[int(row)][int(col) i-1] this gives that when i=0 you place your ship an index further to the left than intended, again causing the ship to wrap when col=0.
Further more, you could remove a few redundant if statements and duplicate lines of code, by moving:
direction = choice(directionposibilities)
col = randint(0, 9)
row = randint(0, 9)
Inside the while loop.
CodePudding user response:
Ok lets go over this:
length check
if col int(shipLen[i]) <= 9:since arrays start at 0 in python the maximum index for a 10x10 board is 9, therefore you need to chek against 9 instead of 11loop variables
for k in range(0, int(shipLen[i])):using the same variable name for the outer and inner loop (while working in this specific case) is really bad formcollision check
if board[row k][col] == "X":you want to build the ships "forwards" so you userow k, you can also forego int conversions when you only use integers to begin withcollsion check 2
if colission: pass else: colission = TrueThis whole block can be shortened tocollision = True breaksince you dont need to keep checking for multiple collisionsbuildcount
for j in range(buildCount):unless you get a collision (then you wouldnt be in this branch) buildCount is always the same asshipLen[i]so it can be completly removed from your codeboat building
board[row j][col] = "X":same as before we build forwardshonorable mentions
shipAvailable = len(shipLen)you could also remove this part completly and iterate over your ships directly in your out for loopInstead of radoomising your direction row and col on every break condition you could randomize it once at the start of your while loop
j = 0unlike C you dont have to define your variables before using them in a loop, this statement does nothing
