""" CS1 24fa - Assignment 1 Main game loop of a battleship game implementation. """ from battleship_helpers import * from battleship_visualizer import * from task3_5 import ask_coordinates from task6 import make_boolean_square_board from task11 import check_win from task12 import go_to_next_round # Define constants and variables # no ship of length 0 or 1, 2 ships of length 2, 2 of length 3, and 1 of 4 SHIPS = [0, 0, 2, 2, 1] PURPLE = "\033[35m" DEFAULT = "\033[0m" N = 7 # Intro message to players def intro(player, rounds): """ Display an introduction message to the players and begin the game. Args: player (int): The current player (0 for Player 1, 1 for Player 2). rounds (int): The current round number. """ clear() print("Welcome to CS1 Battleships, the 2 player version!") print(RULES) input("Player 1, when you are ready to start the game, \ hide the screen from your opponent and press Enter!") clear() print(f"{PURPLE}Player {player + 1} - Round {rounds}{DEFAULT}\n") def place_ships(player, rounds, board_ships_p, ships_placed, rotate): """ Allow a player to place their ships on the board. Args: player (int): current player (0 for Player 1, 1 for Player 2). rounds (int): current round number. board_ships_p (list[list[bool]]): player's ship board. ships_placed (list[list[tuple[int, int]]]): coords of placed ships. rotate (bool): True if ship is vertical, False if horizontal. """ # Players need to place their ships visualize_ship_board(board_ships_p) for length in range(len(SHIPS)-1, 0, -1): for i in range(SHIPS[length]): # TODO (Task 7): add a print statement below to display: # Place a ship of size LENGTH! # with LENGTH the the value of the current ship's length. # Hint: our solution is a 1-liner. invalid_placement = True while invalid_placement: # Checks valid coordinate coord = ask_coordinates(board_ships_p) # Rotate ship for player if desired if input(f"Do you want to rotate the ship from \ 1 x {length} to {length} x 1? (Y/N) ").upper() == 'Y': rotate = True if not check_placement(board_ships_p, length, coord, rotate): print("Invalid position for your ship, try again!") else: invalid_placement = False # Place ship x, y = coord new_ship = [] for j in range(length): if rotate: board_ships_p[y + j][x] = True # TODO (Task 8): modify the following line of code to append # the tuple of coordinates that was just set to True on the # board. Hint: remember that coordinate tuples are in the # following format (x-coordinate, y-coordinate). new_ship.append(()) else: board_ships_p[y][x + j] = True # TODO (Task 9): modify the following line of code to append # the tuple of coordinates that was just set to True on the # board. new_ship.append(()) # TODO (Task 10): modify the following line of code to append the # list of coordinates we just populated to ships_placed of the # current player. Hint: ships placed is of the following format # [[],[]] with the first list corresponding to player 1 and the # second to player 2. Remember that you can use the player # variable. ships_placed rotate = False clear() print(f"{PURPLE}Player {player + 1} - Round \ {rounds}{DEFAULT}\n") visualize_ship_board(board_ships_p) def attack(player, rounds, board_ships, board_hits, ships_placed): """ Allow a player to attack the opponent's ships. Args: player (int): current player (0 for Player 1, 1 for Player 2). rounds (int): current round number. board_ships (list[list[list[bool]]]): players' ship boards. board_hits (list[list[list[bool]]]): players' hit boards. ships_placed (list[list[tuple[int, int]]]): coords of placed ships. Returns: bool: True if the attack was a miss, False otherwise. """ print("You're on the offensive, choose your next spot carefully!") x, y = ask_coordinates(board_hits[player]) board_hits[player][y][x] = True if board_ships[get_opponent(player)][y][x]: # Check if player won! if check_win(board_ships, board_hits, player, N): clear() print(f"Congratulations Player {player + 1}! You sank all of the \ enemy ships in {rounds} rounds!") exit() clear() print(f"{PURPLE}Player {player + 1} - Round {rounds}{DEFAULT}\n") visualize_boards(board_ships, board_hits, player, \ ships_placed[get_opponent(player)]) print("And that's a hit! Woohoo! Your turn again!") else: print("You missed, better luck next time...") return True def game_loop(): """ Main loop of the Battleship game, managing the flow between players and rounds. """ # Initialize boards board_ships = [make_boolean_square_board(N), make_boolean_square_board(N)] board_hits = [make_boolean_square_board(N), make_boolean_square_board(N)] ships_placed = [[], []] player = 0 rounds = 0 intro(player, rounds) while True: if rounds == 0: rotate = False place_ships(player, rounds, board_ships[player], ships_placed, rotate) else: visualize_boards(board_ships, board_hits, player, ships_placed[get_opponent(player)]) missed = False while not missed: missed = attack(player, rounds, board_ships, board_hits, ships_placed) rounds = go_to_next_round(player, rounds) player = switch_player(player, rounds) if __name__ == "__main__": # TODO (Task 13): make a function call to run the Battleship game when the script is # executed! After that, run the file! pass