# 2-player Battleship game Python

I have been working on a 2-player battleship game in Python. The game asked you to guess a row and column from a 5x5 game board before checking those coordinates to see if you have correctly guessed the ships location.

I have been working on this game for quite a while (since I'm fairly new to programming in general) and I've finally created a game that works bug-free (at least I haven't spotted any).

My question is simply whether there is anything in the code below that can be improved upon? Does the code make sense to you? Would you change anything and why?

from random import randint

game_board = []
player_one = {
"name": "Player 1",
"wins": 0,
"lose": 0
}
player_two = {
"name": "Player 2",
"wins": 0,
"lose": 0
}

# Building our 5 x 5 board
def build_game_board(board):
for item in range(5):
board.append(["O"] * 5)

def show_board(board):
print("Find and sink the ship!")
for row in board:
print(" ".join(row))

# Defining ships locations
print("WELCOME TO BATTLESHIP!")
del board[:]
build_game_board(board)
show_board(board)
ship_col = randint(1, len(board))
ship_row = randint(1, len(board[0]))
return {
'ship_col': ship_col,
'ship_row': ship_row,
}

# Players will alternate turns.
def player_turns(total_turns):

if total_turns % 2 == 0:
total_turns += 1
return player_one

else:
return player_two

# Allows new game to start
def play_again():
global ship_points
answer = input("Would you like to play again? ")

else:
print("Thanks for playing!")
exit()

# What will be done with players guesses
def input_check(ship_row, ship_col, player, board):
guess_col = 0
guess_row = 0
while True:
try:
guess_row = int(input("Guess Row:")) - 1
guess_col = int(input("Guess Col:")) - 1
except ValueError:
print("Enter a number only: ")
continue
else:
break
match = guess_row == ship_row - 1 and guess_col == ship_col - 1
not_on_game_board = (guess_row < 0 or guess_row > 4) or (guess_col < 0 or guess_col > 4)

if match:
player["wins"] += 1
print("Congratulations! You sunk my battleship!")
print('The current match score is %d : %d (Player1 : Player2)' % (player_one["wins"], player_two["wins"]))
print("Thanks for playing!")
play_again()

elif not match:
if not_on_game_board:
print("Oops, that's not even in the ocean.")

elif board[guess_row][guess_col] == "X" or board[guess_row][guess_col] == "Y":

else:
print("You missed my battleship!")
if player == player_one:
board[guess_row][guess_col] = "X"
else:
board[guess_row][guess_col] = "Y"
show_board(game_board)

else:
return 0

def main():
begin = input('Type \'start\' to begin: ')
while (begin != str('start')):
begin = input('Type \'start\' to begin: ')

for games in range(3):
for turns in range(6):

if player_turns(turns) == player_one:
# print(ship_points)
print("Player One")
input_check(
ship_points['ship_row'],
ship_points['ship_col'],
player_one, game_board
)

elif player_turns(turns) == player_two:
print("Player Two")
input_check(
ship_points['ship_row'],
ship_points['ship_col'],
player_two, game_board
)

if turns == 5:
print("The number of turns has ended.")
print('The current match score is %d : %d (Player1 : Player2)' % (player_one["wins"], player_two["wins"]))
play_again()

if __name__ == "__main__":
main()


# General

• In build_game_board() you shouldn't use item in the for-loop. Instead, use an underscore:

for _ in range(5):
# something


This is common in loops where you don't need to access / modify each value. You can shorten player_turns() (which I would call take_turns()):

def player_turns(total_turns):
if total_turns % 2 == 0:
total_turns += 1
return player_one
return player_two

• You should indicate which options the user has, like this:

POSITIVE = ("yes", "y")
NEGATIVE = ("no", "n")

while True:
answer = input("Play again (y(es) / n(o)? ").lower()
# something here
# something else here

• In input_check() (bad name), you use an if / elif / else construct, even though it seems there is no way the else block would ever be reached.

# Style issues

• According to PEP-8, if you need to represent single quotation marks in strings, you should encase the string with double quotation marks:

begin = input("Type 'start' to begin: ")
begin = input('Type "start" to begin:')


begin = input('Type \'start\' to begin: ')
begin = input("Type \"start\" to begin: ")

• You may want to add more whitespace to the program, which essentially visually groups together certain aspects of the game, thereby improving the user experience:

print() # Blank line before program starts
call a function()

get input

print() # Blank line before either result
if statement then
print result 1

else then
print result 2

# Etc.

• You may want to color the board. You might use curses, ANSI escape codes, or colorama.

Here's an example of using ANSI escape codes:

colors = {
"reset":"\033[00m",
"red":"\033[91m",
"green":"\033[92m",
"yellow":"\033[93m",
"blue":"\033[94m",
"pink":"\033[95m",
"cyan":"\033[96m"
}

# Other stuff happens here...
# When the board is printed, first print an ANSI color code
print(colors["yellow"])
print(<board>)
print(colors["reset"])