]> gitweb.michael.orlitzky.com - dunshire.git/blobdiff - symmetric_linear_game.py
Play with the error/solution formatting some more.
[dunshire.git] / symmetric_linear_game.py
index a33c34530b4b3ce23f4d2315128499994d741c94..694e09f6a9f21930ee028d732f96ddda9cdbb553 100644 (file)
@@ -1,12 +1,59 @@
 from cvxopt import matrix, printing, solvers
 
 from cones import CartesianProduct
-from errors import GameUnsolvableException, GameValueMismatchException
+from errors import GameUnsolvableException
 from matrices import append_col, append_row, identity
 
 printing.options['dformat'] = '%.7f'
 solvers.options['show_progress'] = False
 
+
+class Solution:
+    """
+    A representation of the solution of a linear game. It should contain
+    the value of the game, and both players' strategies.
+    """
+    def __init__(self, game_value, p1_optimal, p2_optimal):
+        self._game_value = game_value
+        self._player1_optimal = p1_optimal
+        self._player2_optimal = p2_optimal
+
+    def __str__(self):
+        """
+        Return a string describing the solution of a linear game.
+
+        The three data that are described are,
+
+          * The value of the game.
+          * The optimal strategy of player one.
+          * The optimal strategy of player two.
+
+        """
+
+        tpl = 'Game value: {:.7f}\n' \
+              'Player 1 optimal:{:s}\n' \
+              'Player 2 optimal:{:s}\n'
+
+        p1 = '\n{!s}'.format(self.player1_optimal())
+        p1 = '\n  '.join(p1.splitlines())
+        p2 = '\n{!s}'.format(self.player2_optimal())
+        p2 = '\n  '.join(p2.splitlines())
+
+        return tpl.format(self.game_value(), p1, p2)
+
+
+    def game_value(self):
+        return self._game_value
+
+
+    def player1_optimal(self):
+        return self._player1_optimal
+
+
+    def player2_optimal(self):
+        return self._player2_optimal
+
+
 class SymmetricLinearGame:
     """
     A representation of a symmetric linear game.
@@ -65,19 +112,13 @@ class SymmetricLinearGame:
                       append_col(self._e1, -self._L))
         A = matrix([0, self._e1], (1, K.dimension() + 1), 'd')
 
-        soln = solvers.conelp(c, G, h, C.cvxopt_dims(), A, b)
-
-        #if soln['status'] != 'optimal':
-        raise GameUnsolvableException(soln['status'], soln)
+        soln_dict = solvers.conelp(c, G, h, C.cvxopt_dims(), A, b)
 
-        p1_value = soln['x'][0]
-        p2_value = soln['y'][0]
-        p1_strategy = soln['x'][1:]
-        p2_strategy = soln['z'][self._K.dimension():]
+        if soln_dict['status'] != 'optimal':
+            raise GameUnsolvableException(soln_dict)
 
-        #if p1_value != p2_value:
-        raise GameValueMismatchException(p1_value, p2_value, soln)
+        p1_value = soln_dict['x'][0]
+        p1_optimal = soln_dict['x'][1:]
+        p2_optimal = soln_dict['z'][self._K.dimension():]
 
-        return {'game value': p1_value,
-                'player one': p1_strategy,
-                'player two': p2_strategy}
+        return Solution(p1_value, p1_optimal, p2_optimal)