# 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 """ # #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()