Example #1
0
    def try_place_max_prob(self, root, ship):
        '''Try to place the given ship, with base coordinate <root>.
        Try to maximize the probability of the ship not being hit, using the stat model, by trying both orientations.
        Return the result.'''

        ships = [
            Ship(root[0], root[1], ship, True),
            Ship(root[0], root[1], ship, False)
        ]

        for s in sorted(ships, key=self.get_ship_prob):
            if self.try_place_ship(s):
                return True

        return False
    def stage_current_ship(self):
        '''Stage the currently selected ship in the staging area.
        If no ship selected, do nothing.'''

        ship = self._get_current_ship()
        if ship is not None:
            self._staging_panel.stage_ship(Ship(0, 0, ship, True))
Example #3
0
    def load_callback(self, event=None, fname=None, warn=True):
        '''Read the JSON game configuration from file called <code>fname</code>.
        Return a dictionary representing the parsed JSON. All the strings are Unicode.
        
        May raise KeyError if JSON is not in the expected format (see battleship.json for example).
        May raise ValueError if fails to parse file
        May raise IOError if fails to find file'''

        while fname is None or isinstance(fname, list):
            fname = tkFileDialog.askopenfilename(
                defaultextension="json",
                initialdir=os.path.join(os.getcwd(), self.SAVE_DIR),
                filetypes=[("Battleship Games", "*.json")])
            if isinstance(fname, list):
                self.game_frame.show_warning("Select one file only")

        fp = open(os.path.join(GameController.SAVE_DIR, fname), "r")
        obj = json.load(
            fp
        )["battleship"]  # do this so we don't have to reference ["battleship"] every time
        fp.close()

        if not warn or tkMessageBox.askyesno(
                "Load Game",
                "Loading another game will cause you to lose all unsaved progress. Continue?"
        ):

            self.new_game_callback()
            #TODO just for now, to see if it works
            #print obj

            # load the models

            #TODO models go here
            grids = [
                self.game_frame.my_grid._model,
                self.game_frame.their_grid._model
            ]

            # placing ships
            for grid, player in zip(grids, GameController.PLAYERS):
                for ship_name, coords in obj[player]["ships"].items():
                    s = Ship(type=str(ship_name),
                             x=coords[0],
                             y=coords[1],
                             vertical=coords[2])
                    success = grid.add(s)
                    #TODO handle the case when this fails (means bad initial config)
                    assert success

                grid.finalize(error_check=False)

            # firing shots
            for grid, player in zip(grids, GameController.PLAYERS):
                for shot in obj[player]["shots"]:
                    grid.process_shot(*shot)

            self.game_frame.redraw()
            return
Example #4
0
 def _place_ships_randomly(self):
     '''Place ships completely randomly.
     This method does not look at probabilities. Just picks random spots.'''
     
     valid_squares = set(zip(range(GridModel.SIZE), range(GridModel.SIZE)))
     i = 0
     
     while i < len(Ship.SHORT_NAMES) and len(valid_squares) > 0:
         sq = random.sample(valid_squares, 1)[0] #note that Python does not support random.choice for sets
         v = random.choice([True, False])
         ship = Ship(x=sq[0], y=sq[1], type=Ship.SHORT_NAMES[i], vertical=v)
         # try to place this ship
         if self.try_place_ship(ship):
             i += 1
             valid_squares.difference_update(set(ship.get_covering_squares()))
             
     return len(self._placements) == len(Ship.SHORT_NAMES)
Example #5
0
    def can_add_ship(self, x, y, ship, vertical):
        '''Whether the given ship can be added to the grid.
        There are actually two use cases:
            - when placing initially, consider secret ships
            - when constructing model of opponent, hide secret ships'''

        s = Ship(x, y, ship, vertical)
        return self.can_add(s)
Example #6
0
    def _place_ships_randomly(self):
        '''Place ships completely randomly.
        This method does not look at probabilities. Just picks random spots.'''

        valid_squares = set(zip(range(GridModel.SIZE), range(GridModel.SIZE)))
        i = 0

        while i < len(Ship.SHORT_NAMES) and len(valid_squares) > 0:
            sq = random.sample(valid_squares, 1)[
                0]  #note that Python does not support random.choice for sets
            v = random.choice([True, False])
            ship = Ship(x=sq[0], y=sq[1], type=Ship.SHORT_NAMES[i], vertical=v)
            # try to place this ship
            if self.try_place_ship(ship):
                i += 1
                valid_squares.difference_update(
                    set(ship.get_covering_squares()))

        return len(self._placements) == len(Ship.SHORT_NAMES)
 def _create_ships(self):
     '''Create ships on the canvas.'''
     
     self._ship_squares = {}
     
     for i, ship in enumerate(Ship.SHORT_NAMES):
         y = self.TOP_PADDING + i * (self.Y_SPACING * 2 + self.RECT_SIZE)
         s = Ship(0, 0, ship, False)
         self._c.create_text(self.LEFT_PADDING, y, text=s.get_full_name().title(), anchor=NW)
         
         self._ship_squares[ship] = [None] * s.get_size()
         
         for x in range(s.get_size()):
             self._ship_squares[ship][x] = self._c.create_rectangle(
                 self.LEFT_PADDING + x * self.RECT_SIZE,
                 y + self.Y_SPACING,
                 self.LEFT_PADDING + (x + 1) * self.RECT_SIZE,
                 y + self.Y_SPACING + self.RECT_SIZE,
                 fill=self.RECT_NULL_FILL,
                 outline="black"
             )
Example #8
0
 def stage_ship_callback(self, event=None):
     '''Move a ship to the staging area.'''
     
     #ship = get_selected_ship()
     #move ship to staging area
     #that's about it
     
     if self.game_frame.my_grid_frame.ship_panel.get_current_ship() is not None:
         s = Ship(0, 0, self.game_frame.my_grid_frame.ship_panel.get_current_ship(), True)
         self.game_frame.my_grid_frame.staging_panel.add_ship(s)
     
     pass
Example #9
0
    def make_stat_model(
        self
    ):  #, x_start=0, x_end=GridModel.SIZE, y_start=0, y_end=GridModel.SIZE):
        '''(re)compute the statistical model in the given range.'''

        # initialize all squares
        self.prelim_mark_stat_model()

        for x in range(0, GridModel.SIZE):
            for y in range(0, GridModel.SIZE):

                for ship in self._unsunk_ships:
                    for v in [True, False]:
                        s = Ship(x, y, ship, v)
                        self.add_ship_to_stat_model(s)
Example #10
0
    def add_ship(self, x, y, ship, vertical, callback=None):
        '''Add a ship at (x, y). Vertical is the orientation - True of False.'''

        # sometimes nothing is selected, but grid is pressed.
        # ignore these events
        if ship is None:
            return False

        result = self._model.can_add_ship(x, y, ship, vertical)
        if result:
            if ship in self._model._ships:
                prev_ship = self._model._ships[ship]
                for sq in prev_ship.get_covering_squares():
                    self._set_tile_state(*sq)  # reset state
            self._model.add_ship(x, y, ship, vertical)
            s = Ship(x, y, ship, vertical)
            self.add_ship_to_view(s)

            if callback is not None:
                callback()

        return result
 def reset(self):
     for ship in Ship.SHORT_NAMES:
         s = Ship(0, 0, ship, False)
         self.update(s, [0] * s.get_size())
Example #12
0
    def add_ship(self, x, y, ship, vertical):
        '''Add a new ship, or change orientation of existing ship.'''

        s = Ship(x, y, ship, vertical)
        return self.add(s)