old_contents: from . import MDP
  from ..util import utility
  
  
  class GameMDP(MDP):
      '''
      A Markov Decision Process for a Game. Converts a game into an MPD by
      using a deterministic player as an opponent.
      '''
  
      def __init__(self, game, opp_player, opp_idx):
          '''
          opp_player: the opponent player
          opp_idx: the idx of the opponent player in the game
          '''
          self._game = game
          self._opp_player = opp_player
          self._opp_idx = opp_idx
          self._agent_idx = opp_idx ^ 1
          self._states = {}
  
      def __str__(self):
          return '<MDP states={}>'.format(len(self.states))
  
      #######
      # MDP #
      #######
  
      def actions(self, game):
          return game.legal_moves()
  
      def is_terminal(self, game):
          return game.is_over()
  
      def reward(self, game, move, next_game):
          return utility(next_game, self._agent_idx) if next_game.is_over() else 0
  
      def start_state(self):
          new_game = self._game.copy()
          if not new_game.is_over() and new_game.cur_player() == self._opp_idx:
              chosen_move = self._opp_player.choose_move(new_game)
              new_game.make_move(chosen_move)
          return new_game
  
      def states(self):
          if not self._states:
              def generate_states(game):
                  '''Generates all the states for the game'''
                  if game not in self._states:
                      self._states[game] = game
                  for move in game.legal_moves():
                      new_game = game.copy().make_move(move)
                      generate_states(new_game)
              generate_states(self._game)
          return self._states
  
      def transitions(self, game, move):
          if game.is_over():
              return []
          new_game = game.copy().make_move(move)
          if not new_game.is_over() and new_game.cur_player() == self._opp_idx:
              chosen_move = self._opp_player.choose_move(new_game)
              new_game.make_move(chosen_move)
          return [(new_game, 1.0)]
  
new_contents: from . import MDP
  from ..util import utility
  
  
  class GameMDP(MDP):
      '''
      A Markov Decision Process for a Game. Converts a game into an MPD by
      making an opponent with fixed behavior part of the environment.
      '''
  
      def __init__(self, game, opp_player, opp_idx):
          '''
          opp_player: the opponent player
          opp_idx: the idx of the opponent player in the game
          '''
          self._game = game
          self._opp_player = opp_player
          self._opp_idx = opp_idx
          self._agent_idx = opp_idx ^ 1
          self._states = {}
  
      def __str__(self):
          return '<MDP states={}>'.format(len(self.states))
  
      #######
      # MDP #
      #######
  
      def actions(self, game):
          return game.legal_moves()
  
      def is_terminal(self, game):
          return game.is_over()
  
      def reward(self, game, move, next_game):
          return utility(next_game, self._agent_idx) if next_game.is_over() else 0
  
      def start_state(self):
          new_game = self._game.copy()
          if not new_game.is_over() and new_game.cur_player() == self._opp_idx:
              chosen_move = self._opp_player.choose_move(new_game)
              new_game.make_move(chosen_move)
          return new_game
  
      def states(self):
          if not self._states:
              def generate_states(game):
                  '''Generates all the states for the game'''
                  if game not in self._states:
                      self._states[game] = game
                  for move in game.legal_moves():
                      new_game = game.copy().make_move(move)
                      generate_states(new_game)
              generate_states(self._game)
          return self._states
  
      def transitions(self, game, move):
          if game.is_over():
              return []
          new_game = game.copy().make_move(move)
          if not new_game.is_over() and new_game.cur_player() == self._opp_idx:
              chosen_move = self._opp_player.choose_move(new_game)
              new_game.make_move(chosen_move)
          return [(new_game, 1.0)]
  
subject: Comment in GameMDP