1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
"""
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