Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cmath>
- #include <iostream>
- struct Pig
- {
- // value[0][i][j][k] is the probability of the current player winning with
- // score i, opponent score j, and current roll total k.
- double value[2][256][256][256];
- int roll_max;
- int roll_pig;
- // Compute value[] array for the game where each roll is in the range
- // 1..roll_max, rolling roll_pig ends a turn, and reaching the given win
- // score ends the game. Return the number of iterations required to
- // converge within the given tolerance.
- int reset(int roll_max = 6, int roll_pig = 1, int win = 100,
- double tolerance = 1e-15)
- {
- // Initialize value array.
- this->roll_max = roll_max;
- this->roll_pig = roll_pig;
- for (int n = 0; n < 2; ++n)
- {
- for (int i = 0; i < win + roll_max; ++i)
- {
- for (int j = 0; j < win + roll_max; ++j)
- {
- for (int k = 0; k < win + roll_max; ++k)
- {
- // Start with all values 0, except for winning states
- // on the boundary.
- value[n][i][j][k] = ((i + k >= win) ? 1 : 0);
- }
- }
- }
- }
- // Iterate state transitions.
- double err = 2;
- int n = 0;
- int iterations = 0;
- while (err > tolerance || n == 0)
- {
- int m = 1 - n;
- err = 0;
- for (int i = 0; i < win; ++i)
- {
- for (int j = 0; j < win; ++j)
- {
- for (int k = 0; k < win - i; ++k)
- {
- double v = std::max(
- value_hold(i, j, k, m),
- value_roll(i, j, k, m));
- value[n][i][j][k] = v;
- err = std::max(err, std::abs(v - value[m][i][j][k]));
- }
- }
- }
- n = 1 - n;
- ++iterations;
- }
- return iterations;
- }
- // Return probability of the current player winning by passing the die with
- // score i, opponent score j, and current roll total k.
- double value_hold(int i, int j, int k, int m = 0)
- {
- return 1 - value[m][j][i + k][0];
- }
- // Return probability of the current player winning by rolling the die with
- // score i, opponent score j, and current roll total k.
- double value_roll(int i, int j, int k, int m = 0)
- {
- double v = 1 - value[m][j][i][0];
- for (int roll = 1; roll <= roll_max; ++roll)
- {
- if (roll != roll_pig)
- {
- v += value[m][i][j][k + roll];
- }
- }
- return v / roll_max;
- }
- };
- int main()
- {
- Pig *pig = new Pig;
- int iterations = pig->reset();
- // Display tuples (i, j, k, v_hold, v_roll).
- for (int i = 0; i < 100; ++i)
- {
- for (int j = 0; j < 100; ++j)
- {
- for (int k = 0; k < 100 - i; ++k)
- {
- std::cout << i << " " << j << " " << k << " " <<
- (pig->value_hold(i, j, k) < pig->value_roll(i, j, k)) <<
- std::endl;
- }
- }
- }
- delete pig;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement