Ejemplo n.º 1
0
def right_click(x, y, game):
    """ Set/increment/clear the flag in this cell. """
    flag_map = DBSession.query(models.PlayerMap).filter_by(
        game_id=game.id, map_type=const.PlayerMapType.FLAG).first()

    # Get the FlagMapData, if it exists
    flag_data = DBSession.query(models.PlayerMapData).filter_by(
        player_map_id=flag_map.id, row_num=x, col_num=y).first()

    if flag_data is None:
        # UNCLICKED --> FLAG
        recorded_flag = models.PlayerMapData(
            player_map_id=flag_map.id, row_num=x, col_num=y,
            value=const.PlayerMapDataValue.FLAG)
        DBSession.add(recorded_flag)
        value = const.PlayerMapDataValue.FLAG
    else:
        if flag_data.value == const.PlayerMapDataValue.FLAG:
            # FLAG --> UNSURE
            value = const.PlayerMapDataValue.UNSURE
            flag_data.value = value
            DBSession.add(flag_data)
        else:
            # UNSURE --> UNCLICKED
            value = const.CellStates.UNCLICKED
            DBSession.delete(flag_data)
            DBSession.flush()
    return (value, game)
Ejemplo n.º 2
0
    def post(self):
        """ Creates a new Game, MineMap, and PlayerMaps. """
        # Create a MineMap
        mine_matrix = MineMatrix(const.DEFAULT_HEIGHT,
                                 width=const.DEFAULT_WIDTH,
                                 mine_number=const.DEFAULT_MINES)
        mine_map = mine_matrix.to_model()
        DBSession.add(mine_map)
        DBSession.flush()

        # Create a Game and PlayerMaps for it
        game = models.Game(mine_map=mine_map.id)
        game.player_maps = [
            models.PlayerMap(map_type=const.PlayerMapType.CLICK),
            models.PlayerMap(map_type=const.PlayerMapType.FLAG),
        ]
        DBSession.add(game)
        DBSession.flush()
        return HTTPFound(location=self.request.route_url('view_game',
                                                         game_id=game.id))
Ejemplo n.º 3
0
def cascade_reveal(start_x, start_y, mine_matrix, click_map_id):
    """ Returns the list of dicts, representing the values to reveal. """
    # Where the revealed values go. The position records the x, y coordinates
    # Faster lookup than using the reveal list of dicts
    placeholder = Matrix(mine_matrix.height, width=mine_matrix.width,
                         init_value=None)
    blank_spaces = [(start_x, start_y)]  # queue of spaces to explore
    reveal = []

    # Look around each blank space
    while(blank_spaces):
        (focus_x, focus_y) = blank_spaces.pop()
        for x in Matrix._adjacent_indices(focus_x, placeholder.height-1):
            for y in Matrix._adjacent_indices(focus_y, placeholder.width-1):

                # Have we already seen this entry?
                if (x, y) == (focus_x, focus_y) or placeholder[x][y] is not None:
                    continue  # skip this entry

                value = mine_matrix[x][y]
                # We haven't come across this entry yet, but it still may
                # already be clicked
                placeholder[x][y] = value

                # Check if there's a ClickMap entry for this datapoint
                click = DBSession.query(models.PlayerMapData).filter_by(
                    player_map_id=click_map_id, row_num=x, col_num=y).first()
                if click is None:
                    # Save a ClickMap entry for this cell
                    recorded_click = models.PlayerMapData(
                        player_map_id=click_map_id, row_num=x, col_num=y,
                        value=const.PlayerMapDataValue.CLICKED)
                    DBSession.add(recorded_click)
                    reveal.append({'x': x, 'y': y, 'value': value})

                # If the value is another blank space, save to look later
                if value is const.CellStates.CLUE[0]:
                    blank_spaces.append((x, y))

    return reveal
Ejemplo n.º 4
0
def left_click(x, y, click_map, game):
    reveal = []

    # Record a successful click on the Click Map
    recorded_click = models.PlayerMapData(
        player_map_id=click_map.id, row_num=x, col_num=y,
        value=const.PlayerMapDataValue.CLICKED)
    DBSession.add(recorded_click)

    mine_map = DBSession.query(models.MineMap).get(game.mine_map)
    mine_matrix = mine_map.to_matrix()
    value = mine_matrix[x][y]

    # If the cell contains a mine, game over
    if value is const.MineMapDataValue.MINE:
        # Update game state
        game.state = const.GameState.LOSE
        DBSession.add(game)
        DBSession.flush()
        return (value, reveal, game)

    # If a blank space got revealed, time for a cascade reveal
    if value is const.MineMapDataValue.CLUE[0]:
        reveal = cascade_reveal(x, y, mine_matrix, click_map.id)
    DBSession.flush()

    # Compare the Click matrix to the Win matrix. If the same, the game is won
    click_map = DBSession.query(models.PlayerMap).filter_by(
        game_id=game.id, map_type=const.PlayerMapType.CLICK).first()
    click_matrix = click_map.to_matrix()
    win_matrix = derive_win_matrix(game)
    if click_matrix == win_matrix:
        # Update game state
        game.state = const.GameState.WIN
        DBSession.add(game)
        DBSession.flush()
    return (value, reveal, game)