In: Computer Science
Python:
In the CIS 41A version of Battleship, the user tries to find the computer's battleship that has been randomly put on a grid of rows and columns (the game board). Here is how the game is played:
Implementation
The program has 2 constants: MIN which is set to 2, and MAX which is set to 4
and the program has 4 functions:
- if the user successfully guessed the locations: print the board with an 'X' at the correct location, and print the number of trie
Important notes (don't miss them in your code):
-- A docstring (not a comment) for each function, except for the main function
from random import randint
import os
class Ship:
def __init__(self, size, orientation, location):
self.size = size
if orientation == 'horizontal' or orientation == 'vertical':
self.orientation = orientation
else:
raise ValueError("Value must be 'horizontal' or 'vertical'.")
if orientation == 'horizontal':
if location['row'] in range(row_size):
self.coordinates = []
for index in range(size):
if location['col'] + index in range(col_size):
self.coordinates.append({'row': location['row'], 'col':
location['col'] + index})
else:
raise IndexError("Column is out of range.")
else:
raise IndexError("Row is out of range.")
elif orientation == 'vertical':
if location['col'] in range(col_size):
self.coordinates = []
for index in range(size):
if location['row'] + index in range(row_size):
self.coordinates.append({'row': location['row'] + index, 'col':
location['col']})
else:
raise IndexError("Row is out of range.")
else:
raise IndexError("Column is out of range.")
if self.filled():
print_board(board)
print(" ".join(str(coords) for coords in self.coordinates))
raise IndexError("A ship already occupies that space.")
else:
self.fillBoard()
def filled(self):
for coords in self.coordinates:
if board[coords['row']][coords['col']] == 1:
return True
return False
def fillBoard(self):
for coords in self.coordinates:
board[coords['row']][coords['col']] = 1
def contains(self, location):
for coords in self.coordinates:
if coords == location:
return True
return False
def destroyed(self):
for coords in self.coordinates:
if board_display[coords['row']][coords['col']] == 'O':
return False
elif board_display[coords['row']][coords['col']] == '*':
raise RuntimeError("Board display inaccurate")
return True
#Settings Variables
row_size = 9 #number of rows
col_size = 9 #number of columns
num_ships = 4
max_ship_size = 5
min_ship_size = 2
num_turns = 40
#Create lists
ship_list = []
board = [[0] * col_size for x in range(row_size)]
board_display = [["O"] * col_size for x in range(row_size)]
#Functions
def print_board(board_array):
print("\n " + " ".join(str(x) for x in range(1, col_size +
1)))
for r in range(row_size):
print(str(r + 1) + " " + " ".join(str(c) for c in
board_array[r]))
print()
def search_locations(size, orientation):
locations = []
if orientation != 'horizontal' and orientation !=
'vertical':
raise ValueError("Orientation must have a value of either
'horizontal' or 'vertical'.")
if orientation == 'horizontal':
if size <= col_size:
for r in range(row_size):
for c in range(col_size - size + 1):
if 1 not in board[r][c:c+size]:
locations.append({'row': r, 'col': c})
elif orientation == 'vertical':
if size <= row_size:
for c in range(col_size):
for r in range(row_size - size + 1):
if 1 not in [board[i][c] for i in range(r, r+size)]:
locations.append({'row': r, 'col': c})
if not locations:
return 'None'
else:
return locations
def random_location():
size = randint(min_ship_size, max_ship_size)
orientation = 'horizontal' if randint(0, 1) == 0 else
'vertical'
locations = search_locations(size, orientation)
if locations == 'None':
return 'None'
else:
return {'location': locations[randint(0, len(locations) - 1)],
'size': size,\
'orientation': orientation}
def get_row():
while True:
try:
guess = int(input("Row Guess: "))
if guess in range(1, row_size + 1):
return guess - 1
else:
print("\nOops, that's not even in the ocean.")
except ValueError:
print("\nPlease enter a number")
def get_col():
while True:
try:
guess = int(input("Column Guess: "))
if guess in range(1, col_size + 1):
return guess - 1
else:
print("\nOops, that's not even in the ocean.")
except ValueError:
print("\nPlease enter a number")
# Create the ships
temp = 0
while temp < num_ships:
ship_info = random_location()
if ship_info == 'None':
continue
else:
ship_list.append(Ship(ship_info['size'], ship_info['orientation'],
ship_info['location']))
temp += 1
del temp
# Play Game
os.system('clear')
print_board(board_display)
for turn in range(num_turns):
print("Turn:", turn + 1, "of", num_turns)
print("Ships left:", len(ship_list))
print()
guess_coords = {}
while True:
guess_coords['row'] = get_row()
guess_coords['col'] = get_col()
if board_display[guess_coords['row']][guess_coords['col']] == 'X'
or \
board_display[guess_coords['row']][guess_coords['col']] ==
'*':
print("\nYou guessed that one already.")
else:
break
os.system('clear')
ship_hit = False
for ship in ship_list:
if ship.contains(guess_coords):
print("Hit!")
ship_hit = True
board_display[guess_coords['row']][guess_coords['col']] = 'X'
if ship.destroyed():
print("Ship Destroyed!")
ship_list.remove(ship)
break
if not ship_hit:
board_display[guess_coords['row']][guess_coords['col']] = '*'
print("You missed!")
print_board(board_display)
if not ship_list:
break
# End Game
if ship_list:
print("You lose!")
else:
print("All the ships are sunk. You win!")