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__()