pythonpython-2.7

Getting Python error : list index out of range


I programmed a battleship game in python. Here is the code:

#!/usr/bin/python

"""Battleship: Command Line Python Game

This is a classical version of the battleship game.

There is a board in which a battleship is randomly placed in a spot. User who correctly guesses the spot wins the game.

User have eight turns to guess correct cordinates

The game is coded in python 2"""

#imports randint from random to generate random numbers
from random import randint

#creating the board
board = []

#Filling up the board
for x in range(5):
  board.append(["O"] * 6)

#Function to print out the board to user
def print_board(board):
  for row in board:
    print " ".join(row)

#Call to print board to user
print_board(board)

#Function to generate random battleship row
def random_row(board):
  return randint(0, len(board) - 1)

#Function to generate random battleship column
def random_col(board):
  return randint(0, len(board[0]) - 1)

#Call to generate random row and column
ship_row = random_row(board)
ship_col = random_col(board)

#Snippet for debugging
print ship_row
print ship_col
#Snippet for debugging

#Running Turns
for turn in range(8):

  #Print out turn number to user
  print "Turn: " + str(turn + 1)

  #Accepts users guess
  guess_row = int(raw_input("Guess Row: "))
  guess_col = int(raw_input("Guess Col: "))

  #Check if correct guess
  if guess_row == ship_row and guess_col == ship_col:
    #Congratulate the guess
    print "Congratulations! You sunk my battleship!"
    #Exit loop and Game Over
    print "Game Over"
    break

  #If not correct guess
  else:

    #Check weather input is valid
    if (guess_row < 0 or guess_row > 5) or (guess_col < 0 or guess_col > 5):
      #Inform an invalid input
      print "Oops, that's not even in the ocean."

    #Check weather repeated guess
    elif(board[guess_row][guess_col] == 'X'):
      #Inform a repeated guess
      print "You guessed that one already."

    #For valid new input
    else:
      #Inform a missed shot
      print "You missed my battleship!"
      #Fill guessed place with X and print out the board
      board[guess_row][guess_col] = 'X'
      print_board(board)

    #Check Weather out of Turns
    if turn == 7:
      #GAME OVER
      print "Game Over"

It seems to show error: This is the full description of the error from the terminal:

Traceback (most recent call last): File "/home/prem59/Dropbox/Python/Codecademy/battleship.py", line 77, in if(board[guess_row][guess_col] == 'X'): IndexError: list index out of range

I think the elif statement is causing trouble. But if I remove it, I will not be able to check whether the user entered a repetitive input. How can I fix this problem without affecting the functionality of the program?


Solution

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

    Notice that this for loop gives you a 5x6 (5 rows x 6 columns) board. However,

    if (guess_row < 0 or guess_row > 5) or (guess_col < 0 or guess_col > 5):
        ...
    elif(board[guess_row][guess_col] == 'X'):
        ...
    

    With inputs (5, 1) (5, 2) (5, 3)... This gets evaluated to the elif block, because 5 > 5 is False.

    O O O O O O
    O O O O O O
    O O O O O O
    O O O O O O
    O O O O O O
    X X X X X X
    

    The inputs (5, 1) (5, 2) (5, 3)... are that X row which your board doesn't have.

    Quick Fix:

    # Just add another row, the X row, and you're allset
    for x in range(6):
          board.append(["O"] * 6)
    
    # Check if the input == 5, print "not in the ocean", because it really is not.
    if (guess_row < 0 or guess_row >= 5)
    

    By the way, it's a better practice to have a constant variable at the top of your program.

    SIZE = 6
    GUESSES = 8
    

    And refer to them whenever relevant. That way, it's easier to change your board size or number of guesses in the future.