7
\$\begingroup\$

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
def load_game(board):
 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,
 }
ship_points = load_game(game_board)
# 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? ")
 if answer == "yes" or answer == "y":
 ship_points = load_game(game_board)
 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":
 print("You guessed that one already.")
 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()
200_success
146k22 gold badges190 silver badges479 bronze badges
asked May 31, 2017 at 13:23
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

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()
     if answer in POSITIVE:
     # something here
     elif answer in NEGATIVE:
     # 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:')
    

    ... instead of using backslashes:

    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"])
    
answered May 31, 2017 at 15:53
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.