-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbattleship.py
More file actions
262 lines (237 loc) · 7.09 KB
/
battleship.py
File metadata and controls
262 lines (237 loc) · 7.09 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# This is a program for playing Battlship!
# By Mark Edward Murray
import string
def new_game():
ocean = make_ocean(10, 10)
print_ocean(ocean)
fleet = arrange_fleet(ocean)
print_ocean(ocean)
hits = []
for x in range(100):
print "Turn: %d" % x
fire_shot(fleet, ocean, hits)
print_ocean(ocean)
num_of_ships = evaluate_fleet(fleet, hits)
if num_of_ships > 0:
print "There are %i ships remaining." % num_of_ships
else:
break
print "The fleet has been sunk! You win."
ask_to_play()
# synthesis functions
def print_ocean(ocean):
for row in ocean:
print " ".join(row)
def make_ocean(width, height):
ocean = []
header = ["--"]
letters = string.uppercase[:width]
for c in letters:
header.append(c)
ocean.append(header)
i = 1
for x in range(height):
ocean.append( [ "%02d" % i ] + [ "~" ] * width )
i += 1
return ocean
def arrange_fleet(ocean):
occupied = []
fleet = []
print "Deploy your carrier (length 5)."
carrier = deploy_ship(5, ocean, occupied)
fleet.append(carrier)
for ship in fleet:
print ship
print "Deploy your battleship (length 4)."
battleship = deploy_ship(4, ocean, occupied)
fleet.append(battleship)
for ship in fleet:
print ship
print "Deploy your cruiser (length 3)."
cruiser = deploy_ship(3, ocean, occupied)
fleet.append(cruiser)
for ship in fleet:
print ship
print "Deploy your submarine (length 3)."
submarine = deploy_ship(3, ocean, occupied)
fleet.append(submarine)
for ship in fleet:
print ship
print "Deploy your patrol boat (length 2)."
patrol_boat = deploy_ship(2, ocean, occupied)
fleet.append(patrol_boat)
for ship in fleet:
print ship
return fleet
def deploy_ship(length, ocean, occupied):
direction = user_input_valid_direction()
column = user_input_ship_column(length, direction, ocean)
row = user_input_ship_row(length, direction, ocean)
ship = []
# populate ship coordinates
if direction == "V":
for x in range(length):
ship.append([column, str(int(row) + x) ])
elif direction == "H":
header = ocean[0]
column_index = header.index(column)
for x in range(length):
col = header[column_index + x]
ship.append([col, row])
# check for conflict in ship placement
for coordinate in ship:
if coordinate in occupied:
print "That placement conflicts with another vessel. Try again"
print ship
ship = deploy_ship(length, ocean, occupied)
# track ship coordinates in the occupied list
for coordinate in ship:
occupied.append(coordinate)
return ship
# combat functions
def fire_shot(fleet, ocean, hits):
target = user_input_get_unique_target(ocean)
print target
column = target[0]
row = target[1]
header = ocean[0]
column_index = header.index(column)
is_hit = False
for ship in fleet:
if target in ship:
is_hit = True
ship_index = fleet.index(ship)
ship_name = ship_name_for_index(ship_index)
print "Hit!"
ocean[int(row)][column_index] = "#"
hits.append(target)
ship_is_sunk = check_if_sunk(ship, hits)
if ship_is_sunk == True:
print "You sunk the %s!" % ship_name
else:
print "You hit the %s!" % ship_name
if is_hit == False:
print "Miss!"
ocean[int(row)][column_index] = "O"
def check_if_sunk(ship, hits):
for coordinate in ship:
if coordinate not in hits:
return False
return True
def evaluate_fleet(fleet, hits):
active_ships = 0
for ship in fleet:
for coordinate in ship:
if coordinate not in hits:
active_ships += 1
break
return active_ships
def ship_name_for_index(index):
if index == 0:
return "CARRIER"
elif index == 1:
return "BATTLESHIP"
elif index == 2:
return "CRUISER"
elif index == 3:
return "SUBMARINE"
elif index == 4:
return "PATROL BOAT"
else:
return "(ship_name_error)"
# user input functions
def user_input_valid_column(ocean):
header = list(ocean[0])
header.pop(0)
column_string = raw_input("Select target column (%s-%s): " % (header[0], header[-1] ))
valid_columns = header
column_string = column_string.upper()
if column_string not in valid_columns:
print "That is not a valid column."
column_string = user_input_valid_column(ocean)
return column_string
def user_input_valid_row(ocean):
width = len(ocean) - 1
row_numbers = range(len(ocean))
row_numbers.pop(0)
valid_rows = [format(x,'d') for x in row_numbers]
row_string = raw_input("Select target row (%s-%s): " % (valid_rows[0], valid_rows[-1] ))
if row_string not in valid_rows:
print "That is not a valid row."
row_string = user_input_valid_row(ocean)
return row_string
def user_input_valid_direction():
direction = raw_input("Select ship direction (V or H): ")
direction = direction.upper()
valid_directions = [ "V", "H" ]
if direction not in valid_directions:
print "That is not a valid direction."
direction = user_input_valid_direction()
return direction
def user_input_ship_column(length, direction, ocean):
if direction == "V":
return user_input_valid_column(ocean)
elif direction == "H":
header = list(ocean[0])
header.pop(0)
counter = 1
while counter < length:
header.pop()
counter += 1
column_string = raw_input("Select target column (%s-%s): " % (header[0], header[-1] ))
valid_columns = header
column_string = column_string.upper()
if column_string not in valid_columns:
print "That is not a valid column."
column_string = user_input_ship_column(length, direction, ocean)
return column_string
else:
print "direction error"
def user_input_ship_row(length, direction, ocean):
if direction == "H":
return user_input_valid_row(ocean)
elif direction == "V":
width = len(ocean) - 1
row_numbers = range(len(ocean))
row_numbers.pop(0)
counter = 1
while counter < length:
row_numbers.pop()
counter += 1
valid_rows = [format(x,'d') for x in row_numbers]
row_string = raw_input("Select target row (%s-%s): " % (valid_rows[0], valid_rows[-1] ))
if row_string not in valid_rows:
print "That is not a valid row."
row_string = user_input_ship_row(length, direction, ocean)
return row_string
else:
print "direction error"
def user_input_yes_or_no():
user_input = raw_input("y/n: ")
if user_input.lower() == "y" or user_input.lower() == "yes":
return True
elif user_input.lower() == "n" or user_input.lower() == "no":
return False
else:
print "This is a 'yes' or 'no' question, silly."
return user_input_yes_or_no()
def user_input_get_unique_target(ocean):
column = user_input_valid_column(ocean)
row = user_input_valid_row(ocean)
header = ocean[0]
column_index = header.index(column)
if ocean[int(row)][column_index] == "~":
return [column, row]
else:
print "You have already fired on that coordinate."
return user_input_get_unique_target(ocean)
def ask_to_play():
print "Shall we play a game?"
user_input = user_input_yes_or_no()
if user_input == True:
new_game()
else:
print "You would have lost anyway."
quit()
# initial function call
ask_to_play()