Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a new python game #1204

Closed
Brunozml opened this issue Apr 11, 2024 · 7 comments
Closed

Adding a new python game #1204

Brunozml opened this issue Apr 11, 2024 · 7 comments

Comments

@Brunozml
Copy link
Contributor

it is unclear to me how to translate some of the documentation instructions on Adding a game for python. Specifically, when I try rebuild the example (step 6) by running build/examples/example --game=my_game.,

I get the following error

Spiel Fatal Error: Unknown game 'my_game'. Available games are:
2048
add_noise
amazons
...

Which does not list any of the python games. What am I missing here?

I also long for testing the game interactively as I build it (as in step 8). Can I use ConolePlayTest for python games? I haven't achieved so so far.

@lanctot
Copy link
Collaborator

lanctot commented Apr 11, 2024

Which does not list any of the python games. What am I missing here?

That is unexpected. How did you install OpenSpiel? Looks like it was built from source..? (If so, can you point out the commands you used to install + build)? Either way they should be included. Note that they should all start with the python_ prefix.

Can you post the complete list of games that are shown when you run that command?

I also long for testing the game interactively as I build it (as in step 8). Can I use ConolePlayTest for python games? I haven't achieved so so far.

Hmm, probably not.. you can do it manually or use the MCTS example linked below.

The first thing I recommend is the OpenSpiel tutorial video. This will give you an overview of the API which is critical. Then you can play with your game in the same way as I do in the video (via the Python interpreter), which is quite close to the ConsolePlayTest.

There is the python MCTS example which allows you to play from the keyboard. If you run that with both players set to human then you can test your game. We should update the docs to mention that.

@Brunozml
Copy link
Contributor Author

Brunozml commented Apr 12, 2024

First of all, Thank you for the tip about mcts.py. That's exactly the interactivity anyone would like!

Since my last issue I managed to create and run a template C++ game, but python games are still a work in progress... here are the commands I used:

python3 -m venv .venv
source .venv/bin/activate

./install.sh  
python3 -m pip install -r requirements.txt
pip install -e .
./open_spiel/scripts/build_and_run_tests.sh 

Where only the following tests fail:

The following tests FAILED:
         18 - oos_test (Failed)
         22 - tabular_exploitability_test (Failed)
        130 - python/../integration_tests/playthrough_test.py (Failed)

Note: Ignore test 130. It fails because I have managed to create a template of a C++ game without any playthrough.

In terms of the missing games, here's the complete list of games you asked for:

(.venv) ~build/examples/example --game=python_block_dominoes
Registered games:
2048
add_noise
amazons
backgammon
bargaining
battleship
blackjack
blotto
breakthrough
bridge
bridge_uncontested_bidding
catch
checkers
chess
cliff_walking
clobber
coin_game
colored_trails
connect_four
coop_box_pushing
coop_to_1p
coordinated_mp
crazy_eights
cursor_go
dark_chess
dark_hex
dark_hex_ir
deep_sea
dots_and_boxes
dou_dizhu
efg_game
euchre
first_sealed_auction
gin_rummy
go
goofspiel
havannah
hearts
hex
kriegspiel
kuhn_poker
laser_tag
leduc_poker
lewis_signaling
liars_dice
liars_dice_ir
maedn
mancala
markov_soccer
matching_pennies_3p
matrix_bos
matrix_brps
matrix_cd
matrix_coordination
matrix_mp
matrix_pd
matrix_rps
matrix_rpsw
matrix_sh
matrix_shapleys_game
mfg_crowd_modelling
mfg_crowd_modelling_2d
mfg_dynamic_routing
mfg_garnet
misere
morpion_solitaire
negotiation
nfg_game
nim
nine_mens_morris
normal_form_extensive_game
oh_hell
oshi_zumo
othello
oware
pathfinding
pentago
phantom_go
phantom_ttt
phantom_ttt_ir
pig
quoridor
rbc
repeated_game
restricted_nash_response
sheriff
skat
solitaire
start_at
stones_and_gems
tarok
tic_tac_toe
tiny_bridge_2p
tiny_bridge_4p
tiny_hanabi
trade_comm
turn_based_simultaneous_game
ultimate_tic_tac_toe
vaqueritos # my sample new game in C++
y
zerosum
Creating game..

Spiel Fatal Error: Unknown game 'python_block_dominoes'. Available games are:
# same exact output as before

I've noticed something similar in colab, when after installing openspiel, if I import only pyspiel, the list of games doesn't contain any python game, but if I import say, from open_spiel.python.algorithms import exploitability, then pyspiel.registered_names() now also includes the python games. I'd guess the problem lies on not importing correctly that submodule during the installation of open_spiel, but I don't know how to fix it yet.

Additional details:

  • Python version 3.10
  • clang version 15.0
  • cmake version 3.29

@lanctot
Copy link
Collaborator

lanctot commented Apr 12, 2024

Ok perfect, thanks for all the info, I think I understand what is going on.

First: The oos_test and tabular_exploitability_test I fixed recently, those are likely to numerical comparisons in the 10th decimal place (this varies by numpy version). I suspect it'll be the same reason for the playthrough_test. So you can ignore these.

Second: you cannot load a Python game from a C++ binary, which is what you're trying to do above. When running a C++ binary stand-alone, the Python games do not show up. The Python games only show up when you import pyspiel from a Python interpreter. You can actually run a C++ algorithm on a Python game if you want, but that algorithm has to be called from a Python interpreter (i.e. via Python bindings).. but don't worry about that special case for now.

