durak

Durak

Python and Rust implementation of MCTS to guide gameplay in the card game durak.

Getting Started

Clone this repository.

git clone https://github.com/jorisperrenet/durak
cd durak

For the Python implementation, do:

cd python_version
python main.py

For the Rust implementation, do:

cd rust_version
cargo run

Game Rules

This code implements the game of traditional Durak with reflecting. Note:

Gameplay is only available through the console.

Types of Players

Programming Language Human Random DeterminizedMCTS ISMCTS ISMCTSFPV
Python :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:
Rust :heavy_check_mark: :heavy_check_mark: :heavy_check_mark:, multi-threaded :x: :x:

How can you use this to win in a real-life game?

Elo-rating of Players

This program can also be used to rate players, game are played head-to-head with each other. Random players are set to an initial ELO rating of 1000. Players that have a 10 times higher chance to win (or better to not lose) will have an ELO rating of 400 higher. See this for more information on how to calculate the ELO rating of a player (the uncertainty/standard deviation was calculated using this).

I lost against the DeterminizedMCTS version in Rust with 3.3 million simulations (30000 rollouts, 112 deals, 0.8 exploration)… Twice… Knowing his cards…. But I won against the 125 thousand simulations version (5000 rollouts, 25 deals, 0.8 exploration).

Generally, I found that the MCTS was quite unsure of his moves in the beginning stages (all with about 50% chance to win), even having the trump ace. This caused it to throw on the trump ace even though he had the trump 7. However, in the endgame he made up for it by simulating a large amount of the game tree (which started with about 8 cards left to draw).

Possible Additions

Possible additions to the current version could be:

Example Output

The bottom card is ♠Q
You typed ♦A
You typed ♥8
You typed ♠6
You typed ♠J
You typed ♣A
You typed ♥Q
Doing rollout 9999 for Player1
Action(attack, card=♠J), win_rate=49.96%, W=38386, N=76839
Action(attack, card=♣A), win_rate=50.13%, W=41347, N=82473
Action(attack, card=♥Q), win_rate=49.99%, W=40174, N=80369
Action(attack, card=♥8), win_rate=50.26%, W=43843, N=87237
Action(attack, card=♠6), win_rate=49.85%, W=37949, N=76122
Action(attack, card=♦A), win_rate=49.85%, W=38342, N=76912
GOING FOR ACTION Action(attack, card=♥8)
Confirm [y/n]:

Note: this is the Rust version, ran in about 11.2 seconds with 6 threads.