K. Thijssen
K. Thijssen

Reputation: 31

A battleship in Python

For a school project I have to make a Battleship game. In the game, a player has 4 ships, and the game ends if all ships of a single player are destroyed. I'm trying to get this feature to work.

This is the code:

board = []
for x in range(10):
    board.append(["O"] * 10)
def print_board(board):
    for row in board:
        print " ".join(row)
print "Let's play Battleship!"
print_board(board)
def Input_row1(board):
    return int(raw_input("In what row do you want to place your first ship?"))
def Input_col1(board):
    return int(raw_input("In what col do you want to place your first ship?"))  
def Input_row2(board):
    return int(raw_input("In what row do you want to place your second ship?"))
def Input_col2(board):
    return int(raw_input("In what col do you want to place your second ship?")) 
def Input_row3(board):
    return int(raw_input("In what row do you want to place your third ship?"))
def Input_col3(board):
    return int(raw_input("In what col do you want to place your third ship?"))
def Input_row4(board):
    return int(raw_input("In what row do you want to place your fourth ship?"))
def Input_col4(board):
    return int(raw_input("In what col do you want to place your fourth ship?"))  
ship_row1 = Input_row1(board)
ship_col1 = Input_col1(board)
ship_row2 = Input_row2(board)
ship_col2 = Input_col2(board)
ship_row3 = Input_row3(board)
ship_col3 = Input_col3(board)
ship_row4 = Input_row4(board)
ship_col4 = Input_col4(board)
for turn in range(9):
    guess_row = int(raw_input("Guess Row:"))
    guess_col = int(raw_input("Guess Col:"))
    if guess_row == ship_row1 and guess_col == ship_col1 or guess_row == ship_row2 and guess_col == ship_col2 or guess_row == ship_row3 and guess_col == ship_col3 or guess_row == ship_row4 and guess_col == ship_col4:
        print "Congratulations! You sunk my battleship!"
        if True:
            total_ships = 4
            total_ships = total_ships - 1
            print total_ships
            if total_ships == 0:
                print "You destroyed all hostile ships!"
    else:
        if (guess_row < 0 or guess_row > 9) or (guess_col < 0 or guess_col > 9):
            print "Oops, that's not even in the ocean."
        elif(board[guess_row][guess_col] == "X"):
            print "You guessed that one already."
        else:
            print "You missed my battleship!"
            if turn == 9:
                print "GAME OVER"
                if turn == 9:
                    print "Game Over"
        board[guess_row][guess_col] = "X"
    print "Turn", turn + 1
    print_board(board)

The problem is that after the second ship has been hit, the the total_ships stays 3, and does not turn to 2. Why is this not functioning correctly?

Upvotes: 2

Views: 1100

Answers (2)

Zanapher
Zanapher

Reputation: 352

There are a lot of strange things with your program. I'm not sure how much we're supposed to rewrite here since this is a school project, but here are some comments:

  • for your main question, as answered by Nathaniel Ford, the problem is that you reset total_ships to 4 before decrementing it each time a ship is hit. Initialize it only once at the beginning of the program, not in the turns loop.

  • In that same loop, there is a line

    if True:
    

    I don't know what you meant by that, but it's probably not doing what you want it to do. It's completely useless as the block inside the if is always executed (so you might as well remove the if altogether, or more likely rewrite the test so it does what you had in mind).

  • You declare a 10x10 array called board at the beginning but you never use it. If you create a board (which seems to be a good idea), you shouldn't store the positions of each battleship in separate variables (ship_row1, ship_col1, etc.). Instead, when the user chooses the position (i, j) of a ship, you should set the cell board[i][j] to 1 to indicate there is a ship there, and get rid of the ship_col and ship_row variables entirely. That way choosing positions for all ships are done the same way in a loop that asks for x and y (row and column) and changes the corresponding cell in the board (imagine placing 20 ships with the code you wrote, that would be a lot of copy/pasting...). This would also make it simpler to check that the user doesn't place two ships at the same location (in your current implementation, when placing the 4th ship you should add a long check to see if

    ship_col4 == ship_col1 and ship_row4 == ship_row1
    or ship_col4 == ship_col2 and ship_row4 == ship_row2
    or ship_col4 == ship_col3 and ship_row4 == ship_row3
    

    which could be simply replaced by checking if the cell on the board is already 1.

Upvotes: 3

Nathaniel Ford
Nathaniel Ford

Reputation: 21230

This is your problem:

total_ships = 4
total_ships = total_ships - 1

You reset total_ships every time. The above is equivalent to:

total_ships = 3

You should have the initialization of your total_ships be outside your turn for loop. For that matter, the best thing you could do is create a function that is your game loop and a function that handles specific turns, so you don't just have one long file of code.

Upvotes: 3

Related Questions