Skip to content

Instantly share code, notes, and snippets.

@Levi-Lesches
Created April 19, 2020 04:17
Show Gist options
  • Save Levi-Lesches/3c439e2e2d436f3f304ce1610744a68d to your computer and use it in GitHub Desktop.
Save Levi-Lesches/3c439e2e2d436f3f304ce1610744a68d to your computer and use it in GitHub Desktop.
A Python implementation of Battleship (deliberately avoiding OOP)
"""
Battleship
Concepts used:
- constants
- functions (I/O)
- if on one line
- random.choice and random.shuffle
- printing with an `end`
- tuples
- is
- break
- ternary operator
- 2-d lists
- any and all
- list comprehension
- map and lambda
"""
from random import choice, shuffle
BOARD_SIZE = 10
EMPTY_CELL = "_"
SHIP_OR_HIT = "!"
MISS = "X"
SHIPS = [5, 4, 3, 3, 2]
def generate_map() -> [list]:
return [[None for _ in range(BOARD_SIZE)] for __ in range(BOARD_SIZE)]
def print_board(board):
for row in board:
for col in row:
if col is None: letter = EMPTY_CELL
elif col is True: letter = SHIP_OR_HIT
elif col is False: letter = MISS
print(letter, end = " ")
print()
def place_ship(board, ship_length):
horizontal = choice([True, False])
available_rows = list(range(len(board)))
shuffle(available_rows)
for row in available_rows:
ship_coordinates = None
available_cols = list(range(len(board [row])))
shuffle(available_cols)
for col in available_cols:
if (horizontal and len(board [row]) - col >= ship_length):
available_coordinates = [
(row, col + offset) for offset in range(ship_length)
]
if all(
board [coordinate [0]] [coordinate [1]] is None
for coordinate in available_coordinates
): ship_coordinates = available_coordinates
elif(not horizontal and len(board) - row >= ship_length):
available_coordinates = [
(row + offset, col) for offset in range(ship_length)
]
if all(
board [coordinate [0]] [coordinate [1]] is None
for coordinate in available_coordinates
): ship_coordinates = available_coordinates
if ship_coordinates is not None: break
if ship_coordinates is not None:
for coordinate in ship_coordinates:
board [coordinate [0]] [coordinate [1]] = True
break
return ship_coordinates
def pick_coordinate(guesses):
available_coordinates = [
(row, col)
for row in guesses
for col in row
if col is None
]
return choice(available_coordinates)
def did_hit(coordinate, board):
return board [coordinate [0]] [coordinate [1]] is True
def mark_result(coordinate, result, guesses):
guesses [coordinate [0]] [coordinate [1]] = result
def setup_board(board):
return [
place_ship(board, ship)
for ship in SHIPS
]
def still_playing(ship_positions):
return any(ship for ship in ship_positions)
def get_coordinate_from_user():
return tuple(map(lambda num: int(num) - 1, input("Enter a coordinate [row, col]: ").split(", ")))
def main():
computer_board = generate_map()
computer_guesses = generate_map()
user_guesses = generate_map()
ship_positions = setup_board(computer_board)
computer_turn = False
print_board(computer_board)
print()
while still_playing(ship_positions):
if not computer_turn:
print_board(user_guesses)
coordinate = get_coordinate_from_user()
result = did_hit(coordinate, computer_board)
print("Hit!" if result else "Miss!")
mark_result(coordinate, result, user_guesses)
if result:
for ship in ship_positions:
if coordinate in ship:
ship.remove(coordinate)
if not ship: print("You sunk my ship!")
print("Game over! You win!")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment