4
\$\begingroup\$

I'm working on a 2-player battleships game in python, although the game is slightly buggy. It sometimes does not allow me to play another game once the first game has finished, and it does not change the location of the ship once the game has moved onto game 2. I'm not entirely sure how these problems arise only that they only seem to occur sporadically. I've been told to include a main() function and pass all my functions through there but I'm not sure how to get started on that.

I've also been told that manipulating global variables are a problem in this game but I'm not sure why, perhaps you could tell me where I'm going wrong and how to improve the functionality of the game?

from random import randint game_board = [] player_one = { "name": "Player 1", "wins": 0, "lose": 0 } player_two = { "name": "Player 2", "wins": 0, "lose": 0 } total_turns = 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!") print("START") 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(): if total_turns % 2 == 0: return player_two else: return player_one # Allows new game to start def play_again(): answer = str(input("Would you like to play again?")) if answer == "yes" or answer == "y": total_turns = 0 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("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": print("You guessed that one already.") else: print("You missed my battleship!") board[guess_row][guess_col] = "X" show_board(game_board) else: return 0 # GAME - 3 games in total for games in range(3): games += 1 for turns in range(6): total_turns += 1 if player_turns() == player_one: print("Player One") input_check( ship_points['ship_row'], ship_points['ship_col'], player_one, game_board ) elif player_turns() == player_two: print("Player Two") input_check( ship_points['ship_row'], ship_points['ship_col'], player_two, game_board ) else: continue if total_turns == 6 and player_turns() == player_one: print("The game is a draw") play_again() elif total_turns == 6 and player_turns() == player_two: print("The game is a draw") play_again() else: continue 
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

This is a bug, a for-loop automatically increments "games" by one:

for games in range(3): games += 1 

In play_again(); input is automatically of type string, so no need for:

answer = str(input()) 

Rather:

answer = input() 

You should also split logical parts of the code like if-else statements with newline. This makes the code much easier to read. Finally, you can avoid three lines at the end by doing this:

if total_turns == 6: print("The game is a draw") play_again() 

Instead of using if-elif. I tried playing and I didn't come across the bugs you mentioned. About using main(); the idea is to build a main() function and make it run as such:

class AClass: def AFunction(): # do something def main(): input("Enter 'start' to start game: ") Aclass.AFunction() if __name__ == "main": main() 
\$\endgroup\$
1
\$\begingroup\$

Little improvement:

In play_again() function, if the user types "Y" to mean "yes", the game will exit. So it is better to change:

answer = str(input("Would you like to play again?")) 

to:

answer = input("Would you like to play again?").lower() 

P.S. str() is unnecessary here as answer is a string by default:

>>> answer = input("Would you like to play again?") Would you like to play again? >>> type(answer) <class 'str'> >>> 
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.