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:
- Make a Minecraft Game in Python With Source Code
- Guess Number Higher OR Lower Python Game
- Create Fruit Ninja Game In Python With Code
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 🙂