Jump to content

Pig the dice game/Player: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
m (added a games category to this task.)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 801:
Darrell rolls a 3 and WINS!
Hooray! Darrell won the game!
NIL</lang>
 
=={{header|D}}==
Line 1,577:
out of 100 000 tests.
</pre>
 
=={{header|J}}==
This is a partial implementation of the current task.
 
This is a routine to estimate the value of rolling, given the current total of rolls which the player is building (left argument) and the current total of rolls which are a permanent part of the player's score (right argument).
 
If the expected value is positive, it's probably in the best interest of the player to take the roll. That said, a more sophisticated strategy might play cautiously when a player is sufficiently ahead of the other player(s).
<lang j>pigval=:4 :0
(+/%#)(-x),}.(1+i.6)<.100-y+x
)</lang>
Examples:
<lang j> 10 pigval 90
_1.66667</lang>
If we have 10 points from our current rolls and have 90 permanent points, rolling again is a bad idea.
<lang j> 0 5 10 15 20 pigval"0/60 65 70 75 80 85 90 95 100
3.33333 3.33333 3.33333 3.33333 3.33333 3.33333 3.33333 3.16667 0
2.5 2.5 2.5 2.5 2.5 2.5 2.33333 _0.833333 _5
1.66667 1.66667 1.66667 1.66667 1.66667 1.5 _1.66667 _5.83333 _10
0.833333 0.833333 0.833333 0.833333 0.666667 _2.5 _6.66667 _10.8333 _15
0 0 0 _0.166667 _3.33333 _7.5 _11.6667 _15.8333 _20</lang>
If we have 70 permanent points (or less) we should probably re-roll when our uncommitted rolls total to less than 20.
<lang j> (1+i.19) ([,:1+i:~) +/ 0 < pigval"0/~ 1+i.100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
98 97 96 95 93 92 91 90 89 87 86 85 84 82 81 80 78 77 75</lang>
This is a table of decision points. First row represents sum of our current uncommitted rolls. Second row represents the maximum permanent score where you should roll again with that number of uncommitted points, if we are using this estimation mechanism to choose our actions. Note that the first four columns here should have some obvious validity -- for example, if we have 96 permanent points and we have rolled 4 uncommitted points, we have won the game and we gain nothing from rerolling... Note also that this decision mechanism says we should never reroll if we have at least 20 uncommitted points.
 
=={{header|Java}}==
Line 1,983 ⟶ 2,008:
Player 3 had 102 points.
</pre>
 
=={{header|J}}==
This is a partial implementation of the current task.
 
This is a routine to estimate the value of rolling, given the current total of rolls which the player is building (left argument) and the current total of rolls which are a permanent part of the player's score (right argument).
 
If the expected value is positive, it's probably in the best interest of the player to take the roll. That said, a more sophisticated strategy might play cautiously when a player is sufficiently ahead of the other player(s).
<lang j>pigval=:4 :0
(+/%#)(-x),}.(1+i.6)<.100-y+x
)</lang>
Examples:
<lang j> 10 pigval 90
_1.66667</lang>
If we have 10 points from our current rolls and have 90 permanent points, rolling again is a bad idea.
<lang j> 0 5 10 15 20 pigval"0/60 65 70 75 80 85 90 95 100
3.33333 3.33333 3.33333 3.33333 3.33333 3.33333 3.33333 3.16667 0
2.5 2.5 2.5 2.5 2.5 2.5 2.33333 _0.833333 _5
1.66667 1.66667 1.66667 1.66667 1.66667 1.5 _1.66667 _5.83333 _10
0.833333 0.833333 0.833333 0.833333 0.666667 _2.5 _6.66667 _10.8333 _15
0 0 0 _0.166667 _3.33333 _7.5 _11.6667 _15.8333 _20</lang>
If we have 70 permanent points (or less) we should probably re-roll when our uncommitted rolls total to less than 20.
<lang j> (1+i.19) ([,:1+i:~) +/ 0 < pigval"0/~ 1+i.100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
98 97 96 95 93 92 91 90 89 87 86 85 84 82 81 80 78 77 75</lang>
This is a table of decision points. First row represents sum of our current uncommitted rolls. Second row represents the maximum permanent score where you should roll again with that number of uncommitted points, if we are using this estimation mechanism to choose our actions. Note that the first four columns here should have some obvious validity -- for example, if we have 96 permanent points and we have rolled 4 uncommitted points, we have won the game and we gain nothing from rerolling... Note also that this decision mechanism says we should never reroll if we have at least 20 uncommitted points.
 
 
=={{header|Julia}}==
Line 2,305 ⟶ 2,304:
 
</lang>
 
 
=={{header|Perl}}==
Line 2,378 ⟶ 2,376:
{{out}}
<pre>929 3518 3462 1715 376</pre>
 
=={{header|Perl 6}}==
 
This implements a pig player class where you can customize the strategy it uses. Pass a strategy code reference in that will evaluate to a Boolean value. The player will roll the die then decide whether to roll again or lock in its winnings based on its strategy. It will continue to roll until it gets a 1 (bust) or the strategy code reference evaluates to True (finished turn).
 
Set up as many players as you want, then run it. It will play 100 games (by default) then report the score for each game then the win totals for each player. If you want to play a different number of games, pass the number at the command line as a parameter.
 
Here we have 5 players:
player 0 uses the default strategy, always roll if it can.
player 1 will roll up to 5 times then lock in whatever it earned.
player 2 will try to get at least 20 points per turn.
player 3 randomly picks whether to roll again or not biased so that there is a 90% chance that it will.
player 4 randomly chooses to roll again but gets more consrvative as its score get closer to the goal.
 
<lang perl6>my $games = @*ARGS ?? (shift @*ARGS) !! 100;
 
constant DIE = 1 .. 6;
constant GOAL = 100;
 
class player {
has $.score is rw = 0;
has $.ante is rw;
has $.rolls is rw;
has &.strategy is rw = sub { False }; # default, always roll again
 
method turn {
my $done_turn = False;
$.rolls = 0;
$.ante = 0;
repeat {
given DIE.roll {
$.rolls++;
when 1 {
$.ante = 0;
$done_turn = True;
}
when 2..* {
$.ante += $_;
}
}
$done_turn = True if $.score + $.ante >= GOAL or (&.strategy)();
} until $done_turn;
$.score += $.ante;
}
}
 
my @players;
 
# default, go-for-broke, always roll again
@players[0] = player.new;
 
# try to roll 5 times but no more per turn
@players[1] = player.new( strategy => sub { @players[1].rolls >= 5 } );
 
# try to accumulate at least 20 points per turn
@players[2] = player.new( strategy => sub { @players[2].ante > 20 } );
 
# random but 90% chance of rolling again
@players[3] = player.new( strategy => sub { 1.rand < .1 } );
 
# random but more conservative as approaches goal
@players[4] = player.new( strategy => sub { 1.rand < ( GOAL - @players[4].score ) * .6 / GOAL } );
 
my @wins = 0 xx @players;
 
for ^ $games {
my $player = -1;
repeat {
$player++;
@players[$player % @players].turn;
} until @players[$player % @players].score >= GOAL;
 
@wins[$player % @players]++;
 
say join "\t", @players>>.score;
@players[$_].score = 0 for ^@players; # reset scores for next game
}
 
say "\nSCORES: for $games games";
say join "\t", @wins;</lang>
 
'''Sample output for 10000 games'''
<pre>
0 103 46 5 40
0 100 69 0 48
0 105 22 7 44
0 75 69 19 102
105 21 23 5 17
0 101 85 12 29
0 70 66 103 23
0 0 104 69 20
0 100 44 0 20
0 102 63 75 30
0 56 101 12 40
0 103 71 2 38
0 103 91 21 32
0 18 102 47 28
...
...
...
104 0 69 14 47
0 68 101 13 22
0 99 89 102 31
 
SCORES: for 10000 games
947 3534 3396 1714 409
 
</pre>
 
=={{header|Phix}}==
Line 3,031 ⟶ 2,921:
Player 2 wins!
2
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
 
This implements a pig player class where you can customize the strategy it uses. Pass a strategy code reference in that will evaluate to a Boolean value. The player will roll the die then decide whether to roll again or lock in its winnings based on its strategy. It will continue to roll until it gets a 1 (bust) or the strategy code reference evaluates to True (finished turn).
 
Set up as many players as you want, then run it. It will play 100 games (by default) then report the score for each game then the win totals for each player. If you want to play a different number of games, pass the number at the command line as a parameter.
 
Here we have 5 players:
player 0 uses the default strategy, always roll if it can.
player 1 will roll up to 5 times then lock in whatever it earned.
player 2 will try to get at least 20 points per turn.
player 3 randomly picks whether to roll again or not biased so that there is a 90% chance that it will.
player 4 randomly chooses to roll again but gets more consrvative as its score get closer to the goal.
 
<lang perl6>my $games = @*ARGS ?? (shift @*ARGS) !! 100;
 
constant DIE = 1 .. 6;
constant GOAL = 100;
 
class player {
has $.score is rw = 0;
has $.ante is rw;
has $.rolls is rw;
has &.strategy is rw = sub { False }; # default, always roll again
 
method turn {
my $done_turn = False;
$.rolls = 0;
$.ante = 0;
repeat {
given DIE.roll {
$.rolls++;
when 1 {
$.ante = 0;
$done_turn = True;
}
when 2..* {
$.ante += $_;
}
}
$done_turn = True if $.score + $.ante >= GOAL or (&.strategy)();
} until $done_turn;
$.score += $.ante;
}
}
 
my @players;
 
# default, go-for-broke, always roll again
@players[0] = player.new;
 
# try to roll 5 times but no more per turn
@players[1] = player.new( strategy => sub { @players[1].rolls >= 5 } );
 
# try to accumulate at least 20 points per turn
@players[2] = player.new( strategy => sub { @players[2].ante > 20 } );
 
# random but 90% chance of rolling again
@players[3] = player.new( strategy => sub { 1.rand < .1 } );
 
# random but more conservative as approaches goal
@players[4] = player.new( strategy => sub { 1.rand < ( GOAL - @players[4].score ) * .6 / GOAL } );
 
my @wins = 0 xx @players;
 
for ^ $games {
my $player = -1;
repeat {
$player++;
@players[$player % @players].turn;
} until @players[$player % @players].score >= GOAL;
 
@wins[$player % @players]++;
 
say join "\t", @players>>.score;
@players[$_].score = 0 for ^@players; # reset scores for next game
}
 
say "\nSCORES: for $games games";
say join "\t", @wins;</lang>
 
'''Sample output for 10000 games'''
<pre>
0 103 46 5 40
0 100 69 0 48
0 105 22 7 44
0 75 69 19 102
105 21 23 5 17
0 101 85 12 29
0 70 66 103 23
0 0 104 69 20
0 100 44 0 20
0 102 63 75 30
0 56 101 12 40
0 103 71 2 38
0 103 91 21 32
0 18 102 47 28
...
...
...
104 0 69 14 47
0 68 101 13 22
0 99 89 102 31
 
SCORES: for 10000 games
947 3534 3396 1714 409
 
</pre>
 
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.