feat: working version
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
__pycache__
|
||||||
4
constants.py
Normal file
4
constants.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
BOARD_WIDTH = 6
|
||||||
|
BOARD_HEIGHT = 6
|
||||||
|
ROW_NUMBERS = ['1', '2', '3', '4', '5', '6']
|
||||||
|
COLUMN_LETTERS = ['A', 'B', 'C', 'D', 'E', 'F']
|
||||||
160
main.py
Normal file
160
main.py
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
from constants import BOARD_WIDTH, BOARD_HEIGHT, COLUMN_LETTERS, ROW_NUMBERS
|
||||||
|
from print_helper import printBoard, bcolors
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
def generateShips():
|
||||||
|
ships: list[int] = []
|
||||||
|
|
||||||
|
for x in range(BOARD_WIDTH):
|
||||||
|
for y in range(BOARD_HEIGHT):
|
||||||
|
ships.append(0)
|
||||||
|
|
||||||
|
return ships
|
||||||
|
|
||||||
|
|
||||||
|
def fillShipsRandomly(ships: list[int], shipCount: int = 6):
|
||||||
|
indicies: list[int] = []
|
||||||
|
|
||||||
|
for i in range(BOARD_WIDTH * BOARD_HEIGHT):
|
||||||
|
indicies.append(i)
|
||||||
|
|
||||||
|
for i in range(shipCount):
|
||||||
|
randomIndex = random.randint(0, len(indicies) - 1)
|
||||||
|
ships[indicies[randomIndex]] = 1
|
||||||
|
|
||||||
|
indicies.pop(randomIndex)
|
||||||
|
|
||||||
|
|
||||||
|
def getShipIndex(x: int, y: int):
|
||||||
|
return x + y * BOARD_WIDTH
|
||||||
|
|
||||||
|
|
||||||
|
def isShip(ship: int):
|
||||||
|
return ship == 1
|
||||||
|
|
||||||
|
|
||||||
|
def parseBoardInput(boardInput: str):
|
||||||
|
if len(boardInput) != 2:
|
||||||
|
return None
|
||||||
|
|
||||||
|
column = boardInput[0]
|
||||||
|
|
||||||
|
if column not in COLUMN_LETTERS:
|
||||||
|
return None
|
||||||
|
|
||||||
|
row = boardInput[1]
|
||||||
|
|
||||||
|
if row not in ROW_NUMBERS:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return (COLUMN_LETTERS.index(column), ROW_NUMBERS.index(row))
|
||||||
|
|
||||||
|
|
||||||
|
def printPlayerBoard(board: list[int]):
|
||||||
|
print("\nYour board:")
|
||||||
|
printBoard(board)
|
||||||
|
|
||||||
|
|
||||||
|
def printEnemyBoard(board: list[int], hideShips: bool = True):
|
||||||
|
print("\nEnemy's board:")
|
||||||
|
printBoard(board, hideShips)
|
||||||
|
|
||||||
|
|
||||||
|
def remainingShips(board: list[int]):
|
||||||
|
ships = list(filter(isShip, board))
|
||||||
|
|
||||||
|
return len(ships)
|
||||||
|
|
||||||
|
|
||||||
|
def __main__():
|
||||||
|
print(f"{bcolors.FAIL}{bcolors.BOLD}Battleships{bcolors.ENDC}")
|
||||||
|
# 0 -> our board
|
||||||
|
# 1 -> the enemy board
|
||||||
|
boards = [generateShips(), generateShips()]
|
||||||
|
fillShipsRandomly(boards[1])
|
||||||
|
|
||||||
|
ships = list(filter(isShip, boards[0]))
|
||||||
|
|
||||||
|
while (len(ships) < 6):
|
||||||
|
printBoard(boards[0])
|
||||||
|
shipInput = input("Where would you like to place a ship (e.g. C4)?\n")
|
||||||
|
|
||||||
|
parsed = parseBoardInput(shipInput)
|
||||||
|
|
||||||
|
if parsed is None:
|
||||||
|
print("Invalid input. Please provide a location from A1-F6")
|
||||||
|
continue
|
||||||
|
|
||||||
|
(x, y) = parsed
|
||||||
|
|
||||||
|
boards[0][getShipIndex(x, y)] = 1
|
||||||
|
ships = list(filter(isShip, boards[0]))
|
||||||
|
|
||||||
|
print("\n")
|
||||||
|
|
||||||
|
turnIndex = 0
|
||||||
|
while remainingShips(boards[(turnIndex + 1) % 2]) > 0:
|
||||||
|
newTurnIndex = (turnIndex + 1) % 2
|
||||||
|
validTargetIndices: list[int] = []
|
||||||
|
|
||||||
|
enemyBoard = boards[(turnIndex + 1) % 2]
|
||||||
|
for i in range(len(enemyBoard)):
|
||||||
|
if enemyBoard[i] < 2:
|
||||||
|
validTargetIndices.append(i)
|
||||||
|
|
||||||
|
targetIndex = -1
|
||||||
|
|
||||||
|
if turnIndex == 1:
|
||||||
|
randomIndex = random.randint(0, len(validTargetIndices) - 1)
|
||||||
|
targetIndex = validTargetIndices[randomIndex]
|
||||||
|
else:
|
||||||
|
printEnemyBoard(boards[(turnIndex + 1) % 2])
|
||||||
|
|
||||||
|
parsed = None
|
||||||
|
|
||||||
|
while parsed is None:
|
||||||
|
targetInput = input(
|
||||||
|
"\nWhere would you like to shoot (e.g. C4)?\n")
|
||||||
|
|
||||||
|
parsed = parseBoardInput(targetInput)
|
||||||
|
|
||||||
|
if parsed is None:
|
||||||
|
print("Invalid input. Please provide a location from A1-F6")
|
||||||
|
continue
|
||||||
|
|
||||||
|
(x, y) = parsed
|
||||||
|
targetIndex = getShipIndex(x, y)
|
||||||
|
|
||||||
|
cellValue = enemyBoard[targetIndex]
|
||||||
|
newCellValue = 3
|
||||||
|
|
||||||
|
# hit
|
||||||
|
if cellValue == 1:
|
||||||
|
newCellValue = 2
|
||||||
|
newTurnIndex = turnIndex
|
||||||
|
|
||||||
|
enemyBoard[targetIndex] = newCellValue
|
||||||
|
|
||||||
|
if cellValue != 1:
|
||||||
|
if turnIndex == 0:
|
||||||
|
printEnemyBoard(boards[(turnIndex + 1) % 2])
|
||||||
|
else:
|
||||||
|
printPlayerBoard(boards[(turnIndex + 1) % 2])
|
||||||
|
|
||||||
|
turnIndex = newTurnIndex
|
||||||
|
|
||||||
|
print("\n" + "—" * 13 + "\n")
|
||||||
|
|
||||||
|
printEnemyBoard(boards[1], False)
|
||||||
|
printPlayerBoard(boards[0])
|
||||||
|
|
||||||
|
if remainingShips(boards[0]) > 0:
|
||||||
|
print(f"{bcolors.OKGREEN}You win!{bcolors.ENDC}")
|
||||||
|
else:
|
||||||
|
print(f"{bcolors.FAIL}You lose!{bcolors.ENDC}")
|
||||||
|
|
||||||
|
print("\n" + "—" * 13)
|
||||||
|
|
||||||
|
|
||||||
|
__main__()
|
||||||
45
print_helper.py
Normal file
45
print_helper.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
from constants import BOARD_WIDTH, BOARD_HEIGHT, ROW_NUMBERS, COLUMN_LETTERS
|
||||||
|
|
||||||
|
|
||||||
|
class bcolors:
|
||||||
|
HEADER = '\033[95m'
|
||||||
|
OKBLUE = '\033[94m'
|
||||||
|
OKCYAN = '\033[96m'
|
||||||
|
OKGREEN = '\033[92m'
|
||||||
|
WARNING = '\033[93m'
|
||||||
|
FAIL = '\033[91m'
|
||||||
|
ENDC = '\033[0m'
|
||||||
|
BOLD = '\033[1m'
|
||||||
|
UNDERLINE = '\033[4m'
|
||||||
|
|
||||||
|
|
||||||
|
characterPrefixes: list[str] = [bcolors.OKBLUE,
|
||||||
|
bcolors.BOLD, bcolors.FAIL, bcolors.OKBLUE]
|
||||||
|
characters: list[str] = ['0', '#', 'X', '-']
|
||||||
|
|
||||||
|
|
||||||
|
def getShipCharacter(ship: int):
|
||||||
|
return characters[ship]
|
||||||
|
|
||||||
|
|
||||||
|
def printBoard(board: list[int], hideShips: bool = False):
|
||||||
|
i = 0
|
||||||
|
print(" ", end="")
|
||||||
|
for n in range(BOARD_WIDTH):
|
||||||
|
print(f"{bcolors.BOLD}{COLUMN_LETTERS[n]}{bcolors.ENDC} ", end="")
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
for x in range(BOARD_WIDTH):
|
||||||
|
print(f"{bcolors.BOLD}{ROW_NUMBERS[x]}{bcolors.ENDC} ", end="")
|
||||||
|
for y in range(BOARD_HEIGHT):
|
||||||
|
character = getShipCharacter(board[i])
|
||||||
|
prefix = characterPrefixes[board[i]]
|
||||||
|
|
||||||
|
if hideShips and board[i] == 1:
|
||||||
|
character = getShipCharacter(0)
|
||||||
|
prefix = characterPrefixes[0]
|
||||||
|
|
||||||
|
print(f"{prefix}{character}{bcolors.ENDC} ", end="")
|
||||||
|
i += 1
|
||||||
|
print()
|
||||||
Reference in New Issue
Block a user