Ejemplo n.º 1
0
class Game(object):
    """
    A Game is a general abstraction for local search based games
    Known children are MinConflictsGame and SimulatedAnnealingGame
    These children should be also abstract
    """

    def __init__(self):
        self.state_manager = StateManager()
        self.level = None
        self.max_steps = 0
        self.number_steps = 0
        self.max_time = 120
        self.date_begin = 0
        self.verbose = False

    def generate(self, level):
        """
        Generates a new game. Level determines how hard the game will be
        """

        levels = {
            "easy": GameLevel.EASY,
            "medium": GameLevel.MEDIUM,
            "hard": GameLevel.HARD
        }

        assert(level in levels)

        self.level = levels[level]
        self.max_steps = 10000
        self.state_manager.build_new_game(self.level)
        self.state_manager.indexing_constraints()
        self.state_manager.generate_game()

    def run(self):
        """
        Runs the current game.
        It's just an execution of algorithms in the case of MinConflictsGame
        and SimulatedAnnealingGame classes
        """

        pass

    EVAL_MAX = 1000.0

    def evaluate(self, state):
        """
        Evaluates a state (objective function)
        Min value is 1 and max value is EVAL_MAX
        """

        # The idea is to subtract the number of violated constraints (NVC) to a
        # fix value (EVAL_MAX). But since the NVC can be greater than EVAL_MAX
        # we must keep 0 <= NVC <= EVAL_MAX with a rule of three.
        # There is still a problem: the number of total constraints is not
        # perfect because a constraint can modify the count with a coeff (see
        # Magic Square game with SumEqualsConstraint).
        # So here we increase this number by a coeff of 1000. It works fine
        # for this exercise but this solution is far from perfect.
        total_constraints = len(self.state_manager.constraints) * 1000
        nb_constraints = self.state_manager.count_constraint_violated(state)
        _max = Game.EVAL_MAX

        _eval = _max - (nb_constraints * _max) / total_constraints

        return max(1, _eval)

    def is_terminated(self):
        """
        Returns True if the current state is an optimal one, False else
        """

        return self.state_manager.is_optimal() or \
            self.outofsteps() or self.outoftime()

    def outofsteps(self):
        return self.number_steps >= self.max_steps

    def outoftime(self):
        return self.date_begin > 0 and \
            time() > (self.date_begin + self.max_time)

    def show_state_manager(self):
        if self.verbose:
            print self.state_manager