In [0]:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
assert sys.version_info.major == 3
import os
add_paths = True
if add_paths:
sys.path.insert(0, os.path.join(os.path.abspath(os.getcwd()), '..', '..'))
sys.path.insert(
0,
os.path.join(os.path.abspath(os.getcwd()), '..', '..', 'build', 'python'))
import pyspiel
from open_spiel.python.algorithms import cfr
from open_spiel.python.algorithms import exploitability
from open_spiel.python.algorithms import expected_game_score
from open_spiel.python.bots import uniform_random
from open_spiel.python.visualizations import treeviz
In [0]:
games_list = pyspiel.registered_names()
print("Registered games:")
print(games_list)
game = pyspiel.load_game("universal_poker")
In [0]:
"""Test that Python and C++ bots can be called by a C++ algorithm."""
from absl.testing import absltest
import numpy as np
from open_spiel.python.bots import uniform_random
game = pyspiel.load_game("leduc_poker")
bots = [
pyspiel.make_uniform_random_bot(0, 1234),
uniform_random.UniformRandomBot(1, np.random.RandomState(4321)),
]
results = np.array([
pyspiel.evaluate_bots(game.new_initial_state(), bots, iteration)
for iteration in range(10000)
])
leduc_average_results = np.mean(results, axis=0)
print(leduc_average_results)
game = pyspiel.load_game("universal_poker")
bots = [
pyspiel.make_uniform_random_bot(0, 1234),
uniform_random.UniformRandomBot(1, np.random.RandomState(4321)),
]
results = np.array([
pyspiel.evaluate_bots(game.new_initial_state(), bots, iteration)
for iteration in range(10000)
])
universal_poker_average_results = np.mean(results, axis=0)
print(universal_poker_average_results)
#np.testing.assert_allclose(universal_poker_average_results, leduc_average_results, atol=0.1)
In [0]:
universal_poker_kuhn_limit_3p = """\
GAMEDEF
limit
numPlayers = 3
numRounds = 1
blind = 1 1 1
raiseSize = 1
firstPlayer = 1
maxRaises = 1
numSuits = 1
numRanks = 4
numHoleCards = 1
numBoardCards = 0
END GAMEDEF
"""
game = pyspiel.load_game(
"universal_poker",
{"gamedef": pyspiel.GameParameter(universal_poker_kuhn_limit_3p)})
str(game)
In [0]:
# Compare exloitability for two games
players = 2
iterations = 10
print_freq = 1
def compare_exploitability(game_1, game_2):
cfr_solver_1 = cfr.CFRSolver(game_1)
cfr_solver_2 = cfr.CFRSolver(game_2)
for i in range(iterations):
cfr_solver_1.evaluate_and_update_policy()
cfr_solver_2.evaluate_and_update_policy()
if i % print_freq == 0:
conv_1 = exploitability.exploitability(game_1,
cfr_solver_1.average_policy())
conv_2 = exploitability.exploitability(game_2,
cfr_solver_2.average_policy())
print("Iteration {} exploitability of the {} vs: {}".format(
i, conv_1, conv_2))
print("Final exploitability is {} vs {}".format(conv_1, conv_2))
game_1 = pyspiel.load_game("kuhn_poker",
{"players": pyspiel.GameParameter(2)})
universal_poker_kuhn_limit_2p = """\
GAMEDEF
limit
numPlayers = 2
numRounds = 1
blind = 1 1
raiseSize = 1
firstPlayer = 1
maxRaises = 1
numSuits = 1
numRanks = 3
numHoleCards = 1
numBoardCards = 0
END GAMEDEF
"""
game_2 = pyspiel.load_game(
"universal_poker",
{"gamedef": pyspiel.GameParameter(universal_poker_kuhn_limit_2p)})
compare_exploitability(game_1, game_2)
In [0]:
game_1 = pyspiel.load_game("leduc_poker",
{"players": pyspiel.GameParameter(2)})
# Taken verbatim from the linked paper above: "In Leduc hold'em, the deck
# consists of two suits with three cards in each suit. There are two rounds.
# In the first round a single private card is dealt to each player. In the
# second round a single board card is revealed. There is a two-bet maximum,
# with raise amounts of 2 and 4 in the first and second round, respectively.
# Both players start the first round with 1 already in the pot.
universal_poker_leduc_limit_2p = """\
GAMEDEF
limit
numPlayers = 2
numRounds = 2
blind = 1 1
raiseSize = 1 1
firstPlayer = 1 1
maxRaises = 2 2
raiseSize = 2 4
numSuits = 2
numRanks = 3
numHoleCards = 1 0
numBoardCards = 0 1
END GAMEDEF
"""
game_2 = pyspiel.load_game(
"universal_poker",
{"gamedef": pyspiel.GameParameter(universal_poker_leduc_limit_2p)})
compare_exploitability(game_1, game_2)
In [0]:
game = "universal_poker"
out = "/tmp/gametree.png"
prog = "dot"
group_infosets = False
group_terminal = False
verbose = False
def _zero_sum_node_decorator(state):
"""Custom node decorator that only shows the return of the first player."""
attrs = treeviz.default_node_decorator(state) # get default attributes
if state.is_terminal():
attrs["label"] = str(int(state.returns()[0]))
return attrs
game = pyspiel.load_game(
game, {"gamedef": pyspiel.GameParameter(universal_poker_kuhn_limit_2p)})
game_type = game.get_type()
if game_type.dynamics != pyspiel.GameType.Dynamics.SEQUENTIAL:
raise ValueError("Game must be sequential, not {}".format(game_type.dynamics))
if (game_type.utility == pyspiel.GameType.Utility.ZERO_SUM and
game.num_players() == 2):
gametree = treeviz.GameTree(
game,
node_decorator=_zero_sum_node_decorator,
group_infosets=group_infosets,
group_terminal=group_terminal)
else:
gametree = treeviz.GameTree(game) # use default decorators
if verbose:
logging.info("Game tree:\n%s", gametree.to_string())
gametree.draw(out, prog=prog)
In [0]: