Untitled
4 years ago in Python
# Battleships.py ?/?/2016 Amos Asody (c)
# Sink Battleships by choosing tiles on a board
#
# version: 2
# updated:
#
# code:
import os, sys
from random import randint
from clear import clear
class Game(Object):
""" Game class that holds all the game methods """
def __init__(self):
""" Init method """
#<Default settings
self.board_size = 5 #board size
self.ship_min_size = 2 #ship min size
self.ship_max_size = 4 #ship max size
self.turns = 10 #number of turns
self.debug = 0 #set debug
self.number_of_ships = 2 #set number of ship
self.pvp = 1 #set player vs player mode
self.pvc = 0 #set player vs computer mode
#>
#config file path
self.config_file = os.path.join(os.path.dirname(sys.argv[0]), "Battleships.ini")
def read_settings(self):
""" Open settings file """
try:
with open(self.config_file, "r") as config:
settings = config.readlines()
for line in settings:
if not line.startswith("#"):
setting, value = line.split("=")
if setting == "board_size":
self.board_size = int(value.strip())
elif setting == "ship_min_size":
self.ship_min_size = int(value.strip())
elif setting == "ship_max_size":
self.ship_max_size = int(value.strip())
elif setting == "turns":
self.turns = int(value.strip())
elif setting == "debug":
self.debug = int(value.strip())
except IOError as error_message:
print "Cannot find Battleships.ini\n<{0})>".format(error_message)
raw_input("\nPress any key to load default settings")
def generate_board(self):
""" Generate the board """
self.board = [["O"] * self.board_size for x in range(self.board_size)]
def print_board(self, message):
""" Prints the board, custom message and turns remaining """
#clear screen
clear()
#debug
self._show_ship()
#print message
print "{0}".format(message)
#print board
for row in self.board:
print " ".join(row)
#print remaining turns
print "Turns remaining: {0}".format(self.turns - self.turn)
def user_input(self):
""" Get user input and do checks """
while 1:
try:
#guess row
self.guess_row = int(raw_input("Guess Row:")) - 1
if (self.guess_row < 0) or (self.guess_row > (self.board_size - 1)):
self.print_board("Oops, that's not even in the ocean...")
continue
#guess column
self.guess_col = int(raw_input("Guess Col:")) - 1
if (self.guess_col < 0) or (self.guess_col > (self.board_size - 1)):
self.print_board("Oops, that's not even in the ocean...")
continue
#check if guessed already
if self.board[self.guess_row][self.guess_col] in ["X", "V"]:
self.print_board("You guessed that one already.")
continue
except (SyntaxError, NameError, ValueError):
self.print_board("Please enter digits.")
else:
break
def new_game(self):
""" New game main loop """
#set default values
self.directions = [] #ship possible directions
self.hits = 0 #hit counter
self.won = 0 #Won flag
self.guess_row = 0 #user inputs - row
self.guess_col = 0 #user inputs - column
self.turn = 0 #current turn
#read config file
self.read_settings()
#generate the board
self.generate_board()
#generate the ship
self.generate_ship()
#main game loop
self.print_board("Let's play Battleships!")
while 1:
#asks for coordinates from user
self.user_input()
#increase turn by 1
self.turn += 1
#check if ship is hit
self.check_ship()
#check if game won or lost
if self.won == 1:
self.print_board("You sank the battleship!")
break
if self.turn == self.turns:
self.print_board("Game Over!")
break
class BattleShips(object):
""" Generates the battleship and it's attributes """
def generate_ship(self):
""" Generate the ship array based on possible directions """
#initialize ship
while self.directions == []:
#ship length
self.ship_length = randint(self.ship_min_size, self.ship_max_size)
#ship starting coordinates
self.ship = [[randint(0, self.board_size - 1), randint(0, self.board_size - 1)]]
#check for room down the board
if (self.ship_length + self.ship[0][0]) <= self.board_size:
self.directions.append("down")
#checks for room up the board
if ((self.ship[0][0] + 1) - self.ship_length) >= 0:
self.directions.append("up")
#check for room to the right
if (self.ship_length + self.ship[0][1]) <= self.board_size:
self.directions.append("right")
#checks for room to the left
if ((self.ship[0][1] + 1) - self.ship_length) >= 0:
self.directions.append("left")
else:
#set a direction
self.ship_direction = self.directions[randint(0, len(self.directions) - 1)]
#build the ship array
if self.ship_direction == "down":
for i in range(self.ship_length - 1):
self.ship.append([self.ship[i][0] + 1, self.ship[0][1]])
elif self.ship_direction == "up":
for i in range(self.ship_length - 1):
self.ship.append([self.ship[i][0] - 1, self.ship[0][1]])
elif self.ship_direction == "right":
for i in range(self.ship_length - 1):
self.ship.append([self.ship[0][0], self.ship[i][1] + 1])
elif self.ship_direction == "left":
for i in range(self.ship_length - 1):
self.ship.append([self.ship[0][0], self.ship[i][1] - 1])
def check_ship(self):
""" Check if user input scope the ship coordinates """
#check if user input hit the ship
if [self.guess_row, self.guess_col] in self.ship:
self.board[self.guess_row][self.guess_col] = "V"
self.hits += 1
self.print_board("You hit the battleship!")
else:
self.board[self.guess_row][self.guess_col] = "X"
self.print_board("You missed the battleship!")
#check if won
if self.hits == len(self.ship):
self.won = 1
def _show_ship(self):
""" Prints ship details and various vars - For debugging """
if self.debug == 1:
#print ship details. ###for debug purpose###
print "Length:{0},Location:({1}),Direction:{2},Input:({3},{4})".\
format(self.ship_length, self.ship, self.ship_direction, self.guess_row + 1,\
self.guess_col + 1)
def main():
""" Main function """
#generate game object
game = BattleShips()
while 1:
#start new game
game.new_game()
#check if user wants to play again
if raw_input("\nPlay Again (y/n)? ") != "y":
break
if __name__ == "__main__":
#run main if script is executed directly
main()