Question

In: Computer Science

Python Language: In the CIS 41A version of Battleship, the user tries to find the computer's...

Python Language:

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:

  1. The computer asks the user to choose the size of the board, which is a square of 2, 3, or 4 rows and columns.
  2. The computer randomly chooses a spot on the board (r, c) where r = row, c = column, as the location for the battleship
  3. The computer prints the board with the correct size, and asks the user for a row and a column.
  4. If the user row and column matches (r,c), then the computer prints the grid again with an X at the found location. This means the user has found the computer's battleship.
    Otherwise the computer prints the board again with no 'X'
  5. Repeat steps 3 and 4 until the user has found the battleship
  6. Then the computer prints the number tries that the user took.

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:

  1. getNum: get a number from the user and return it
    1. prompt the user for the number with an appropriate prompt string
    2. check that the input number is between a given low and high value, inclusive, or print an error message to show the valid range, and then re-prompt until you get a valid number
  2. printBoard: print the grid based on the size from the user
  3. start with a row of column numbers going across
  4. then a row of dashes, which is the top of the board
  5. each row of the board starts with a row number, then multiple patterns of:  '|', 3 spaces, and another '|'
    which makes up each 'square' in the grid
  6. after each row of squares is a row of dashes
  7. if the battleship has been sunken by the user, then the string '  X  '  (space, X, space) is printed instead of the 3 spaces
  8. hideShip: create 2 random numbers between 1 and MAX, to serve as the coordinates for the battleship
  9. the first 2 random numbers make up the (r, c) location of the battleship
  10. you can choose to print the 2 random numbers to screen to make testing easier
  11. play: play one game until the user has sunken the battleship
  12. call the getNum function to get the size of the board from the user. Pass input arguments to the function so that it can prompt the user appropriately and print the correct range if the input is not valid
  13. call the hideShip function to determine the hidden location of the battleship
  14. call the printBoard function to print the board with no 'X' (since the user hasn't guessed yet)
  15. call the getNum function twice, once to get the row and a second time to get the column from the user. Pass input arguments to the function so that it can prompt the user appropriately and print the correct range if the input is not valid
  16. - if the user hasn't guessed the location: print the same board, and loop back to step d

- if the user successfully guessed the locations: print the board with an 'X' at the correct location, and print the number of trie

  1. main: let the user keep playing the game until the user chooses to end
  1. seed the random generator
  2. call the play function to play the game one time
  3. ask the user whether to continue, and loop back to step b if the answer is 'y' or 'Y'.
    Otherwise the program ends.

Important notes (don't miss them in your code):

  • There should be 5 functions and each function should work as described.
  • The input arguments for the functions are not fully described in this lab document, it's your job to determine what data need to be passed to the functions and what (if any) return value there is
  • Don't use global variables (1pt deduction for each global variable). Instead, pass input arguments to the functions, and catch any return value.
  • Note that there should be only one printBoard function, and it should be able to print the board without the 'X' or with the 'X'. Don't write 2 different printBoard functions.
    Likewise, there is only one getNum function, and it should be able to prompt the user and print the appropriate error message, depending on whether it's the size of the board, the row number, or the column number.
    This is how a function can make your program shorter: you write 1 function and call it 3 times, instead of writing 3 blocks of code to get the 3 values.
  • The board game (the rows and columns and row / column numbers) should line up correctly, no matter the size of the board. This is your practice with using loops.
  • Make sure to document your code:
    -- A comment at the top of the file with your name and lab number

-- A docstring (not a comment) for each function, except for the main function

Solutions

Expert Solution

from random import randint import os #Ship Class 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!")


Related Solutions

Python: In the CIS 41A version of Battleship, the user tries to find the computer's battleship...
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: The computer asks the user to choose the size of the board, which is a square of 2, 3, or 4 rows and columns. The computer randomly chooses a spot on the board (r, c) where r = row, c = column,...
Write a code to find the following in a text file (Letter). language: Python (a) Find...
Write a code to find the following in a text file (Letter). language: Python (a) Find the 20 most common words (b) How many unique words are used? (c) How many words are used at least 5 times? (d) Write the 200 most common words, and their counts, to a file. text file: Look in thy glass and tell the face thou viewest, Now is the time that face should form another, Whose fresh repair if now thou not renewest,...
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT