Skip to main content

Rust Game Collection with Reninforcement Learning gym environments

Project description

Zarena

🦀 Rust Game Collection with Reninforcement Learning gym environments. This library aims to serve the same purpose as OpenSpiel, except in Rust to make it easier to use & maintain. The current games are gato, blackjack, chess & poker texas hold'em. All of these additionally support Web Assembly. You can play gato & chess against our Artificial Intelligence at Zeti Games

Configurations

Depending on the cargo file you want. You must change your cargo.toml to match that build.

Cargo.py.toml -> Python Build Cargo.rs.toml -> Development Build Cargo.wa.toml -> Web Assembly Build Cargo.toml -> The actual file that Rust will build on. Copy from py/rs/wa to this file.

Commands

If you don't have Rust, no worries. Download Rust for Linux or Windows Subsystem. If you need more help.

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Download the C compiler

sudo apt-get update && sudo apt-get install build-essential

Install poetry

curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -

Install Maturin via Poetry

poetry install

Build the Maturin Develop Build

poetry run maturin develop

Build the Maturin Test Build

poetry run maturin build

Build the Maturin Production Build. The Python Wheel & source distribution.

poetry run maturin build --release

Build the Web Assembly file

wasm-pack build --target web -- --features wasm

Usage

You can import the Python classes directly, or create pre-defined environments with gym in this case it is also necessary to import the class:

# import gym to use training environments
import gym
# from zarena import the training environment of your choice, for: 
# option 1.- use the python class directly 
# option 2.- register the environment in gym and use it with gym.make(environment_name)
from zarena import gym_chess

env = gym_chess.ChessEnv() # Option 1
env = gym.make('ChessEnv-v3') # Option 2

# reset the environment and get the initial state observation
observation = env.reset()

# obtain legal actions
actions = env.legal_actions()

# select action according to a criterion, in this case random
action = random.choice(actions)

# pass it to the env and get the next state observation, reward, if the game is over and environment information
observation, reward, done, info = env.step(action)

# get the player to play
env.to_play()

# properly close the game
env.close()

# display the game ovservation
env.render()

Environments id

  • Tictactoe: TictactoeR-v2
  • Chess: ChessEnv-v3
  • Blackjack: BlackjackR-v1
  • Poker: PokerR-v1

Testing

Run all the tests with pytest.

Code linting and fixing

Python code is formatted with black.

Rust code is formatted with cargo fmt.

Building the Rust code

The environment uses a chess engine implemented in Rust that uses PyO3 Maturin to bind to the Python interpreter. Rust is an amazing compiled language and this project holds 2 configurations:

  • Cargo.py.toml is used to build the library into a Python module with maturin
  • Cargo.rs.toml is used to build directly with cargo in Rust to access the library in the main.rs script for development
  • Cargo.wa.toml is used to build to build for Javascript with Web Assembly. The games can be played via Web Assembly on Zeti's website https://zeti.ai

Note: we haven't found a way to specify the Cargo toml file to either process, so copy the contents of the config you want to use into Cargo.toml to make it work.

Game of Gato

The game of Xs & Os

API

Initialize environment

>>> env = BlackjackEnv(n_players=1)
  • n_players: specify the number of players 2<=n_players<=7 (default: 1)

Set actions

>>> env.step(action)
  • action: mark a position, could be 0<=action<=8
> 0 | 1 | 2 
> 3 | 4 | 5 
> 6 | 7 | 8 

Available opponents

  • random
  • expert
gata

Notes:

Tests not implemented yet.

Blackjack

API

Initialize environment

>>> env = BlackjackEnv(n_players=1)
  • n_players: specify the number of players 2<=n_players<=7 (default: 1)

Set actions

>>> env.step(action)
  • action: can be
    • 0 -> stand
    • 1 -> HIT
    • 2 -> double down
    • 3 -> pull apart (currently disabled)

21

Notes:

Tests not implemented yet.

Chess

See the chess board and moves

Visualise the current state of the chess game:

env.render()
    -------------------------
 8 |                 |
 7 |                 |
 6 |  .  .  .  .  .  .  .  . |
 5 |  .  .  .  .  .  .  .  . |
 4 |  .  .  .  .  .  .  .  . |
 3 |  .  .  .  .  .  .  .  . |
 2 |                 |
 1 |                 |
    -------------------------
      a  b  c  d  e  f  g  h

You can also visualise multiple moves:

>>> moves = env.possible_moves
>>> env.render_moves(moves[10:12] + moves[16:18])

API

Initialize environment

>>> env = ChessEnv(player_color="WHITE", opponent="random", log=True, initial_state=DEFAULT_BOARD)
  • opponent: can be "random", "none" or a function. Tells the environment whether to use a bot that picks a random move, play against self or use a specific bot policy (default: "random")
  • log: True or False, specifies whether to log every move and render every new state (default: True)
  • initial_state: initial board positions, the default value is the default chess starting board. You can specify a custom board. View scripts gym_chess/test/ for some examples
  • player_color: "WHITE" or "BLACK", only useful if playing against a bot (default: "WHITE")
>>> env.get_possible_moves(state=state, player="WHITE", attack=False)

This method will calculate the possible moves. By default they are calculated at the current state for the current player (state.current_player).

  • state: (optional) state for which to calculate the moves
  • player: (optional) "WHITE" or "BLACK", specifies the player

Move specification:

Moves are encoded as either:

  • a tuple of coordinates ((from_x, from_y), (to_x, to_y))
  • or a string e.g. "CASTLE_KING_SIDE_WHITE", "CASTLE_QUEEN_SIDE_BLACK", "RESIGN"

Moves are pre-calculated for every new state and stored in possible_moves.

Get State

>>> print(env.state['board'])
[[-3, -5, -4, -2, -1, -4, -5, -3],
 [-6, -6, -6, -6, -6, -6, -6, -6],
 [0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0, 0, 0, 0],
 [6, 6, 6, 6, 6, 6, 6, 6],
 [3, 5, 4, 2, 1, 4, 5, 3]]

Every integer represents a piece. Positive pieces are white and negative ones are black.

Piece IDs are stored in constants that can be imported.

from gym_chess.envs.chess import (
    KING_ID,
    QUEEN_ID,
    ROOK_ID,
    BISHOP_ID,
    KNIGHT_ID,
    PAWN_ID,
)

The schema is:

EMPTY_SQUARE_ID = 0
KING_ID = 1
QUEEN_ID = 2
ROOK_ID = 3
BISHOP_ID = 4
KNIGHT_ID = 5
PAWN_ID = 6

Additional information can be found in other attributes of the environment:

env.current_player
env.white_king_castle_possible
env.white_queen_castle_possible
env.black_king_castle_possible
env.black_queen_castle_possible
env.white_king_on_the_board
env.black_king_on_the_board

Fischer

Notes:

En-passant has not been implemented yet.

Poker

API

Initialize environment

>>> env = PokerEnv(n_players=2, infinite_game=True)
  • n_players: specify the number of players 2<=n_players<=9 (default: 2)
  • infinite_game: True or False, specify if players get their starting credit back after each round (default: True)

Set actions

>>> env.step(action)
  • action: can be
    • 0 -> small blind
    • 1 -> big blind
    • 2 -> fold
    • 3 -> check
    • 4 -> bet
    • 5 -> call
    • 6 -> raise to 25
    • 7 -> raise to 50
    • 8 -> raise to 100
    • 9 -> raise to 500
    • 10 -> raise to 1000
    • 11 -> all in

alt text

Notes:

Tests not implemented yet.

References

Contrbutions

Pull Request Are Welcomed!

License

MIT

Social

Discord Twitter Youtube Facebook

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zarena-0.2.0.tar.gz (58.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

zarena-0.2.0-cp36-abi3-win_amd64.whl (233.8 kB view details)

Uploaded CPython 3.6+Windows x86-64

zarena-0.2.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl (1.1 MB view details)

Uploaded CPython 3.6+manylinux: glibc 2.5+ x86-64

zarena-0.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.whl (1.1 MB view details)

Uploaded CPython 3.6+manylinux: glibc 2.5+ i686

zarena-0.2.0-cp36-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (657.9 kB view details)

Uploaded CPython 3.6+macOS 10.9+ universal2 (ARM64, x86-64)macOS 10.9+ x86-64macOS 11.0+ ARM64

zarena-0.2.0-cp36-abi3-macosx_10_7_x86_64.whl (349.2 kB view details)

Uploaded CPython 3.6+macOS 10.7+ x86-64

File details

Details for the file zarena-0.2.0.tar.gz.

File metadata

  • Download URL: zarena-0.2.0.tar.gz
  • Upload date:
  • Size: 58.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.12.5

File hashes

Hashes for zarena-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9c37febd057bbb6c445e2c52a93c8b6dbcf8cbfa84df1848bedff715e29bb3a9
MD5 342d35c29afbc587b1b834dd610332d2
BLAKE2b-256 777e797f0e111f2c4aae7bb653a61bdebc3b26b0f9afbfb7db51ecefa1a6fd92

See more details on using hashes here.

File details

Details for the file zarena-0.2.0-cp36-abi3-win_amd64.whl.

File metadata

  • Download URL: zarena-0.2.0-cp36-abi3-win_amd64.whl
  • Upload date:
  • Size: 233.8 kB
  • Tags: CPython 3.6+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/0.12.5

File hashes

Hashes for zarena-0.2.0-cp36-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e48dfa0a82d35e88edaaf38aed553ad83686493b49a3750a079579f670c246ae
MD5 5acc7b132a2c00057efe1fcb86d98cf6
BLAKE2b-256 3b12b6844c4adfc2d418ea80274c0ba186cacebc722eaa387354a273e2012516

See more details on using hashes here.

File details

Details for the file zarena-0.2.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for zarena-0.2.0-cp36-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 7c332ccbd030c6607584866f0ee1dae421569f3464df76777a7a2db6934d9a75
MD5 6d2b260c567dd8348c7562a9b79d5ae5
BLAKE2b-256 b5a4615dfbf4da8164e2a22672ff32e5b39e88a61b006ef2480dc96f1461c240

See more details on using hashes here.

File details

Details for the file zarena-0.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.whl.

File metadata

File hashes

Hashes for zarena-0.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.whl
Algorithm Hash digest
SHA256 7c6025ef928ce55f87ebc45102ec0ff669181e7af092f1ae6c3d842b941a68ae
MD5 cb382fd3215390ae02228f8db45fbf7f
BLAKE2b-256 5f11665745092271ca3062ac9aaccd5333e21b6c8e51a66e54094f33631d8e7f

See more details on using hashes here.

File details

Details for the file zarena-0.2.0-cp36-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for zarena-0.2.0-cp36-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 aaf4487b72ecc8f9c8fecf8237766810d7500161faf1c37a6f15666e533fc3b9
MD5 c753647e4a9cc8fcd84bb79273a03f1c
BLAKE2b-256 d5f432decee08a69a7a3f008ce0d0e5bc76c346c8ce79942c9ccf3a92164e296

See more details on using hashes here.

File details

Details for the file zarena-0.2.0-cp36-abi3-macosx_10_7_x86_64.whl.

File metadata

File hashes

Hashes for zarena-0.2.0-cp36-abi3-macosx_10_7_x86_64.whl
Algorithm Hash digest
SHA256 580b0afe620cf3a571e5f6aa31c0a8ea4db42c58dded60c563997cfd4f885a82
MD5 32af97bc84476d4de82d565b383f231e
BLAKE2b-256 49f2856eb85ac613b7b172bb7ee1ebff00470585c5b0687790e35bb3b6baa8bf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page