Pythondex
Python Game Programs

Making a Python Battleship Game With Source Code

Last updated June 6, 2023 by Jarvis Silva

Today in this tutorial I will show you how to make a python battleship game with source code, this is a single-player battleship game in python and it will be console-based. this game is made with grids you have to enter the row and column of the battleship you want to destroy.

Python Battleship Game Code


import random
import time

"""
    -------BATTLESHIPS-------
    Pre-reqs: Loops, Strings, Arrays, 2D Arrays, Global Variables, Methods
    How it will work:
    1. A 10x10 grid will have 8 ships of variable length randomly placed about
    2. You will have 50 bullets to take down the ships that are placed down
    3. You can choose a row and column such as A3 to indicate where to shoot
    4. For every shot that hits or misses it will show up in the grid
    5. A ship cannot be placed diagonally, so if a shot hits the rest of
        the ship is in one of 4 directions, left, right, up, and down
    6. If all ships are unearthed before using up all bullets, you win
        else, you lose
    Legend:
    1. "." = water or empty space
    2. "O" = part of ship
    3. "X" = part of ship that was hit with bullet
    4. "#" = water that was shot with bullet, a miss because it hit no ship
"""

# Global variable for grid
grid = [[]]
# Global variable for grid size
grid_size = 10
# Global variable for number of ships to place
num_of_ships = 2
# Global variable for bullets left
bullets_left = 50
# Global variable for game over
game_over = False
# Global variable for number of ships sunk
num_of_ships_sunk = 0
# Global variable for ship positions
ship_positions = [[]]
# Global variable for alphabet
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"


def validate_grid_and_place_ship(start_row, end_row, start_col, end_col):
    """Will check the row or column to see if it is safe to place a ship there"""
    global grid
    global ship_positions

    all_valid = True
    for r in range(start_row, end_row):
        for c in range(start_col, end_col):
            if grid[r][c] != ".":
                all_valid = False
                break
    if all_valid:
        ship_positions.append([start_row, end_row, start_col, end_col])
        for r in range(start_row, end_row):
            for c in range(start_col, end_col):
                grid[r][c] = "O"
    return all_valid


def try_to_place_ship_on_grid(row, col, direction, length):
    """Based on direction will call helper method to try and place a ship on the grid"""
    global grid_size

    start_row, end_row, start_col, end_col = row, row + 1, col, col + 1
    if direction == "left":
        if col - length < 0:
            return False
        start_col = col - length + 1

    elif direction == "right":
        if col + length >= grid_size:
            return False
        end_col = col + length

    elif direction == "up":
        if row - length < 0:
            return False
        start_row = row - length + 1

    elif direction == "down":
        if row + length >= grid_size:
            return False
        end_row = row + length

    return validate_grid_and_place_ship(start_row, end_row, start_col, end_col)


def create_grid():
    """Will create a 10x10 grid and randomly place down ships
       of different sizes in different directions"""
    global grid
    global grid_size
    global num_of_ships
    global ship_positions

    random.seed(time.time())

    rows, cols = (grid_size, grid_size)

    grid = []
    for r in range(rows):
        row = []
        for c in range(cols):
            row.append(".")
        grid.append(row)

    num_of_ships_placed = 0

    ship_positions = []

    while num_of_ships_placed != num_of_ships:
        random_row = random.randint(0, rows - 1)
        random_col = random.randint(0, cols - 1)
        direction = random.choice(["left", "right", "up", "down"])
        ship_size = random.randint(3, 5)
        if try_to_place_ship_on_grid(random_row, random_col, direction, ship_size):
            num_of_ships_placed += 1


def print_grid():
    """Will print the grid with rows A-J and columns 0-9"""
    global grid
    global alphabet

    debug_mode = True

    alphabet = alphabet[0: len(grid) + 1]

    for row in range(len(grid)):
        print(alphabet[row], end=") ")
        for col in range(len(grid[row])):
            if grid[row][col] == "O":
                if debug_mode:
                    print("O", end=" ")
                else:
                    print(".", end=" ")
            else:
                print(grid[row][col], end=" ")
        print("")

    print("  ", end=" ")
    for i in range(len(grid[0])):
        print(str(i), end=" ")
    print("")


def accept_valid_bullet_placement():
    """Will get valid row and column to place bullet shot"""
    global alphabet
    global grid

    is_valid_placement = False
    row = -1
    col = -1
    while is_valid_placement is False:
        placement = input("Enter row (A-J) and column (0-9) such as A3: ")
        placement = placement.upper()
        if len(placement) <= 0 or len(placement) > 2:
            print("Error: Please enter only one row and column such as A3")
            continue
        row = placement[0]
        col = placement[1]
        if not row.isalpha() or not col.isnumeric():
            print("Error: Please enter letter (A-J) for row and (0-9) for column")
            continue
        row = alphabet.find(row)
        if not (-1 < row < grid_size):
            print("Error: Please enter letter (A-J) for row and (0-9) for column")
            continue
        col = int(col)
        if not (-1 < col < grid_size):
            print("Error: Please enter letter (A-J) for row and (0-9) for column")
            continue
        if grid[row][col] == "#" or grid[row][col] == "X":
            print("You have already shot a bullet here, pick somewhere else")
            continue
        if grid[row][col] == "." or grid[row][col] == "O":
            is_valid_placement = True

    return row, col


def check_for_ship_sunk(row, col):
    """If all parts of a shit have been shot it is sunk and we later increment ships sunk"""
    global ship_positions
    global grid

    for position in ship_positions:
        start_row = position[0]
        end_row = position[1]
        start_col = position[2]
        end_col = position[3]
        if start_row <= row <= end_row and start_col <= col <= end_col:
            # Ship found, now check if its all sunk
            for r in range(start_row, end_row):
                for c in range(start_col, end_col):
                    if grid[r][c] != "X":
                        return False
    return True


def shoot_bullet():
    """Updates grid and ships based on where the bullet was shot"""
    global grid
    global num_of_ships_sunk
    global bullets_left

    row, col = accept_valid_bullet_placement()
    print("")
    print("----------------------------")

    if grid[row][col] == ".":
        print("You missed, no ship was shot")
        grid[row][col] = "#"
    elif grid[row][col] == "O":
        print("You hit!", end=" ")
        grid[row][col] = "X"
        if check_for_ship_sunk(row, col):
            print("A ship was completely sunk!")
            num_of_ships_sunk += 1
        else:
            print("A ship was shot")

    bullets_left -= 1


def check_for_game_over():
    """If all ships have been sunk or we run out of bullets its game over"""
    global num_of_ships_sunk
    global num_of_ships
    global bullets_left
    global game_over

    if num_of_ships == num_of_ships_sunk:
        print("Congrats you won!")
        game_over = True
    elif bullets_left <= 0:
        print("Sorry, you lost! You ran out of bullets, try again next time!")
        game_over = True


def main():
    """Main entry point of application that runs the game loop"""
    global game_over

    print("-----Welcome to Battleships-----")
    print("You have 50 bullets to take down 8 ships, may the battle begin!")

    create_grid()

    while game_over is False:
        print_grid()
        print("Number of ships remaining: " + str(num_of_ships - num_of_ships_sunk))
        print("Number of bullets left: " + str(bullets_left))
        shoot_bullet()
        print("----------------------------")
        print("")
        check_for_game_over()


if __name__ == '__main__':
    """Will only be called when program is run from terminal or an IDE like PyCharms"""
    main()

Above is the code for a battleship game in python, It is made using python functions and if-else statements, you can always modify the code and add extra features and functionality.

As I have said you can use an online compiler or run it on your computer if you don't have python setup then you can refer to this guide: Setting up python on a computer.

After running the above code below is an example console output of this game


-----Welcome to Battleships-----
You have 50 bullets to take down 8 ships, may the battle begin!
A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . O . . . .
D) . . . . . O . . . .
E) . . . . . O . . . .
F) . . O . . O . . . .
G) . . O . . O . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 2
Number of bullets left: 50
Enter row (A-J) and column (0-9) such as A3: D5

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . O . . . .
D) . . . . . X . . . .
E) . . . . . O . . . .
F) . . O . . O . . . .
G) . . O . . O . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 2
Number of bullets left: 49
Enter row (A-J) and column (0-9) such as A3: C5

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . O . . . .
F) . . O . . O . . . .
G) . . O . . O . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 2
Number of bullets left: 48
Enter row (A-J) and column (0-9) such as A3: E5

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . O . . O . . . .
G) . . O . . O . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 2
Number of bullets left: 47
Enter row (A-J) and column (0-9) such as A3: F5

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . O . . X . . . .
G) . . O . . O . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 2
Number of bullets left: 46
Enter row (A-J) and column (0-9) such as A3: G5

----------------------------
You hit! A ship was completely sunk!
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . O . . X . . . .
G) . . O . . X . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 1
Number of bullets left: 45
Enter row (A-J) and column (0-9) such as A3: F2

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . X . . X . . . .
G) . . O . . X . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 1
Number of bullets left: 44
Enter row (A-J) and column (0-9) such as A3: G2

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . X . . X . . . .
G) . . X . . X . . . .
H) . . O . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 1
Number of bullets left: 43
Enter row (A-J) and column (0-9) such as A3: H2

----------------------------
You hit! A ship was shot
----------------------------

A) . . . . . . . . . .
B) . . . . . . . . . .
C) . . . . . X . . . .
D) . . . . . X . . . .
E) . . . . . X . . . .
F) . . X . . X . . . .
G) . . X . . X . . . .
H) . . X . . . . . . .
I) . . O . . . . . . .
J) . . . . . . . . . .
   0 1 2 3 4 5 6 7 8 9
Number of ships remaining: 1
Number of bullets left: 42
Enter row (A-J) and column (0-9) such as A3: I2

----------------------------
You hit! A ship was completely sunk!
----------------------------

Congrats you won!

As you can see there is a grid with rows and columns and O marked as ships you have 50 bullets to destroy all the ships so you enter the row and column of the ship to destroy them.

How does it work

This is a very simple game to play but there is a lot of things which you need to understand below are some of the things you need to know about this game:

  • A 10x10 grid will have 8 ships of variable length randomly placed about
  • You will have 50 bullets to take down the ships that are placed down
  • You can choose a row and column such as A3 to indicate where to shoot
  • For every shot that hits or misses it will show up in the grid
  • A ship cannot be placed diagonally, so if a shot hits the rest of the ship is in one of 4 directions, left, right, up, and down
  • If all ships are unearthed before using up all bullets, you win else, you lose

Below are symbols used to represent obstacles or components in the game:

  • "." = water or empty space
  • "O" = part of ship
  • "X" = part of ship that was hit with a bullet
  • "#" = water that was shot with a bullet, a miss because it hit no ship

So these were some of the things you needed to know about this game, I hope you understood and ran this game successfully on your computer.

Here are some more python games tutorial for you:

I hope you found what you were looking for and if you want more python projects like this then stay with us by joining our Telegram channel.

Thanks for reading, have a nice day 🙂