2

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?

3
  • 3
    Look at the code where you create your board. What are its dimensions? (Hint: What does range(5) return?) Commented Aug 26, 2018 at 14:48
  • range(5) will give you [0,1,2,3,4]. so you should either change it to range(6) or change the validity check Commented Aug 26, 2018 at 14:49
  • Thanks. Now I fixed the problem Commented Aug 26, 2018 at 15:15

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

0

Your board is currently of size 5x6.

This means the row/column indexes are: 0, 1, 2, 3, 4.

Your current condition to check if the guess is off the board is:

if (guess_row < 0 or guess_row > 5) or (guess_col < 0 or guess_col > 5):

but this allows index 5 for both rows and columns when the maximum is 4.

So you should correct it to:

if guess_row < 0 or guess_row > 5 or guess_col < 0 or guess_col > 4:

(the parenthesis are unnecessary)


Note that this is entirely personal preference, but I would consider the following more readable:

if not (0 <= guess_row < 5 and 0 <= guess_col < 5):

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.