Pig the dice game/Player: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(11 intermediate revisions by 8 users not shown)
Line 1:
[[Category:Games]]
 
{{task}}
 
Line 20 ⟶ 22:
 
 
;References
;Reference
* [[wp:Pig (dice)|Pig (dice)]]
* [https://youtu.be/ULhRLGzoXQ0 The Math of Being a Pig] and [https://www.youtube.com/watch?v=zD9-V9Idbug Pigs (extra)] - Numberphile videos featuring Ben Sparks.
<br><br>
 
Line 32 ⟶ 35:
The implementation reads five parameters from the command line, in that order: (1) N the number of games to play, (2) the Bound for the first player, (3) the Final_Run for the first player, (4) the Bound for the second player and (5) the Final_Run for the second player. After reading these from the command line (or accepting reasonable defaults), it plays the game N times and counts how often either player wins.
 
<langsyntaxhighlight Adalang="ada">with Pig; with Ada.Text_IO; with Ada.Command_Line;
 
procedure automatic_Pig is
Line 68 ⟶ 71:
Ada.Text_IO.Put_Line(Natural'Image(Win_Count(True)) &
Natural'Image(Win_Count(False)));
end Automatic_Pig;</langsyntaxhighlight>
 
 
Line 85 ⟶ 88:
 
Requires additional file from [[Pig the dice game/Player/AutoHotkey]]
<langsyntaxhighlight lang="autohotkey">#NoEnv
SetBatchLines, -1
#SingleInstance, Force
Line 158 ⟶ 161:
Roll := Optimal[SumMe,TurnSum,SumOpp+1]
Return Roll = "" ? 1 : Roll
}</langsyntaxhighlight>
{{out}}
<table border=1 cellpadding=1 cellspacing=0 width=500 style='table-layout:fixed;width:375pt'>
Line 311 ⟶ 314:
Player 3 always tries to score at least 20 points in a round.<br />
Player 4, just like player 3, always tries to score at least 20 points in a round. But as his round score increases, he gets a little "nervous", what increases the chances that he'll hold.
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <iostream>
Line 471 ⟶ 474:
}
//--------------------------------------------------------------------------------------------------
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 635 ⟶ 638:
=={{header|Common Lisp}}==
Just implemented two strategies. One is actually a variable strategy which holds until a specific value is reached and then turns the dice over. The default value is 25. The other is from "Practical Play of the Dice Game Pig" by ToddW. Neller and Clifton G.M. Presser. Their suggested strategy is "If either player’s score is 71 or higher, roll for the goal. Otherwise, hold at 21 + (j - i) / 8" where j is the other player's score and i is the strategizing player's score. The scoring is handled by generic functions on the player type.
<langsyntaxhighlight lang="lisp">(defclass player ()
((score :initform 0 :accessor score)
(name :initarg :name :accessor name)))
Line 695 ⟶ 698:
 
(defun play-pig-player (player1 player2)
(catch 'quit (format t "Hooray! ~A won the game!"</langsyntaxhighlight>
Output:
<syntaxhighlight lang="text">Darrell: Rolled a 4 - Turn: 4 Current Score: 4 Keep rolling (Y, N or Q)?Y
Darrell: Rolled a 3 - Turn: 7 Current Score: 7 Keep rolling (Y, N or Q)?Y
Darrell: Rolled a 3 - Turn: 10 Current Score: 10 Keep rolling (Y, N or Q)?Y
Line 799 ⟶ 802:
Darrell rolls a 3 and WINS!
Hooray! Darrell won the game!
NIL</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.stdio, std.random;
 
enum nPlayers = 4, maxPoints = 100;
Line 929 ⟶ 932:
writeln("Player III (AL20): ", players[2].getCurrScore);
writeln("Player IV (AL20T): ", players[3].getCurrScore, "\n\n");
}</langsyntaxhighlight>
 
The output is similar to the C++ entry.
Line 935 ⟶ 938:
=={{header|Erlang}}==
Four players take turns starting. Their strategy is how long to wait before holding. They aim for 5, 10, 15 and 20 rolls. Player20 managed better than I thought it would.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( pig_dice_player ).
 
Line 990 ⟶ 993:
Result
end.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,001 ⟶ 1,004:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package pig
 
import (
Line 1,191 ⟶ 1,194:
}
pg.PrintStatus(gameOverSummary)
}</langsyntaxhighlight>
Sample run, player one just tries to keep ahead, while player two always tries to take three rolls, no more.
<pre>
Line 1,404 ⟶ 1,407:
- player4 rolls 3/4 of the time, 1/4 he holds, but if he gets a score more than 75 he goes for the win
 
<syntaxhighlight lang="haskell">
<lang Haskell>
{-# LANGUAGE ViewPatterns #-}
 
Line 1,480 ⟶ 1,483:
p4 = pInfo { name = "Stephen" }
strat1 [p1, p2, p3, p4]
</syntaxhighlight>
</lang>
 
Example output:
Line 1,539 ⟶ 1,542:
To test the distribution by yourself (in parallel):
 
<syntaxhighlight lang="haskell">
<lang Haskell>
 
-- add this to the top
Line 1,562 ⟶ 1,565:
-- ghc FILENAME.hs -O2 -threaded -with-rtsopts="-N4" -o dice
 
</syntaxhighlight>
</lang>
 
Distribution:
Line 1,575 ⟶ 1,578:
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).
<syntaxhighlight lang="j">pigval=:4 :0
(+/%#)(-x),}.(1+i.6)<.100-y+x
)</syntaxhighlight>
Examples:
<syntaxhighlight lang="j"> 10 pigval 90
_1.66667</syntaxhighlight>
If we have 10 points from our current rolls and have 90 permanent points, rolling again is a bad idea.
<syntaxhighlight 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</syntaxhighlight>
If we have 70 permanent points (or less) we should probably re-roll when our uncommitted rolls total to less than 20.
<syntaxhighlight 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</syntaxhighlight>
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,580 ⟶ 1,608:
 
This is the main file, Pigdice.java
<langsyntaxhighlight Javalang="java">import java.util.Scanner;
 
public class Pigdice {
Line 1,719 ⟶ 1,747:
}
}</langsyntaxhighlight>
 
This is the Player.java class file.
<langsyntaxhighlight Javalang="java">public class Player {
 
private int points = 0;
Line 1,779 ⟶ 1,807:
}
 
}</langsyntaxhighlight>
 
This is the Move.java class file.
<langsyntaxhighlight Javalang="java">public enum Move { ROLL, HOLD }</langsyntaxhighlight>
 
This is the Strategy.java class file.
<langsyntaxhighlight Javalang="java">import java.util.Scanner;
 
public interface Strategy {
Line 1,913 ⟶ 1,941:
};
 
}</langsyntaxhighlight>
 
And finally, this is the Dice.java class file. It's pretty self-explanatory.
<langsyntaxhighlight Javalang="java">import java.util.Random;
 
public class Dice {
Line 1,930 ⟶ 1,958:
return rand.nextInt(sides) + 1;
}
}</langsyntaxhighlight>
 
Here's a small sample output using only bots (even though it fully supports human players too). A full game simulation can obviously be MUCH longer.
Line 1,981 ⟶ 2,009:
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}}==
<langsyntaxhighlight lang="julia">mutable struct Player
score::Int
ante::Int
Line 2,065 ⟶ 2,067:
 
rungames(1000000)
</langsyntaxhighlight>{{out}}
<pre>
Player 3 rolls a 5.
Line 2,206 ⟶ 2,208:
Even for 20+20 games strategy 12, 20 wins 8, 10
 
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module GamePig (games, strategy1, strategy2) {
Print "Game of Pig"
Line 2,302 ⟶ 2,304:
 
 
</syntaxhighlight>
</lang>
 
=={{header|Nim}}==
{{trans|D}}
We use the same strategies as D (and C++) but the code is somewhat different. To represent the players with their different strategies, we don’t use a player base class with subclasses for each strategy but a single player object with a “strategy” field. To dispatch, we use a "case" statement rather than method overriding. This is only a matter of preference as Nim allows inheritance and method overriding.
 
We also describe the list of players as a linked ring of player objects. The code is somewhat more pleasant this way.
 
Except for some small differences in the formatting, the output is similar to that of D (or C++) implementation.
 
<syntaxhighlight lang="nim">import random, strformat
 
const MaxPoints = 100
 
type
 
Move {.pure.} = enum Roll, Hold
Strategy {.pure.} = enum Rand, Q2Win, AL20, AL20T
 
# Player description.
Player = ref object
num: Natural
currentScore: Natural
roundScore: Natural
strategy: Strategy
next: Player
 
# Player list managed as a singly linked ring.
PlayerList = object
count: Natural
head, tail: Player
 
 
proc addPlayer(playerList: var PlayerList; strategy: Strategy) =
## Add a player with given strategy.
inc playerList.count
let newPlayer = Player(num: playerList.count, strategy: strategy)
if playerList.head.isNil:
playerList.head = newPlayer
else:
playerList.tail.next = newPlayer
playerList.tail = newPlayer
newPlayer.next = playerList.head
 
 
iterator items(playerList: PlayerList): Player =
## Yield the successive players of a player list.
var player = playerList.head
yield player
while player != playerList.tail:
player = player.next
yield player
 
 
proc getMove(player: Player): Move =
## Get the move for the given player.
 
if player.roundScore + player.currentScore >= MaxPoints: return Hold
 
case player.strategy
 
of Strategy.Rand:
result = if rand(1) == 0: Roll
elif player.roundScore > 0: Hold
else: Roll
 
of Strategy.Q2Win:
let q = MaxPoints - player.currentScore
result = if q < 6 or player.roundScore < q div 4: Roll
else: Hold
 
of Strategy.AL20:
result = if player.roundScore < 20: Roll
else: Hold
 
of Strategy.AL20T:
let d = 5 * player.roundScore
result = if player.roundScore < 20 and d < rand(99): Roll
else: Hold
 
 
randomize()
 
# Create player list.
var playerList = PlayerList()
for strategy in Strategy.low..Strategy.high:
playerList.addPlayer(strategy)
 
var endGame = false
var player = playerList.head
 
while not endGame:
case player.getMove()
 
of Roll:
let die = rand(1..6)
if die == 1:
echo &"Player {player.num} rolled {die} Current score: {player.currentScore:3}\n"
player.roundScore = 0
player = player.next
continue
inc player.roundScore, die
echo &"Player {player.num} rolled {die} Round score: {player.roundScore:3}"
 
of Hold:
inc player.currentScore, player.roundScore
echo &"Player {player.num} holds Current score: {player.currentScore:3}\n"
if player.currentScore >= MaxPoints:
endGame = true
else:
player.roundScore = 0
player = player.next
 
for player in playerList:
let stratStr = &"({player.strategy}):"
echo &"Player {player.num} {stratStr:8} {player.currentScore:3}"</syntaxhighlight>
 
{{out}}
<pre>Player 1 rolled 2 Round score: 2
Player 1 rolled 5 Round score: 7
Player 1 holds Current score: 7
 
Player 2 rolled 2 Round score: 2
Player 2 rolled 6 Round score: 8
Player 2 rolled 4 Round score: 12
Player 2 rolled 4 Round score: 16
Player 2 rolled 4 Round score: 20
Player 2 rolled 1 Current score: 0
 
Player 3 rolled 3 Round score: 3
Player 3 rolled 1 Current score: 0
 
Player 4 rolled 6 Round score: 6
Player 4 holds Current score: 6
 
Player 1 rolled 1 Current score: 7
 
Player 2 rolled 6 Round score: 6
Player 2 rolled 6 Round score: 12
Player 2 rolled 1 Current score: 0
 
Player 3 rolled 3 Round score: 3
Player 3 rolled 5 Round score: 8
Player 3 rolled 2 Round score: 10
Player 3 rolled 4 Round score: 14
Player 3 rolled 2 Round score: 16
Player 3 rolled 4 Round score: 20
Player 3 holds Current score: 20
 
Player 4 rolled 1 Current score: 6
 
Player 1 rolled 4 Round score: 4
Player 1 rolled 3 Round score: 7
Player 1 holds Current score: 14
 
Player 2 rolled 3 Round score: 3
Player 2 rolled 4 Round score: 7
Player 2 rolled 3 Round score: 10
Player 2 rolled 2 Round score: 12
Player 2 rolled 6 Round score: 18
Player 2 rolled 4 Round score: 22
Player 2 rolled 5 Round score: 27
Player 2 holds Current score: 27
 
Player 3 rolled 3 Round score: 3
Player 3 rolled 4 Round score: 7
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 5 Round score: 5
Player 4 rolled 5 Round score: 10
Player 4 rolled 1 Current score: 6
 
Player 1 rolled 2 Round score: 2
Player 1 rolled 3 Round score: 5
Player 1 holds Current score: 19
 
Player 2 rolled 2 Round score: 2
Player 2 rolled 2 Round score: 4
Player 2 rolled 3 Round score: 7
Player 2 rolled 2 Round score: 9
Player 2 rolled 5 Round score: 14
Player 2 rolled 4 Round score: 18
Player 2 holds Current score: 45
 
Player 3 rolled 3 Round score: 3
Player 3 rolled 5 Round score: 8
Player 3 rolled 4 Round score: 12
Player 3 rolled 4 Round score: 16
Player 3 rolled 3 Round score: 19
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 3 Round score: 3
Player 4 rolled 6 Round score: 9
Player 4 holds Current score: 15
 
Player 1 rolled 6 Round score: 6
Player 1 holds Current score: 25
 
Player 2 rolled 6 Round score: 6
Player 2 rolled 3 Round score: 9
Player 2 rolled 3 Round score: 12
Player 2 rolled 6 Round score: 18
Player 2 holds Current score: 63
 
Player 3 rolled 2 Round score: 2
Player 3 rolled 4 Round score: 6
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 4 Round score: 4
Player 4 rolled 4 Round score: 8
Player 4 holds Current score: 23
 
Player 1 rolled 4 Round score: 4
Player 1 holds Current score: 29
 
Player 2 rolled 3 Round score: 3
Player 2 rolled 6 Round score: 9
Player 2 holds Current score: 72
 
Player 3 rolled 5 Round score: 5
Player 3 rolled 5 Round score: 10
Player 3 rolled 6 Round score: 16
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 2 Round score: 2
Player 4 rolled 3 Round score: 5
Player 4 rolled 2 Round score: 7
Player 4 holds Current score: 30
 
Player 1 rolled 4 Round score: 4
Player 1 holds Current score: 33
 
Player 2 rolled 1 Current score: 72
 
Player 3 rolled 6 Round score: 6
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 2 Round score: 2
Player 4 rolled 1 Current score: 30
 
Player 1 rolled 3 Round score: 3
Player 1 rolled 3 Round score: 6
Player 1 rolled 5 Round score: 11
Player 1 rolled 5 Round score: 16
Player 1 holds Current score: 49
 
Player 2 rolled 2 Round score: 2
Player 2 rolled 4 Round score: 6
Player 2 rolled 4 Round score: 10
Player 2 holds Current score: 82
 
Player 3 rolled 2 Round score: 2
Player 3 rolled 6 Round score: 8
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 6 Round score: 6
Player 4 holds Current score: 36
 
Player 1 rolled 2 Round score: 2
Player 1 holds Current score: 51
 
Player 2 rolled 5 Round score: 5
Player 2 holds Current score: 87
 
Player 3 rolled 1 Current score: 20
 
Player 4 rolled 6 Round score: 6
Player 4 rolled 3 Round score: 9
Player 4 holds Current score: 45
 
Player 1 rolled 5 Round score: 5
Player 1 holds Current score: 56
 
Player 2 rolled 2 Round score: 2
Player 2 rolled 1 Current score: 87
 
Player 3 rolled 2 Round score: 2
Player 3 rolled 5 Round score: 7
Player 3 rolled 5 Round score: 12
Player 3 rolled 3 Round score: 15
Player 3 rolled 5 Round score: 20
Player 3 holds Current score: 40
 
Player 4 rolled 5 Round score: 5
Player 4 rolled 6 Round score: 11
Player 4 rolled 2 Round score: 13
Player 4 rolled 4 Round score: 17
Player 4 rolled 3 Round score: 20
Player 4 holds Current score: 65
 
Player 1 rolled 6 Round score: 6
Player 1 holds Current score: 62
 
Player 2 rolled 4 Round score: 4
Player 2 holds Current score: 91
 
Player 3 rolled 5 Round score: 5
Player 3 rolled 5 Round score: 10
Player 3 rolled 4 Round score: 14
Player 3 rolled 6 Round score: 20
Player 3 holds Current score: 60
 
Player 4 rolled 4 Round score: 4
Player 4 rolled 4 Round score: 8
Player 4 holds Current score: 73
 
Player 1 rolled 3 Round score: 3
Player 1 rolled 2 Round score: 5
Player 1 rolled 6 Round score: 11
Player 1 rolled 6 Round score: 17
Player 1 holds Current score: 79
 
Player 2 rolled 5 Round score: 5
Player 2 holds Current score: 96
 
Player 3 rolled 4 Round score: 4
Player 3 rolled 6 Round score: 10
Player 3 rolled 4 Round score: 14
Player 3 rolled 2 Round score: 16
Player 3 rolled 3 Round score: 19
Player 3 rolled 4 Round score: 23
Player 3 holds Current score: 83
 
Player 4 rolled 3 Round score: 3
Player 4 rolled 4 Round score: 7
Player 4 rolled 2 Round score: 9
Player 4 holds Current score: 82
 
Player 1 rolled 1 Current score: 79
 
Player 2 rolled 3 Round score: 3
Player 2 rolled 1 Current score: 96
 
Player 3 rolled 1 Current score: 83
 
Player 4 rolled 6 Round score: 6
Player 4 holds Current score: 88
 
Player 1 rolled 4 Round score: 4
Player 1 rolled 3 Round score: 7
Player 1 holds Current score: 86
 
Player 2 rolled 2 Round score: 2
Player 2 rolled 1 Current score: 96
 
Player 3 rolled 2 Round score: 2
Player 3 rolled 2 Round score: 4
Player 3 rolled 3 Round score: 7
Player 3 rolled 4 Round score: 11
Player 3 rolled 1 Current score: 83
 
Player 4 rolled 1 Current score: 88
 
Player 1 rolled 6 Round score: 6
Player 1 holds Current score: 92
 
Player 2 rolled 4 Round score: 4
Player 2 holds Current score: 100
 
Player 1 (Rand): 92
Player 2 (Q2Win): 100
Player 3 (AL20): 83
Player 4 (AL20T): 88</pre>
 
=={{header|Perl}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="perl">my $GOAL = 100;
 
package Player;
Line 2,372 ⟶ 2,735:
 
print ' ----' x @players, "\n";
printf "%5d", $_ for @wins; print "\n";</langsyntaxhighlight>
Distribution of wins after 10000 games:
{{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}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant maxScore = 100
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">constant</span> <span style="color: #000000;">maxScore</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100</span>
function one_game(sequence strategies)
integer numPlayers = length(strategies)
<span style="color: #008080;">function</span> <span style="color: #000000;">one_game</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">strategies</span><span style="color: #0000FF;">)</span>
sequence scores = repeat(0,numPlayers)
<span style="color: #004080;">integer</span> <span style="color: #000000;">numPlayers</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strategies</span><span style="color: #0000FF;">),</span>
integer points = 0, -- points accumulated in current turn, 0=swap turn
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- points accumulated in current turn, 0=swap turn</span>
rolls = 0, -- number of rolls
<span style="color: #000000;">rolls</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- number of rolls</span>
player = rand(numPlayers) -- start with a random player
<span style="color: #000000;">player</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">numPlayers</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- start with a random player</span>
while true do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">scores</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">numPlayers</span><span style="color: #0000FF;">)</span>
integer roll = rand(6)
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
if roll=1 then
<span style="color: #004080;">integer</span> <span style="color: #000000;">roll</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">)</span>
points = 0 -- swap turn
<span style="color: #008080;">if</span> <span style="color: #000000;">roll</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
else
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- swap turn</span>
points += roll
<span style="color: #008080;">else</span>
if scores[player]+points>=maxScore then exit end if
<span style="color: #000000;">points</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">roll</span>
rolls += 1
<span style="color: #008080;">if</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">player</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">points</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">maxScore</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if not call_func(strategies[player],{scores,player,points,rolls}) then
<span style="color: #000000;">rolls</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
scores[player] += points
<span style="color: #004080;">integer</span> <span style="color: #000000;">play</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">strategies</span><span style="color: #0000FF;">[</span><span style="color: #000000;">player</span><span style="color: #0000FF;">]</span>
points = 0 -- swap turn
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">play</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">,</span><span style="color: #000000;">player</span><span style="color: #0000FF;">,</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rolls</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">player</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">points</span>
end if
<span style="color: #000000;">points</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- swap turn</span>
if points=0 then
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
player = mod(player,numPlayers) + 1
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
rolls = 0
<span style="color: #008080;">if</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">player</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">player</span><span style="color: #0000FF;">,</span><span style="color: #000000;">numPlayers</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span>
end while
<span style="color: #000000;">rolls</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
return player
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">player</span>
-- each strategy returns true to roll, false to hold.
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function strategy1(sequence /*scores*/, integer /*player*/, points, /*rolls*/)
<span style="color: #000080;font-style:italic;">-- each strategy returns true to roll, false to hold.</span>
return points<20 -- roll until 20 or more
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">strategy1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000080;font-style:italic;">/*scores*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*player*/</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*rolls*/</span><span style="color: #0000FF;">)</span>
constant r_s1 = routine_id("strategy1")
<span style="color: #008080;">return</span> <span style="color: #000000;">points</span><span style="color: #0000FF;"><</span><span style="color: #000000;">20</span> <span style="color: #000080;font-style:italic;">-- roll until 20 or more</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
function strategy2(sequence /*scores*/, integer /*player*/, /*points*/, rolls)
return rolls<4 -- roll 4 times
<span style="color: #008080;">function</span> <span style="color: #000000;">strategy2</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000080;font-style:italic;">/*scores*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*player*/</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*points*/</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">rolls</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">rolls</span><span style="color: #0000FF;"><</span><span style="color: #000000;">4</span> <span style="color: #000080;font-style:italic;">-- roll 4 times</span>
constant r_s2 = routine_id("strategy2")
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function strategy3(sequence scores, integer player, points, /*rolls*/)
<span style="color: #008080;">function</span> <span style="color: #000000;">strategy3</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">player</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*rolls*/</span><span style="color: #0000FF;">)</span>
-- roll until 20 or score>80
<span style="color: #000080;font-style:italic;">-- roll until 20 or score&gt;80</span>
return points<20 or scores[player]+points>80
<span style="color: #008080;">return</span> <span style="color: #000000;">points</span><span style="color: #0000FF;"><</span><span style="color: #000000;">20</span> <span style="color: #008080;">or</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">player</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">points</span><span style="color: #0000FF;">></span><span style="color: #000000;">80</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
constant r_s3 = routine_id("strategy3")
 
<span style="color: #008080;">function</span> <span style="color: #000000;">strategy4</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">player</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*rolls*/</span><span style="color: #0000FF;">)</span>
function strategy4(sequence scores, integer player, points, /*rolls*/)
<span style="color: #000080;font-style:italic;">-- roll until 20 or any player has >&gt;71</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">scores</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
for i=1 to length(scores) do
<span style="color: #008080;">if</span> <span style="color: #000000;">scores</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]></span><span style="color: #000000;">71</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
if scores[i]>71 then return true end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">return</span> <span style="color: #000000;">points</span><span style="color: #0000FF;"><</span><span style="color: #000000;">20</span>
return points<20
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
constant r_s4 = routine_id("strategy4")
<span style="color: #008080;">constant</span> <span style="color: #000000;">strategies</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">strategy1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strategy2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strategy3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">strategy4</span><span style="color: #0000FF;">},</span>
 
<span style="color: #000000;">numStrategies</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strategies</span><span style="color: #0000FF;">),</span>
constant strategies = {r_s1,r_s2,r_s3,r_s4}
<span style="color: #000000;">numOpponents</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">numStrategies</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
 
-- play each strategy 1000 times against all combinations of other strategies
<span style="color: #000080;font-style:italic;">-- play each strategy 1000 times against all combinations of other strategies</span>
for s=1 to length(strategies) do
<span style="color: #008080;">for</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">numStrategies</span> <span style="color: #008080;">do</span>
sequence opponents = strategies
<span style="color: #004080;">integer</span> <span style="color: #000000;">strategy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">strategies</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">],</span>
opponents[s..s] = {}
<span style="color: #000000;">mask</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">numOpponents</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
integer mask = power(2,length(opponents))-1
<span style="color: #000000;">wins</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer wins = 0
<span style="color: #004080;">sequence</span> <span style="color: #000000;">opponents</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">strategies</span><span style="color: #0000FF;">)</span>
for m=1 to mask do -- (all possible bit settings, bar 0, eg/ie 1..7)
<span style="color: #000000;">opponents</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">..</span><span style="color: #000000;">s</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- (ie all others only)</span>
sequence game = {strategies[s]}
<span style="color: #008080;">for</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">mask</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (all possible bit settings, bar 0, eg/ie 1..7)</span>
for g=1 to length(opponents) do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">game</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">strategy</span><span style="color: #0000FF;">}</span>
if and_bits(m,power(2,g-1)) then
<span style="color: #008080;">for</span> <span style="color: #000000;">g</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">numOpponents</span> <span style="color: #008080;">do</span>
game &= opponents[g]
<span style="color: #008080;">if</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">g</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">game</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">opponents</span><span style="color: #0000FF;">[</span><span style="color: #000000;">g</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
for n=1 to 1000 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
wins += one_game(game)=1
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1000</span> <span style="color: #008080;">do</span>
end for
<span style="color: #000000;">wins</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">one_game</span><span style="color: #0000FF;">(</span><span style="color: #000000;">game</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"strategy %d: %d wins\n",{s,wins})
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"strategy %d: %d wins\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">wins</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,590 ⟶ 2,848:
Notice how Pythons Counter class from the standard library is used to collate the winning statistics near the end of the program without much additional code.
 
<langsyntaxhighlight lang="python">#!/usr/bin/python3
 
'''
Line 2,716 ⟶ 2,974:
for i in range(maxgames))
print(' Players(position) winning on left; occurrences on right:\n %s'
% ',\n '.join(str(w) for w in winners.most_common()))</langsyntaxhighlight>
{{out}}
First is shown the game data for a single game with reduced maxscore then statistics on multiple games.
Line 2,764 ⟶ 3,022:
Same as [[Pig_the_dice_game#Racket]], with three strategy makers, and
simulation code for trying out strategies.
<langsyntaxhighlight lang="racket">#lang racket
 
(define (pig-the-dice #:print? [print? #t] . players)
Line 2,809 ⟶ 3,067:
;; (n-runs 1000 (n-random 2) (n-random 3) (n-random 4))
;; (n-runs 1000 (n-rounds 5) (n-points 24))
;; (n-runs 1000 (n-rounds 5) (n-random 2))</langsyntaxhighlight>
The following example run demonstrates the output from
<langsyntaxhighlight Racketlang="racket">(pig-the-dice #:print? #t (n-points 12) (n-rounds 4))</langsyntaxhighlight>
Where <code>n-points</code> is a strategy where the user continues to roll until the specified number of points is gained and <code>n-rounds</code> is a strategy where the users rolls the specified number of times each round.
<pre>
Line 3,029 ⟶ 3,287:
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.
 
<syntaxhighlight lang="raku" line>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;</syntaxhighlight>
 
'''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>
 
Line 3,035 ⟶ 3,402:
 
The (somewhat aggressive) "quarter" strategy was chosen to give the advantage to a human (it was presumed that this dice game would be played with a CBLF).
<langsyntaxhighlight lang="rexx">/*REXX program plays "pig the dice game" (any number of CBLFs and/or silicons or HALs).*/
sw= linesize() - 1 /*get the width of the terminal screen,*/
parse arg hp cp win die _ . '(' names ")" /*obtain optional arguments from the CL*/
Line 3,132 ⟶ 3,499:
/*──────────────────────────────────────────────────────────────────────────────────────*/
err: say; say; say center(' error! ', max(40, linesize() % 2), "*"); say
do j=1 for arg(); say arg(j); say; end; say; exit 13</langsyntaxhighlight>
This REXX program makes use of &nbsp; '''LINESIZE''' &nbsp; BIF &nbsp; which returns the terminals width (linesize).
<br>Some REXXes don't have a &nbsp; '''LINESIZE''' &nbsp; BIF, so one is included here &nbsp; ──► &nbsp; [[LINESIZE.REX]].
Line 3,265 ⟶ 3,632:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">
def player1(sum,sm)
for i in 1..100
Line 3,306 ⟶ 3,673:
sm=0
player1(sum,sm)
return</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">var (games=100) = ARGV.map{.to_i}...
 
define DIE = 1..6;
define GOAL = 100;
 
class Player(score=0, ante=0, rolls=0, strategy={false}) {
method turn {
rolls = 0;
ante = 0;
loop {
rolls++;
given (var roll = DIE.rand) { |roll|
when (1) {
ante = 0;
break;
}
case (roll > 1) {
ante += roll;
}
}
((score + ante >= GOAL) || strategy) && break;
}
score += ante;
}
}
 
var 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: { players[1].rolls >= 5 } );
 
# try to accumulate at least 20 points per turn
players[2] = Player.new( strategy: { players[2].ante > 20 } );
 
# random but 90% chance of rolling again
players[3] = Player.new( strategy: { 1.rand < 0.1 } );
 
# random but more conservative as approaches goal
players[4] = Player.new( strategy: { 1.rand < ((GOAL - players[4].score) * 0.6 / GOAL) } );
 
var wins = [0]*players.len;.of(0)
 
games.times {
var player = -1;
loop {
player++;
var p = players[player % players.len];
p.turn;
p.score >= GOAL && break;
}
wins[player % players.len]++;
players.map{.score}.join("\t").say;
players.each { |p| p.score = 0 };
}
 
say "\nSCORES: for #{games} games";
say wins.join("\t");</langsyntaxhighlight>
{{out}}
<pre>
Line 3,399 ⟶ 3,766:
<table><tr><td>{{works with|Tcl|8.6}}</td><td>or alternatively with Tcl 8.5 and</td><td>{{libheader|TclOO}}</td></tr></table><!-- dirty trick! -->
First the structure of the game (from [[Pig the dice game#Tcl|the parent page]]):
<langsyntaxhighlight lang="tcl">package require TclOO
 
oo::class create Player {
Line 3,505 ⟶ 3,872:
rotateList scores
}
}</langsyntaxhighlight>
Then the classes that create the various implemented strategies:
<langsyntaxhighlight lang="tcl">oo::class create RoboPlayer {
superclass Player
variable me
Line 3,567 ⟶ 3,934:
dict set scores $who $score
}
}</langsyntaxhighlight>
Demonstration, pitting the three of them against each other:
<langsyntaxhighlight lang="tcl">pig [RandomPlayer new] [To20Player new] [Desperate new]</langsyntaxhighlight>
{{out}}
<pre>
Line 3,666 ⟶ 4,033:
Desperate® has (66,31)... roll
Desperate® has won! (Score: 101)
</pre>
 
=={{header|Wren}}==
{{trans|Sidef}}
<syntaxhighlight lang="wren">import "random" for Random
import "os" for Process
 
var args = Process.arguments
var games = (args.count == 0) ? 100 : Num.fromString(args[0])
 
var Rand = Random.new()
var Die = 1..6
var Goal = 100
 
class Player {
construct new(strategy) {
_score = 0
_ante = 0
_rolls = 0
_strategy = strategy
}
 
score { _score }
rolls { _rolls }
ante { _ante }
 
score=(s) { _score = s }
 
turn() {
_rolls = 0
_ante = 0
while (true) {
_rolls = _rolls + 1
var roll = Rand.int(Die.from, Die.to + 1)
if (roll == 1) {
_ante = 0
break
}
_ante = _ante + roll
if (_score + _ante >= Goal || _strategy.call()) break
}
_score = _score + _ante
}
}
 
var numPlayers = 5
var players = List.filled(numPlayers, null)
 
// default, go-for-broke, always roll again
players[0] = Player.new { false }
 
// try to roll 5 times but no more per turn
players[1] = Player.new { players[1].rolls >= 5 }
 
// try to accumulate at least 20 points per turn
players[2] = Player.new { players[2].ante > 20 }
 
// random but 90% chance of rolling again
players[3] = Player.new { Rand.float() < 0.1 }
 
// random but more conservative as approaches goal
players[4] = Player.new { Rand.float() < (Goal - players[4].score) * 0.6 / Goal }
 
var wins = List.filled(numPlayers, 0)
 
for (i in 0...games) {
var player = -1
while (true) {
player = player + 1
var p = players[player % numPlayers]
p.turn()
if (p.score >= Goal) break
}
wins[player % numPlayers] = wins[player % numPlayers] + 1
System.print(players.map { |p| p.score }.join("\t"))
players.each { |p| p.score = 0 }
}
 
System.print("\nSCORES: for %(games) games")
System.print(wins.join("\t"))</syntaxhighlight>
 
{{out}}
Sample output for 10000 games:
<pre>
0 89 88 102 33
0 21 45 101 16
0 84 104 11 29
0 101 46 20 22
0 102 24 0 36
0 42 100 49 13
0 103 92 34 65
0 82 100 34 34
0 95 100 60 41
0 105 69 53 82
0 35 101 65 66
0 19 102 83 27
0 40 101 24 30
0 101 71 15 67
...
0 101 23 31 34
0 81 45 103 24
102 66 68 82 36
0 101 42 49 49
0 86 103 29 22
0 100 91 82 32
 
SCORES: for 10000 games
938 3581 3426 1656 399
</pre>
9,476

edits