Julia OpenSpiel¶
We also provide a Julia wrapper for the OpenSpiel project. Most APIs are aligned
with those in Python (some are extended to accept AbstractArray
and/or keyword
arguments for convenience). See spiel.h
for the full API description.
Install¶
For general usage, you can install this package in the Julia REPL with
] add OpenSpiel
. Note that this method only supports the Linux platform and
ACPC is not included. For developers, you need to follow the instructions bellow
to install this package:
Install Julia and dependencies. Edit
open_spiel/scripts/global_variables.sh
and setOPEN_SPIELOPEN_SPIEL_BUILD_WITH_JULIA=ON
(you may also turn on other options as you wish). Then run./install.sh
. If you already have Julia installed on your system, make sure that it is visible in your terminal and its version is v1.3 or later. Otherwise, Julia v1.3.1 will be automatically installed in your home dir and a soft link will be created at/usr/local/bin/julia
.Build and run tests
./open_spiel/scripts/build_and_run_tests.sh
Install
] dev ./open_spiel/julia
(run in Julia REPL).
Known Problems¶
There’s a problem when building this package on Mac with XCode v11.4 or above (see discussions here). To fix it, you need to install the latest
libcxxwrap
by following the instructions here after running./install.sh
. Then make sure that the result ofjulia --project=./open_spiel/julia -e 'using CxxWrap; print(CxxWrap.prefix_path())'
points to the newly builtlibcxxwrap
. After that, build and install this package as stated above.
Example¶
Here we demonstrate how to use the Julia API to play one game:
using OpenSpiel
# Here we need the StatsBase package for weighted sampling
using Pkg
Pkg.add("StatsBase")
using StatsBase
function run_once(name)
game = load_game(name)
state = new_initial_state(game)
println("Initial state of game[$(name)] is:\n$(state)")
while !is_terminal(state)
if is_chance_node(state)
outcomes_with_probs = chance_outcomes(state)
println("Chance node, got $(length(outcomes_with_probs)) outcomes")
actions, probs = zip(outcomes_with_probs...)
action = actions[sample(weights(collect(probs)))]
println("Sampled outcome: $(action_to_string(state, action))")
apply_action(state, action)
elseif is_simultaneous_node(state)
chosen_actions = [rand(legal_actions(state, pid-1)) for pid in 1:num_players(game)] # in Julia, indices start at 1
println("Chosen actions: $([action_to_string(state, pid-1, action) for (pid, action) in enumerate(chosen_actions)])")
apply_action(state, chosen_actions)
else
action = rand(legal_actions(state))
println("Player $(current_player(state)) randomly sampled action: $(action_to_string(state, action))")
apply_action(state, action)
end
println(state)
end
rts = returns(state)
for pid in 1:num_players(game)
println("Utility for player $(pid-1) is $(rts[pid])")
end
end
run_once("tic_tac_toe")
run_once("kuhn_poker")
run_once("goofspiel(imp_info=True,num_cards=4,points_order=descending)")
Q&A¶
What is
StdVector
?StdVector
is introduced in CxxWrap.jl recently. It is a wrapper ofstd::vector
in the C++ side. Since that it is a subtype ofAbstractVector
, most functions should just work out of the box.0-based
or1-based
?As this package is a low-level wrapper of OpenSpiel C++, most APIs are zero-based: for instance, the
Player
id starts from zero. But note that some bridge types, likeStdVector
, implicitly convert between indexing conventions, so APIs that useStdVector
are one-based.I can’t find the
xxx
function/type in the Julia wrapper/The program exits unexpectedly.Although most of the functions and types should be exported, there is still a chance that some APIs are not well tested. So if you encounter any error, please do not hesitate to create an issue.