I made a battleship game for a programming class, where I only had about a week to get it done. Under this time crunch, and the fact that I don't know python very well, I made some of the code in very roundabout ways, and probably far more complicated than it needs to be.
"""
This is my program that lets you play one man battleship.
It has a board that displays the info to the player, henceforth know as the player board,
and an enemy board which is hidden from the player, know as the enemy board which is used to store ship locations.
There is also an info board that has the ship locations for each board on the corosponding line.
On the enemy board, a zero is used to represent an empty tile, while an X is a ship section.
On the player board, a zero is used to represent a unguessed tile, an M the misses, and an X for hits.
"""
import random
board = []
hits = 0
random.seed()
num = random.randrange(1, 5)
sunk = [0 , 0, 0, 0]
# Loads the enemy board
def enemyBoardLoader():
global num
file = open("board" + str(num) + ".txt")
return file.read()
#Loads the line of the info board that corosponds to the board chosen
def boardInfoLoader():
file = open("boardInfo.txt")
#Reads a line and puts it on a filler varible, as that is the only way to incremeant the readline command
for x in range(num - 1):
filler = file.readline()
return boardInfoInterp(file.readline())
#Turn the line input into a list of lists
def boardInfoInterp(boardInfo):
boardInfoList = [] #Output
shipSet = [] #Varible 1 that is used to chunk the list
shotSet = [] #Varible 2 that is used to chunk the list
x = 0
#Loop that moves it into a nested list
while x < len(boardInfo):
#If the letter the program is on is a number, it adds it to the second chunk varible
try:
shotSet.append(int(boardInfo[x]))
#If its not, it runs this code
except ValueError:
#If it reaches a comma, moves the first chunk varible to the first one, then clears the first chunk varible
if boardInfo[x] == ",":
shipSet.append(shotSet)
shotSet = []
#If it reaches a semi colon, moves the second chunk varible to the ouput, making a nested list, then clears the second chunk varible
elif boardInfo[x] == ";":
boardInfoList.append(shipSet)
shipSet = []
x += 1
return(boardInfoList)
#If a shot is on a ship, it removes that shot from the boardInfo list
def boardInfoRemover(hit):
global boardInfo
#Makes the input be in a format that the program needs
hit = str(hit)
hit = list(hit)
#Removes extra charecters from the list
while "[" in hit:
hit.remove("[")
while " " in hit:
hit.remove(" ")
while "," in hit:
hit.remove(",")
while "]" in hit:
hit.remove("]")
x = 0
#Makes the numbers left in the list numbers
while x < len(hit):
hit[x] = int(hit[x])
x += 1
x = 0
#Checks to see which shot location it was, and removes it from the boardInfo list
while x < len(boardInfo):
y = 0
while y < len(boardInfo[x]):
if boardInfo[x][y] == hit:
del boardInfo[x][y]
y += 1
x += 1
# General things done to the player board
def boardFunc(func, shot):
global board
if func == "reset": # Checks if command given was reset
# Sets default board state of 100 zeros
for x in enemyBoard:
board.append("0")
if func == "print": # Checks if command given was print
# Prints 10 rows of 10 characters
for x in range(10):
print(" ".join(board[(x * 10):((x + 1) * 10)]))
if func == "update": # Checks if command given was update
if enemyBoard[((shot[0] - 1) + (shot[1] - 1) * 10)] == "X": # If the shot location is an X on the enemy board, mark a hit on the player board
if board[((shot[0] - 1) + (shot[1] - 1) * 10)] != "X":
board[((shot[0] - 1) + (shot[1] - 1) * 10)] = "X"
boardInfoRemover(shot)
global hits
hits += 1
else:
board[((shot[0] - 1) + (shot[1] - 1) * 10)] = "M" # If the shot location is not an X on the enemy board, mark a miss on the player board
#Takes and cleans the input to prevent errors
def inputCleaner():
global y, x
num = []
repeat = True # Secondary variable to handle loops
# Checks to make sure input is 2 items instead of one
while repeat:
try:
xy = input("Were do you want to shoot your shot? (num1 num2):")
x, y = xy.split() # Gives error if its only one number
repeat = False # If there is an error, this does not run, making the loop keep running
# If error is given, runs this instead of any code left to run
except ValueError:
print("Please enter two numbers")
true = True # Primary variable to handle loops
# Main loop to check if input is right
while true:
true = False # *Starts chuckling*
try:
# Sets the variable to numbers instead of characters they came in as. If this fails, it runs the except code below
x = int(x)
y = int(y)
if y > 10 or y < 1: # Makes sure that the first number is on the board, if not asks for another number to replace it
true = True
y = input(
"Please make sure that your first number is at least 1 and no more than 10. Re-enter only your first number:")
elif x > 10 or x < 1: # Same as above, but with x
true = True
x = input(
"Please make sure that your second number is at least 1 and no more than 10. Re-enter only your second number:")
else: # If neither of the above are true, puts the numbers in the num list
num.append(int(x))
num.append(int(y))
except ValueError or TypeError: # If something other than a number is entered, it runs this code
repeat = True
# This code makes sure at least two numbers were entered
while repeat:
try:
xy = input("Please use only numbers. Enter you shot location again:")
x, y = xy.split()
repeat = False
true = True
except ValueError:
print("Please enter two numbers")
return num
#Checks if all locations on a ship have been shot
def sunkChecker():
global boardInfo
global sunk
if len(boardInfo[0]) == 0 and sunk[0] == 0:
print("You sunk the aircraft carrier.")
sunk[0] = 1
if len(boardInfo[1]) == 0 and sunk[1] == 0:
print("You sunk the battleship.")
sunk[1] = 1
if len(boardInfo[2]) == 0 and sunk [2] == 0:
print("You sunk the cruiser.")
sunk[2] = 1
if len(boardInfo[3]) == 0 and sunk[3] == 0:
print("You sunk the submarine.")
sunk[3] = 1
enemyBoard = enemyBoardLoader()
boardInfo = boardInfoLoader()
while True:
boardFunc("reset", 0)
while hits < 15: # Each board has 15 ship spots, when all are hit it breaks out of this loop
boardFunc("print", 0)
boardFunc("update", inputCleaner())
sunkChecker()
boardFunc("print", 0)
if input("YOU WON!! Would you like to play again? (y/n):") == "n":
quit()
What are some parts that could be simplified? Also, these are the specific files I have for this program.