The boss loved the implementation of Battleship we put together on our lab day. It's a hit! Our product owner says that the next feature is to make it a two-way game... in our implementation, the computer has a map and ships that the player guesses against. We'd like a version where the player has a map too, and the computer guesses something they haven't guessed yet between each player guess.
Also, our tech lead said that our code was a little too... basic. They want us to clean it up and make it a bit more efficient.
Our battleship script is uploaded to Canvas as battleship_v2.py. Download that file and use it as a starting point. Your final product should be a two-player version of Battleship in which both the player and computer receive a map with random ships, and the computer makes guesses in between the player guesses.
Use everything we've learned (decision structures, loops, functions) to make the code as efficient, readable, and well-documented as possible.
Name your file "battleship_onyen.py" where onyen is your onyen and upload to Canvas.
I'll be grading your assignment based on output correctness and code readability based on the best practices we've discussed so far.
Having trouble finding our battleship script on Canvas? Here's a version you can copy:
import random
print("Welcome to battleship!")
## TODO: explain the rules
## create a grid_sizexgrid_size grid
grid_size = int(input("How big would you like the grid to be? "))
map = []
for row in range(grid_size):
inner_row = []
for col in range(grid_size):
inner_row.append(False)
map.append(inner_row)
## create 3 random 1x1 ships on the map
num_ships = int(input("How many ships would you like there to be? "))
for ship in range(num_ships):
## TODO: make sure there's not a ship here first
x_axis = random.randint(0, grid_size - 1)
y_axis = random.randint(0, grid_size - 1)
print(x_axis, y_axis)
map[x_axis][y_axis] = True
## Ask users for x/y coordinates
keep_going = True
## continue guessing until they have hit all three ships
hits = []
misses = []
while keep_going:
## display hits and misses if there are any
if len(hits):
print("Your hits so far: ")
for hit in hits:
print(hit)
if len(misses):
print("Your misses so far: ")
for miss in misses:
print(miss)
## ask the user for coordinates to target
## TODO: Either write the full alphabet, or constraint the user grid size to our list
## TODO: the max size of the grid would be the letters in the alphabet?
alphabet = ["a", "b", "c", "d", "e"]
user_x = input(f"Which row are you targeting? {alphabet[0]} - {alphabet[-1]} ")
user_y = int(input(f"Which column are you targeting? 1 - {grid_size}"))
## validate the user input
if user_x not in alphabet or user_y < 1 or user_y > grid_size:
print("You have provided values outside of the range. Please try again")
continue
## locate the user's target
print(alphabet, user_x, alphabet.index(user_x))
target = map[alphabet.index(user_x)][user_y - 1]
if target:
## tell them it is a hit, add to the hit array, and set target to false
print("Direct hit! You sunk my battleship!")
target = False
hits.append([user_x, user_y])
else:
## tell them it is a miss, add to the miss array
misses.append([user_x, user_y])
print("You missed!")
## end the game if they have hit three ships
if len(hits) == 3:
keep_going = False
## print the results
print("Game over! You sunk all the battleships.")