Home > Software engineering >  What is the best way to generate random ships in an array in Python?
What is the best way to generate random ships in an array in Python?

Time:02-01

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:

  1. 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 11

  2. loop 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 form

  3. collision check

    if board[row k][col] == "X": you want to build the ships "forwards" so you use row k, you can also forego int conversions when you only use integers to begin with

  4. collsion check 2

    if colission: pass else: colission = True This whole block can be shortened to collision = True break since you dont need to keep checking for multiple collisions

  5. buildcount

    for j in range(buildCount): unless you get a collision (then you wouldnt be in this branch) buildCount is always the same as shipLen[i] so it can be completly removed from your code

  6. boat building

    board[row j][col] = "X": same as before we build forwards

  7. honorable mentions

    shipAvailable = len(shipLen) you could also remove this part completly and iterate over your ships directly in your out for loop

    Instead of radoomising your direction row and col on every break condition you could randomize it once at the start of your while loop

    j = 0 unlike C you dont have to define your variables before using them in a loop, this statement does nothing

  •  Tags:  
  • Related