Python: Extended Battleship Game


#1

Hi,
I’ve been building the Battleship Game in the Python Course, and i’ve imported the code to my own computer and extended it. The problem is, when i enter colon = 10 and row = 7, then it gives this error message:

elif board[guess_row][guess_col] == “X” or board[guess_row][guess_col] == “B” or board[guess_row][guess_col] == “A”:
IndexError: list index out of range

and i’m just confused:

  1. I don’t know precisely what “list index out of range” means
  2. What the problem with that line should be (because I covered it in my code)
  3. A third, very different thing: When the square has been guessed before, or if the guess is out of the range of the ocean: I wrote “turn -= 1”, but it didn’t affect; it increased when it shouldn’t!

Can anybody please help me because i really want to get this fixed! :smiley:



from random import randint

# This code makes the boards and print them
board = []

for x in range(7):
    board.append(["O"] * 10)

def print_board(board):
    for row in board:
        print " ".join(row)

def print_startofgame():
    print "Welcome to the Battleship Game!"
    print "Instructions:"
    print "This is a single player Battleship Game. There are a battleship and a aircraft carrier, which fills one square each."
    print "You have 30 guesses. First, you will be asked for the colon. You can guess from colon 1 to 10. "
    print "Then you would be asked for the row. You can guess from row 1 to row 7. "
    print "If you don't guess where the ships is with your 30 guesses, the game is over."
    print "Ready? Lets start!"
    print ""
    print ""
    print ""
    print ""
    print ""
    print ""
    print ""

print print_startofgame()

print_board(board)

# This code defines where the battleship is
def random_row_1(board):
    return randint(0, len(board) - 1)

def random_col_1(board):
    return randint(0, len(board[0]) - 1)

battleship_row = random_row_1(board)
battleship_col = random_col_1(board)

# This code defines where the aircraft carrier is
def random_row_2(board):
    return randint(0, len(board) - 1)

def random_col_2(board):
    return randint(0, len(board[0]) - 1)

aircraft_carrier_row = random_row_2(board)
aircraft_carrier_col = random_col_2(board)



# This code checks the guesses and if the ships are on top of each other
if (battleship_row == aircraft_carrier_row) and (battleship_col == aircraft_carrier_col):
    print "Game crashed. Close the terminal and try again." # Ships are on top of each other
else:
    for turn in range(30):
        print "Turn", turn + 1
        guess_row = int(raw_input("Guess Col: ")) - 1
        guess_col = int(raw_input("Guess Row: ")) - 1

        if guess_row == battleship_row and guess_col == battleship_col:
            print "Kaboom! You sunk my battleship!"
            board[guess_row][guess_col] = "B"
            print_board(board)
        elif guess_row == aircraft_carrier_row and guess_col == aircraft_carrier_col:
            print "Kaboom! You sunk my aircraft carrier!"
            board[guess_row][guess_col] = "A"
            print_board(board)
        else:
            if (guess_row < 0 or guess_row > 10) or (guess_col < 0 or guess_col > 7):
                print "Oops, that's not even in the ocean."
                print
                turn -= 1
            elif board[guess_row][guess_col] == "X" or board[guess_row][guess_col] == "B" or board[guess_row][guess_col] == "A":
                print "You guessed that one already."
                turn -= 1
            else:
                print "Splash! You missed!"
                print 
                board[guess_row][guess_col] = "X"
                turn += 1
                print_board(board)
        if (board[battleship_row][battleship_col]) == "B" and (board[aircraft_carrier_row][aircraft_carrier_col] == "A"):
            print "Wow! You sunk my ships! You're good at shooting!"
        
        
        if turn == 30:
            print "Game Over!"
            print "You have to work on your aim."
            if (board[battleship_row][battleship_col] == "O") and (board[aircraft_carrier_row][aircraft_carrier_col] == "O"):
                print "Here's were the ships was:"
                board[battleship_row][battleship_col] = "B"
                board[aircraft_carrier_row][aircraft_carrier_col] = "A"
                print_board(board)
            elif (board[battleship_row][battleship_col] == "O") and (board[aircraft_carrier_row][aircraft_carrier_col] != "O"):
                print "Here's were the battleship was:"
                board[battleship_row][battleship_col] = "B"
                print_board(board)
            elif (board[aircraft_carrier_row][aircraft_carrier_col] == "O") and (board[battleship_row][battleship_col] != "O"):
                print "Here's were the aircraft carrier was:"
                board[aircraft_carrier_row][aircraft_carrier_col] = "A"
                print_board(board)
        
        


Technical informations:

I print it in the terminal (iTerm2)

Old code (from the exercise in the course, before i imported it and extended it):

Click to view
from random import randint

board = []

for x in range(5):
    board.append(["O"] * 5)

def print_board(board):
    for row in board:
        print " ".join(row)

print "Let's play Battleship!"
print_board(board)

def random_row(board):
    return randint(0, len(board) - 1)

def random_col(board):
    return randint(0, len(board[0]) - 1)

ship_row = random_row(board)
ship_col = random_col(board)
print ship_row
print ship_col

# Everything from here on should go in your for loop!
# Be sure to indent four spaces!
for turn in range(4):
    print "Turn", turn + 1
    guess_row = int(raw_input("Guess Row:"))
    guess_col = int(raw_input("Guess Col:"))

    if guess_row == ship_row and guess_col == ship_col:
        print "Congratulations! You sunk my battleship!"
        break
    else:
        if (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4):
            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!"
            board[guess_row][guess_col] = "X"
        turn += 1
        print_board(board)
        
    if turn == 4:
        print "Game Over"

#2
>>> row = list(range(10))
>>> row
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> row[10]
Traceback (most recent call last):
  File "<pyshell#76>", line 1, in <module>
    row[10]
IndexError: list index out of range
>>> 

I could be wrong but in Python for loops, we cannot manipulate the iterator variable value the way we can in JavaScript. To be able to manipulate that value, use a while loop.

i = 0
while i < 30:
    i++
    # ...

#3

I know that the list range would be 0,1,2,3,4,5,6,7,8,9
and I thought that It would be a better game if a player should guess from 1 to 10 instead of 0 to 9, because for normal people it doesn’t make very much sense to count from zero instead of one.
So, if you see this part:


        guess_row = int(raw_input("Guess Col: ")) - 1
        guess_col = int(raw_input("Guess Row: ")) - 1

The code says:
Prompt the player for a colon and a row guess, subtract it by one and store it in the variables guess_row and guess_col
And I tested it with a smaller board and it worked, but on this 7x10 board it doesn’t work.
Don’t understand why


#4

Subtracting 1 puts the values in the expected range so the first row and first column are reachable.

Your board has 7 rows and 10 columns.

if guess_row not in range(7) or guess_col not in range(10)

#5

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.