You should now set your PYTHONPATH (step 5 here) so your Python interpreter knows where to find OpenSpiel, and then start python and try this:

import pyspiel
print (pyspiel.registered_names())

You should see the python games.

A similar example as the C++ one above is available in Python: python/examples/example.py.

If, then, you see the other games but not your Python game, it's likely because you have to add it to the init file here.

Hope this helps. Please let us know if you have any other questions.

@Brunozml
Copy link
Contributor Author

Brunozml commented Apr 12, 2024

Thank you for your replies, and sorry for the inconvenience :(

However, I still haven't managed to resolve the issue. In fact, I began following your nice tutorial once again and found the same thing on Colab. Running

!pip install --upgrade open_spiel
import pyspiel
games_list = pyspiel.registered_names()
print(f'{len(games_list)} Registered games:' )

records 102 registered games, but when running an additional code block

import open_spiel.python.games
games_list = pyspiel.registered_names()
print(f'{len(games_list)} Registered games:' )

there are now 109 registered games, with the following having been excluded before:

{'chat_game',
 'python_block_dominoes',
 'python_dynamic_routing',
 'python_iterated_prisoners_dilemma',
 'python_kuhn_poker',
 'python_liars_poker',
 'python_tic_tac_toe'}

Since Google Colab is running on a separate kernel, I assume there must be some wider issue I'm missing.

Recap

the latest installation-and-build procedure was the following:

./install.sh  
python3.10 -m venv .venv
source .venv/bin/activate

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
pip3 install --upgrade pip
pip3 install --upgrade setuptools testresources

python3 -m pip install -r requirements.txt
./open_spiel/scripts/build_and_run_tests.sh 

python3 -m pip install -e .

export PYTHONPATH=$PYTHONPATH:/<**absolute**_path_to_open_spiel>
export PYTHONPATH=$PYTHONPATH:/<*absolute**_path_to_open_spiel>/build/python

#I've run ./open_spiel/scripts/build_and_run_tests.sh again afterwards and got the same three errors as before.

locally, I get 101 games when running pyspiel.registered_names(), with the missing games being:

{'python_kuhn_poker', 
'python_liars_poker', 
**'hanabi',** 
'python_iterated_prisoners_dilemma', 
'python_block_dominoes', 'python_dynamic_routing', 
'chat_game', 
'python_tic_tac_toe', 
'universal_poker'}

When adding import open_spiel.python.games, only {'universal_poker', 'hanabi'} are missing (to be expected). However. running build/examples/example --game=python_block_dominoes from the command line still doesn't list python games.

Update:

  • When adding open_spiel.python.games to the imports in mcts.py, one can now also test interactively python games too! I haven't managed to get it working with my new game though, only with pre-exisiting ones.
  • I imagine a simple change of that kind to the source code for examples/example.cc might do to, but I don't know how to handle the C++Python configuration.

@lanctot
Copy link
Collaborator

lanctot commented Apr 12, 2024

Hi @Brunozml,

Great. There are simple explanations for all of this. It's not nearly as complicated as it seems, I promise :)

The colab version install OpenSpiel v1.4 from PyPI which is back-dated to Nov 16th, 2023. There have been games added since then, so when you build from master you see the new ones (e.g. chat_game). We should be releasing a v1.5 in the next 2 months and so Colab will be up-to-date with master again then.

hanabi and universal_poker are optional games (because they require additional dependencies). They don't show up when built from master unless you enable the appropriate environment flags and install the extra dependencies, but we include them in the binary wheel on PyPI because we expect people will be interested in having them (and they don't need to download+compile the extra dependencies).

Yes, it seems like importing pyspiel is not enough: you need to also import open_spiel.python.games to get the python games. Sorry, I have not used any of them so this is news to me.. and all the more reasons to improve the docs as a result of these exchanges, which I promise to do! (Perfectly in time for v1.5!)

However. running build/examples/example --game=python_block_dominoes from the command line still doesn't list python games.

That's right, and this is expected because that example is compiled from a C++ file. I explained in my response from last night:

Second: you cannot load a Python game from a C++ binary, which is what you're trying to do above. When running a C++ binary stand-alone, the Python games do not show up.

You will not be able to use a Python game from a C++-compiled binary (build/examples/example is the compiled binary of this C++ file). You should use the analogous Python example instead.

Hope this helps!

@lanctot
Copy link
Collaborator

lanctot commented Apr 12, 2024

I imagine a simple change of that kind to the source code for examples/example.cc might do to, but I don't know how to handle the C++Python configuration.

No, unfortunately you really can't load a Python game from a C++ binary right now. Technically it would be possible to support that.. but you'd have to launch a Python interpreter from C++ and run it as a subprocess. It's quite awkward/clunky to do that and it's also be error-prone, so currently we only support loading Python games if you are already running from Python. This is not a big problem because most of the algorithms also have Python versions too.

Many of the examples are also available in python here: https://github.com/google-deepmind/open_spiel/tree/master/open_spiel/python/examples

@Brunozml
Copy link
Contributor Author

Dear @lanctot,

I have now managed to begin developing and testing my game implementation in python, all thanks to your help. I expect to propose a commit soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants