farkle.py
is a script that lets us statistically compare different play strategies so that we can cream our family.
farkle.py
- contains a bunch of utility functions for doing farkle math on lists of dicegameplay.py
- contains a game simulator and some statistics functionspolicy_*.py
- contains a policy definition. Try outpython policy_naive.py
for a sample
Give your policy a cool name, like "awesome policy" and save it with the naming convention policy_*.py
, so in your case policy_awesome.py
. Have it contain a function using the properties defined below, in our example we'll call it my_awesome_policy
.
Your policy should be a function that takes these arguments:
choices
- alist
of choices (explanation below)total_score
- the total score of the game so far, not including points from dice picked up in the current turnturn_score
- the score of the current turn so far, not including any newly thrown dice which have not yet been picked upis_open
-True
if the player needs to choose more dice to open, otherwiseFalse
Example signature: def my_awesome_policy(choices, total_score, turn_score, is_open):
A choice
is a dict
that looks like this (for example):
{
"score": 300,
"remaining": 2
}
This means that the player will pick up some number of dice, leave 2
dice ready to be re-rolled, and gain 300
points.
For example, if the player rolled [5, 2, 2, 2, 1, 4]
, the choices
object would look like this:
[
{"score": 350, "remaining": 1},
{"score": 300, "remaining": 2},
{"score": 200, "remaining": 3},
{"score": 150, "remaining": 4},
{"score": 100, "remaining": 5}
]
To communicate with the simulator what the player intends to do next, the policy function should return one of these choices and a decision as to whether to continue to roll again. The return value may look something like the following example:
{
"choice": {"score": 300, "remaining": 2},
"roll_again": False
}
Using the same choices
example from above, this would mean the player decided to pick up the 1 and a 3-of-a-kind, scoring 300
points and leaving the 4 and the 5 on the table. This player has elected to not roll the remaining 2 dice (if the player is not yet open the game simulator will override the policy's decision).
Call the play_single_player_game
function from gameplay.py
. Set verbose=True
to see gameplay output:
play_single_player_game(my_awesome_policy_function, verbose=True)
Call the analyze_n_single_player_games
function to run multiple games and generate statistics. For example, to run 10,000 trials:
analyze_n_single_player_games(n=10000, policy=always_roll_once)
Run
python policy_naive.py
to see the output from a game using a basic policy, and some statistics about how this policy performs.