Pig the dice game

From Rosetta Code
Jump to: navigation, search
Task
Pig the dice game
You are encouraged to solve this task according to the task description, using any language you may know.

The game of Pig is a multiplayer game played with a single six-sided die. The object of the game is to reach 100 points or more. Play is taken in turns. On each person's turn that person has the option of either

  1. Rolling the dice: where a roll of two to six is added to their score for that turn and the player's turn continues as the player is given the same choice again; or a roll of 1 loses the player's total points for that turn and their turn finishes with play passing to the next player.
  2. Holding: The player's score for that round is added to their total and becomes safe from the effects of throwing a one. The player's turn finishes with play passing to the next player.
Task goal

The goal of this task is to create a program to score for, and simulate dice throws for, a two-person game.

Cf

Contents

[edit] ActionScript

 
package {
 
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
 
public class PigTheDiceGame extends Sprite {
 
/**
* The name of the first player.
*
* @private
*/

private var _name1:String = "Player 1";
 
/**
* The name of the second player.
*
* @private
*/

private var _name2:String = "Player 2";
 
/**
* True if the next turn is of the second player, false if it is of the first player.
*
* @private
*/

private var _isPlayer2:Boolean = false;
 
/**
* The score of the first player.
*
* @private
*/

private var __p1Score:uint;
 
/**
* The score of the second player.
*
* @private
*/

private var __p2Score:uint;
 
/**
* The number of points in the current turn.
*
* @private
*/

private var __turnPts:uint;
 
/**
* The text field displaying the score of the first player.
*
* @private
*/

private var _p1ScoreText:TextField;
 
/**
* The text field displaying the score of the second player.
*
* @private
*/

private var _p2ScoreText:TextField;
 
/**
* The button which must be clicked for a player to roll the dice.
*
* @private
*/

private var _rollButton:Sprite;
 
/**
* The button which must be clicked for a player to hold.
*
* @private
*/

private var _holdButton:Sprite;
 
/**
* The text field displaying the name of the current player.
*/

private var _currentPlayerText:TextField;
 
/**
* The text field displaying the number of points in the current turn.
*
* @private
*/

private var _ptsThisTurnText:TextField;
 
/**
* The dice.
*
* @private
*/

private var _dice:Shape;
 
/**
* The number of points required to win the game.
*
* @private
*/

private var _maxScore:uint = 100;
 
/**
* The text field displaying additional information about the game.
*
* @private
*/

private var _statusText:TextField;
 
/**
* Creates a new PigTheDiceGame instance.
*/

public function PigTheDiceGame() {
if ( stage ) _init();
else addEventListener(Event.ADDED_TO_STAGE, _init);
}
 
/**
* Function which constructs the dice game when the object is added to the stage.
*
* @private
*/

private function _init(e:Event = null):void {
 
// Border and background
 
graphics.beginFill(0xFFFFDD);
graphics.lineStyle(2, 0xFFCC00);
graphics.drawRect(0, 0, 450, 280)
 
x = 20;
y = 20;
 
// Text fields and labels
 
var currentPlayerText:TextField = _createTextField(_name1 + "'s turn", 20, 0, 10, 0xDD0000, TextFieldAutoSize.CENTER, width);
var p1ScoreLabel:TextField = _createTextField(_name1 + "'s score:", 15, 20, currentPlayerText.y + currentPlayerText.height + 20, 0x000000, TextFieldAutoSize.LEFT, 120);
var p1ScoreText:TextField = _createTextField("0", 17, 135, p1ScoreLabel.y, 0xFF0000, TextFieldAutoSize.RIGHT, 50);
var p2ScoreLabel:TextField = _createTextField(_name2 + "'s score:", 15, 20, p1ScoreText.y + p1ScoreText.height + 5, 0x000000, TextFieldAutoSize.LEFT, 120);
var p2ScoreText:TextField = _createTextField("0", 17, 135, p2ScoreLabel.y, 0xFF0000, TextFieldAutoSize.RIGHT, 50);
var ptsThisTurnLabel:TextField = _createTextField("Points in this turn:", 15, 20, p2ScoreText.y + p2ScoreText.height + 15, 0x000000, TextFieldAutoSize.LEFT, 120);
var ptsThisTurnText:TextField = _createTextField("0", 17, 135, ptsThisTurnLabel.y, 0xFF0000, TextFieldAutoSize.RIGHT, 50);
 
// Dice
 
var dice:Shape = new Shape();
dice.x = 201;
dice.y = ptsThisTurnText.y + ptsThisTurnText.height + 30;
dice.visible = false;
 
var statusText:TextField = _createTextField("Start Play!", 15, 0, dice.y + 70, 0x0000A0, TextFieldAutoSize.CENTER, 450);
 
// "Roll" button
 
var rollButton:Sprite = new Sprite();
var rollButtonText:TextField = _createTextField("Roll dice", 17, 0, 0, 0x000000, TextFieldAutoSize.CENTER, 100);
rollButton.mouseChildren = false;
rollButton.buttonMode = true;
rollButton.graphics.lineStyle(1, 0x444444);
rollButton.graphics.beginFill(0xDDDDDD);
rollButton.graphics.drawRect(0, 0, 100, rollButtonText.height);
rollButton.x = 330;
rollButton.y = 80;
rollButton.addChild(rollButtonText);
 
// "Hold" button
 
var holdButton:Sprite = new Sprite();
var holdButtonText:TextField = _createTextField("Hold", 17, 0, 0, 0x000000, TextFieldAutoSize.CENTER, 100);
holdButton.mouseChildren = false;
holdButton.buttonMode = true;
holdButton.graphics.copyFrom(rollButton.graphics);
holdButton.x = 330;
holdButton.y = rollButton.y + rollButton.height + 10;
holdButton.addChild(holdButtonText);
 
rollButton.addEventListener(MouseEvent.CLICK, _rollButtonClick);
holdButton.addEventListener(MouseEvent.CLICK, _holdButtonClick);
 
_currentPlayerText = currentPlayerText;
_p1ScoreText = p1ScoreText;
_p2ScoreText = p2ScoreText;
_ptsThisTurnText = ptsThisTurnText;
_rollButton = rollButton;
_holdButton = holdButton;
_dice = dice;
_statusText = statusText;
 
addChild(currentPlayerText);
addChild(p1ScoreLabel);
addChild(p1ScoreText);
addChild(p2ScoreLabel);
addChild(p2ScoreText);
addChild(ptsThisTurnLabel);
addChild(ptsThisTurnLabel);
addChild(ptsThisTurnText);
addChild(statusText);
addChild(_dice);
addChild(rollButton);
addChild(holdButton);
 
}
 
/**
* Creates a new text field.
*
* @param text The text to be displayed in the text field.
* @param size The font size of the text.
* @param x The x-coordinate of the text field.
* @param y The y-coordinate of the text field.
* @param colour The text colour.
* @param autoSize The text alignment mode.
* @param width The width of the text field.
* @return A TextField object.
* @private
*/

private function _createTextField(text:String, size:Number, x:Number, y:Number, colour:uint, autoSize:String, width:Number):TextField {
var t:TextField = new TextField();
t.defaultTextFormat = new TextFormat(null, size, colour);
t.autoSize = autoSize;
t.x = x;
t.y = y;
t.width = width;
t.text = text;
t.height = t.textHeight + 5;
return t;
}
 
/**
* Rolls the dice.
*
* @return The result of the roll (1-6)
* @private
*/

private function _rollDice():uint {
 
// Since Math.random() returns a number between 0 and 1, multiplying it by 6 and then rounding down
// gives a number between 0 and 5, so add 1 to it.
 
var roll:uint = uint(Math.random() * 6) + 1;
 
_dice.visible = true;
var diceGraphics:Graphics = _dice.graphics;
 
// Draw the dice.
 
diceGraphics.clear();
diceGraphics.lineStyle(2, 0x555555);
diceGraphics.beginFill(0xFFFFFF);
diceGraphics.drawRect(0, 0, 48, 48);
diceGraphics.beginFill(0x000000);
diceGraphics.lineStyle(0);
 
switch ( roll ) {
case 1:
diceGraphics.drawCircle(24, 24, 3);
break;
case 2:
diceGraphics.drawCircle(16, 16, 3);
diceGraphics.drawCircle(32, 32, 3);
break;
case 3:
diceGraphics.drawCircle(12, 12, 3);
diceGraphics.drawCircle(24, 24, 3);
diceGraphics.drawCircle(36, 36, 3);
break;
case 4:
diceGraphics.drawCircle(16, 16, 3);
diceGraphics.drawCircle(16, 32, 3);
diceGraphics.drawCircle(32, 16, 3);
diceGraphics.drawCircle(32, 32, 3);
break;
case 5:
diceGraphics.drawCircle(12, 12, 3);
diceGraphics.drawCircle(24, 24, 3);
diceGraphics.drawCircle(36, 36, 3);
diceGraphics.drawCircle(36, 12, 3);
diceGraphics.drawCircle(12, 36, 3);
break;
case 6:
diceGraphics.drawCircle(16, 12, 3);
diceGraphics.drawCircle(16, 24, 3);
diceGraphics.drawCircle(16, 36, 3);
diceGraphics.drawCircle(32, 12, 3);
diceGraphics.drawCircle(32, 24, 3);
diceGraphics.drawCircle(32, 36, 3);
break;
}
 
return roll;
 
}
 
/**
* The score of the first player.
*
* @private
*/

private function get _p1Score():uint {
return __p1Score;
}
 
/**
* @private
*/

private function set _p1Score(value:uint):void {
__p1Score = value;
_p1ScoreText.text = String(value);
 
if ( value >= _maxScore ) {
_currentPlayerText.text = "Game over!";
_statusText.text = _name1 + " wins!";
removeChild(_rollButton);
removeChild(_holdButton);
}
}
 
/**
* The score of the second player.
*
* @private
*/

private function get _p2Score():uint {
return __p2Score;
}
 
/**
* @private
*/

private function set _p2Score(value:uint):void {
__p2Score = value;
_p2ScoreText.text = String(value);
 
if ( value >= _maxScore ) {
_currentPlayerText.text = "Game over!";
_statusText.text = _name2 + " wins!";
removeChild(_rollButton);
removeChild(_holdButton);
}
}
 
/**
* The number of points in the current turn.
*
* @private
*/

private function get _turnPts():uint {
return __turnPts;
}
 
/**
* @private
*/

private function set _turnPts(value:uint):void {
__turnPts = value;
_ptsThisTurnText.text = String(value);
 
if ( _isPlayer2 && __p2Score + value >= _maxScore ) {
_ptsThisTurnText.text = "0";
_p2Score += value;
}
else if ( ! _isPlayer2 && __p1Score + value >= _maxScore ) {
_ptsThisTurnText.text = "0";
_p1Score += value;
}
}
 
/**
* Function called when the "Roll dice" button is clicked.
*
* @private
*/

private function _rollButtonClick(e:MouseEvent):void {
var roll:uint = _rollDice();
 
if ( roll == 1 ) {
if ( _isPlayer2 ) {
_currentPlayerText.text = _name1 + "'s turn";
_statusText.text = _name2 + " rolls 1 and loses " + __turnPts + " points. " + _name1 + "'s turn now.";
}
else {
_currentPlayerText.text = _name2 + "'s turn";
_statusText.text = _name1 + " rolls 1 and loses " + __turnPts + " points. " + _name2 + "'s turn now.";
}
 
_isPlayer2 = ! _isPlayer2;
_turnPts = 0;
}
else {
_turnPts += roll;
_statusText.text = "";
}
}
 
/**
* Function called when the "Hold" button is clicked.
*
* @private
*/

private function _holdButtonClick(e:MouseEvent):void {
if ( _isPlayer2 ) {
_currentPlayerText.text = _name1 + "'s turn";
_statusText.text = _name2 + " holds and wins " + __turnPts + " points. " + _name1 + "'s turn now.";
_p2Score += __turnPts;
}
else {
_currentPlayerText.text = _name2 + "'s turn";
_statusText.text = _name1 + " holds and wins " + __turnPts + " points. " + _name2 + "'s turn now.";
_p1Score += __turnPts;
}
 
_dice.visible = false;
_turnPts = 0;
_isPlayer2 = ! _isPlayer2;
}
 
}
 
}
 

[edit] Ada

Uses Ada 2012.

[edit] The Package Pig

We first define a package Pig, which we also use in the player task Pig the dice game/Player.

Essentially, this package specifies two classes: Player provides the record keeping of the player's score saved so far, the points accumulated in the current round that may be added to the score, and the most recent roll. Actor is an abstract class to model the decision of rolling the dice once more or to save the current points into the score.

Also, there is a procedure Play to play the game, following whatever the actors do.

package Pig is
 
type Dice_Score is range 1 .. 6;
 
type Player is tagged private;
function Recent(P: Player) return Natural;
function All_Recent(P: Player) return Natural;
function Score(P: Player) return Natural;
 
type Actor is abstract tagged null record;
function Roll_More(A: Actor; Self, Opponent: Player'Class)
return Boolean is abstract;
 
procedure Play(First, Second: Actor'Class; First_Wins: out Boolean);
 
private
type Player is tagged record
Score: Natural := 0;
All_Recent: Natural := 0;
Recent_Roll: Dice_Score := 1;
end record;
 
end Pig;

The implementation of Pig is as follows:

with Ada.Numerics.Discrete_Random;
package body Pig is
 
function Score(P: Player) return Natural is (P.Score);
function All_Recent(P: Player) return Natural is (P.All_Recent);
function Recent(P: Player) return Natural is (Natural(P.Recent_Roll));
function Has_Won(P: Player) return Boolean is (P.Score >= 100);
 
package RND is new Ada.Numerics.Discrete_Random(Dice_Score);
Gen: RND.Generator;
 
procedure Roll(P: in out Player) is
begin
P.Recent_Roll := RND.Random(Gen);
if P.Recent = 1 then
P.All_Recent := 0;
else
P.All_Recent := P.All_Recent + P.Recent;
end if;
end Roll;
 
procedure Add_To_Score(P: in out Player) is
begin
P.Score := P.Score + P.All_Recent;
P.All_Recent := 0;
end Add_To_Score;
 
procedure Play(First, Second: Actor'Class;
First_Wins: out Boolean) is
P1, P2: Player;
begin
loop
Roll(P1);
while First.Roll_More(P1, P2) and then P1.Recent > 1 loop
Roll(P1);
end loop;
Add_To_Score(P1);
exit when P1.Score >= 100;
Roll(P2);
while Second.Roll_More(P2, P1) and then P2.Recent > 1 loop
Roll(P2);
end loop;
Add_To_Score(P2);
exit when P2.Score >= 100;
end loop;
First_Wins := P1.Score >= 100;
end Play;
 
begin
RND.Reset(Gen);
end Pig;

[edit] Solving the Task

Now, to actually play the game, we need a procedure Play_Pig. Mainly, we derive a class Hand from the class Actor to implement manually playing the game.

with Pig, Ada.Text_IO;
 
procedure Play_Pig is
 
use Pig;
 
type Hand is new Actor with record
Name: String(1 .. 5);
end record;
function Roll_More(A: Hand; Self, Opponent: Player'Class) return Boolean;
 
function Roll_More(A: Hand; Self, Opponent: Player'Class) return Boolean is
Ch: Character := ' ';
use Ada.Text_IO;
begin
Put(A.Name & " you:" & Natural'Image(Self.Score) &
" (opponent:" & Natural'Image(Opponent.Score) &
") this round:" & Natural'Image(Self.All_Recent) &
" this roll:" & Natural'Image(Self.Recent) &
"; add to score(+)?");
Get(Ch);
return Ch /= '+';
end Roll_More;
 
A1: Hand := (Name => "Alice");
A2: Hand := (Name => "Bob ");
 
Alice: Boolean;
begin
Play(A1, A2, Alice);
Ada.Text_IO.Put_Line("Winner = " & (if Alice then "Alice!" else "Bob!"));
end Play_Pig;
Output:
Alice you: 0 (opponent: 0) this round: 3 this roll: 3;  add to score(+)? 
Alice you: 0 (opponent: 0) this round: 5 this roll: 2;  add to score(+)? 
Alice you: 0 (opponent: 0) this round: 10 this roll: 5;  add to score(+)? 
Alice you: 0 (opponent: 0) this round: 13 this roll: 3;  add to score(+)?+
Bob   you: 0 (opponent: 13) this round: 6 this roll: 6;  add to score(+)? 
Bob   you: 0 (opponent: 13) this round: 8 this roll: 2;  add to score(+)? 
Bob   you: 0 (opponent: 13) this round: 11 this roll: 3;  add to score(+)? 
Bob   you: 0 (opponent: 13) this round: 16 this roll: 5;  add to score(+)? 
Bob   you: 0 (opponent: 13) this round: 18 this roll: 2;  add to score(+)? 
Bob   you: 0 (opponent: 13) this round: 20 this roll: 2;  add to score(+)?+
Alice you: 13 (opponent: 20) this round: 2 this roll: 2;  add to score(+)?

... lots of more lines ...

Alice you: 76 (opponent: 66) this round: 8 this roll: 5;  add to score(+)? 
Alice you: 76 (opponent: 66) this round: 13 this roll: 5;  add to score(+)?+
Bob   you: 66 (opponent: 89) this round: 4 this roll: 4;  add to score(+)? 
Bob   you: 66 (opponent: 89) this round: 7 this roll: 3;  add to score(+)? 
Bob   you: 66 (opponent: 89) this round: 12 this roll: 5;  add to score(+)? 
Bob   you: 66 (opponent: 89) this round: 15 this roll: 3;  add to score(+)? 
Bob   you: 66 (opponent: 89) this round: 21 this roll: 6;  add to score(+)? 
Bob   you: 66 (opponent: 89) this round: 0 this roll: 1;  add to score(+)? 
Alice you: 89 (opponent: 66) this round: 6 this roll: 6;  add to score(+)? 
Alice you: 89 (opponent: 66) this round: 11 this roll: 5;  add to score(+)?+
Winner = Alice!

[edit] AutoHotkey

Gui, Font, s12, Verdana
Gui, Add, Text, vPlayer0, Player 0
Gui, Add, Text, vSum0, 000
Gui, Add, Button, Default, Roll
Gui, Add, Text, ys vLastRoll, Roll 0
Gui, Add, Text, vTurnSum, Sum 000
Gui, Add, Button, , Hold
Gui, Add, Text, ys vPlayer1, Player 1
Gui, Add, Text, vSum1, 000
Gui, Add, Button, , Reload
Gui, Show
GuiControl, Disable, Player1
 
CurrentPlayer := 0
ButtonRoll:
Loop 10
{
Random, LastRoll, 1, 6
GuiControl, , LastRoll, Roll %LastRoll%
Sleep 50
}
If LastRoll != 1
{
TurnSum += LastRoll
GuiControl, , TurnSum, Sum %TurnSum%
Return
}
TurnSum := 0
ButtonHold:
Sum%CurrentPlayer% += TurnSum
TurnSum := 0
GuiControl, , LastRoll, Roll
GuiControl, , TurnSum, Sum %TurnSum%
GuiControl, , Sum%CurrentPlayer%, % Sum%CurrentPlayer%
If Sum%CurrentPlayer% >= 100
{
MsgBox Player %CurrentPlayer% Won!
GuiClose:
ExitApp
}
GuiControl, Disable, Player%CurrentPlayer%
CurrentPlayer := !CurrentPlayer
GuiControl, Enable, Player%CurrentPlayer%
Return
 
ButtonReload:
Reload

[edit] C++

 
#include <windows.h>
#include <iostream>
#include <string>
 
//--------------------------------------------------------------------------------------------------
using namespace std;
 
//--------------------------------------------------------------------------------------------------
const int PLAYERS = 2, MAX_POINTS = 100;
 
//--------------------------------------------------------------------------------------------------
class player
{
public:
player() { reset(); }
void reset()
{
name = "";
current_score = round_score = 0;
}
string getName() { return name; }
void setName( string n ) { name = n; }
int getCurrScore() { return current_score; }
void addCurrScore() { current_score += round_score; }
int getRoundScore() { return round_score; }
void addRoundScore( int rs ) { round_score += rs; }
void zeroRoundScore() { round_score = 0; }
 
private:
string name;
int current_score, round_score;
};
//--------------------------------------------------------------------------------------------------
class pigGame
{
public:
pigGame() { resetPlayers(); }
 
void play()
{
while( true )
{
system( "cls" );
int p = 0;
while( true )
{
if( turn( p ) )
{
praise( p );
break;
}
 
++p %= PLAYERS;
}
 
string r;
cout << "Do you want to play again ( y / n )? "; cin >> r;
if( r != "Y" && r != "y" ) return;
resetPlayers();
}
}
 
private:
void resetPlayers()
{
system( "cls" );
string n;
for( int p = 0; p < PLAYERS; p++ )
{
_players[p].reset();
cout << "Enter name player " << p + 1 << ": "; cin >> n;
_players[p].setName( n );
}
 
}
 
void praise( int p )
{
system( "cls" );
cout << "CONGRATULATIONS " << _players[p].getName() << ", you are the winner!" << endl << endl;
cout << "Final Score" << endl;
drawScoreboard();
cout << endl << endl;
}
 
void drawScoreboard()
{
for( int p = 0; p < PLAYERS; p++ )
cout << _players[p].getName() << ": " << _players[p].getCurrScore() << " points" << endl;
cout << endl;
}
 
bool turn( int p )
{
system( "cls" );
drawScoreboard();
_players[p].zeroRoundScore();
string r;
int die;
while( true )
{
cout << _players[p].getName() << ", your round score is: " << _players[p].getRoundScore() << endl;
cout << "What do you want to do (H)old or (R)oll? "; cin >> r;
if( r == "h" || r == "H" )
{
_players[p].addCurrScore();
return _players[p].getCurrScore() >= MAX_POINTS;
}
if( r == "r" || r == "R" )
{
die = rand() % 6 + 1;
if( die == 1 )
{
cout << _players[p].getName() << ", your turn is over." << endl << endl;
system( "pause" );
return false;
}
_players[p].addRoundScore( die );
}
cout << endl;
}
return false;
}
 
player _players[PLAYERS];
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
srand( GetTickCount() );
pigGame pg;
pg.play();
return 0;
}
//--------------------------------------------------------------------------------------------------
 

Output:

Chuck: 14 points
Bob: 16 points

Chuck, your round score is: 0
What do you want to do (H)old or (R)oll? r

Chuck, your round score is: 6
What do you want to do (H)old or (R)oll? r

Chuck, your round score is: 11
What do you want to do (H)old or (R)oll? r

Chuck, your round score is: 16
What do you want to do (H)old or (R)oll?

[edit] C#

 
using System;
using System.IO;
 
namespace Pig {
 
class Roll {
public int TotalScore{get;set;}
public int RollScore{get;set;}
public bool Continue{get;set;}
}
 
class Player {
public String Name{get;set;}
public int Score {get;set;}
Random rand;
 
public Player() {
Score = 0;
rand = new Random();
}
 
public Roll Roll(int LastScore){
Roll roll = new Roll();
roll.RollScore = rand.Next(6) + 1;
 
if(roll.RollScore == 1){
roll.TotalScore = 0;
roll.Continue = false;
return roll;
}
 
roll.TotalScore = LastScore + roll.RollScore;
roll.Continue = true;
return roll;
}
 
public void FinalizeTurn(Roll roll){
Score = Score + roll.TotalScore;
}
}
 
public class Game {
public static void Main(String[] argv){
String input = null;
Player[] players = new Player[2];
 
// Game loop
while(true){
Console.Write("Greetings! Would you like to play a game (y/n)?");
while(input == null){
input = Console.ReadLine();
if(input.ToLowerInvariant() == "y"){
players[0] = new Player();
players[1] = new Player();
Console.Write("Player One, what's your name?");
input = Console.ReadLine();
players[0].Name = input;
Console.Write("Player Two, what's your name?");
input = Console.ReadLine();
players[1].Name = input;
Console.WriteLine(players[0].Name + " and " + players[1].Name + ", prepare to do battle!");
} else if (input.ToLowerInvariant() == "n"){
goto Goodbye; /* Not considered harmful */
} else {
input = null;
Console.Write("I'm sorry, I don't understand. Play a game (y/n)?");
}
}
 
// Play the game
int currentPlayer = 0;
Roll roll = null;
bool runTurn = true;
while(runTurn){
Player p = players[currentPlayer];
roll = p.Roll( (roll !=null) ? roll.TotalScore : 0 );
if(roll.Continue){
if(roll.TotalScore + p.Score > 99){
Console.WriteLine("Congratulations, " + p.Name + "! You rolled a " + roll.RollScore + " for a final score of " + (roll.TotalScore + p.Score) + "!");
runTurn = false;
} else {
Console.Write(p.Name + ": Roll " + roll.RollScore + "/Turn " + roll.TotalScore + "/Total " + (roll.TotalScore + p.Score) + ". Roll again (y/n)?");
input = Console.ReadLine();
if(input.ToLowerInvariant() == "y"){
// Do nothing
} else if (input.ToLowerInvariant() == "n"){
p.FinalizeTurn(roll);
currentPlayer = Math.Abs(currentPlayer - 1);
Console.WriteLine();
Console.WriteLine(players[0].Name + ": " + players[0].Score + " " + players[1].Name + ": " + players[1].Score);
Console.WriteLine(players[currentPlayer].Name + ", your turn begins.");
roll = null;
} else {
input = null;
Console.Write("I'm sorry, I don't understand. Play a game (y/n)?");
}
}
} else {
Console.WriteLine(p.Name + @", you rolled a 1 and lost your points for this turn.
Your current score: "
+ p.Score);
Console.WriteLine();
Console.WriteLine(players[0].Name + ": " + players[0].Score + " " + players[1].Name + ": " + players[1].Score);
currentPlayer = Math.Abs(currentPlayer - 1);
}
}
 
 
input = null;
}
Goodbye:
Console.WriteLine("Thanks for playing, and remember: the house ALWAYS wins!");
System.Environment.Exit(0);
}
}
}
 

[edit] Common Lisp

(defconstant +max-score+ 100)
(defconstant +n-of-players+ 2)
 
(let ((scores (make-list +n-of-players+ :initial-element 0))
(current-player 0)
(round-score 0))
(loop
(format t "Player ~d: (~d, ~d). Rolling? (Y)"
current-player
(nth current-player scores)
round-score)
(if (member (read-line) '("y" "yes" "") :test #'string=)
(let ((roll (1+ (random 6))))
(format t "~tRolled ~d~%" roll)
(if (= roll 1)
(progn
(format t
"~tBust! you lose ~d but still keep your previous ~d~%"
round-score (nth current-player scores))
(setf round-score 0)
(setf current-player
(mod (1+ current-player) +n-of-players+)))
(incf round-score roll)))
(progn
(incf (nth current-player scores) round-score)
(setf round-score 0)
(when (>= (apply #'max scores) 100)
(return))
(format t "~tSticking with ~d~%" (nth current-player scores))
(setf current-player (mod (1+ current-player) +n-of-players+)))))
(format t "~%Player ~d wins with a score of ~d~%" current-player
(nth current-player scores)))
Output:
Player 0: (0, 0). Rolling? (Y)
 Rolled 5
Player 0: (0, 5). Rolling? (Y)
 Rolled 6
Player 0: (0, 11). Rolling? (Y)n
 Sticking with 11
Player 1: (0, 0). Rolling? (Y)
 Rolled 4
Player 1: (0, 4). Rolling? (Y)
 Rolled 3
Player 1: (0, 7). Rolling? (Y)
 Rolled 6
Player 1: (0, 13). Rolling? (Y)n
 Sticking with 13
...
Player 0: (81, 0). Rolling? (Y)
 Rolled 2
Player 0: (81, 2). Rolling? (Y)
 Rolled 2
Player 1: (85, 0). Rolling? (Y)
 Rolled 3
Player 1: (85, 3). Rolling? (Y)
 Rolled 3
Player 1: (85, 6). Rolling? (Y)
 Rolled 5
Player 1: (85, 11). Rolling? (Y)
 Rolled 6
Player 1: (85, 17). Rolling? (Y)n

Player 1 wins with a score of 102

[edit] D

Translation of: Python
void main() {
import std.stdio, std.string, std.algorithm, std.random;
enum maxScore = 100;
enum playerCount = 2;
immutable confirmations = ["yes", "y", ""];
 
int[playerCount] safeScore;
int player, score;
 
while (true) {
writef(" Player %d: (%d, %d). Rolling? (y/n) ", player,
safeScore[player], score);
if (safeScore[player] + score < maxScore &&
confirmations.canFind(readln.strip.toLower)) {
immutable rolled = uniform(1, 7);
writefln(" Rolled %d", rolled);
if (rolled == 1) {
writefln(" Bust! You lose %d but keep %d\n",
score, safeScore[player]);
} else {
score += rolled;
continue;
}
} else {
safeScore[player] += score;
if (safeScore[player] >= maxScore)
break;
writefln(" Sticking with %d\n", safeScore[player]);
}
 
score = 0;
player = (player + 1) % playerCount;
}
 
writefln("\n\nPlayer %d wins with a score of %d",
player, safeScore[player]);
}
Output:
 Player 0: (0, 0). Rolling? (y/n) 
   Rolled 6
 Player 0: (0, 6). Rolling? (y/n) 
   Rolled 5
 Player 0: (0, 11). Rolling? (y/n) 
   Rolled 1
 Bust! you lose 11 but keep 0

 Player 1: (0, 0). Rolling? (y/n) 
   Rolled 3
 Player 1: (0, 3). Rolling? (y/n) 
   Rolled 4
 Player 1: (0, 7). Rolling? (y/n) 
   Rolled 6
 Player 1: (0, 13). Rolling? (y/n) n
 Sticking with 13

 ...

 Player 0: (88, 0). Rolling? (y/n) 
   Rolled 6
 Player 0: (88, 6). Rolling? (y/n) 
   Rolled 4
 Player 0: (88, 10). Rolling? (y/n) 
   Rolled 3
 Player 0: (88, 13). Rolling? (y/n)

 Player 0 wins with a score of 101

[edit] Erlang

Some of the code (ex: quit/2) is only there to make play during development easier. Some (ex: player_name/1) is only there to make Pig_the_dice_game/Player easier.

 
-module( pig_dice ).
 
-export( [game/1, goal/0, hold/2, player_name/1, players_totals/1, quit/2, roll/2, score/1, task/0] ).
 
-record( player, {name, score=0, total=0} ).
 
game( [_Player | _T]=Players ) ->
My_pid = erlang:self(),
erlang:spawn_link( fun() -> random:seed(os:timestamp()), game_loop( [#player{name=X} || X <- Players], 100, My_pid ) end ).
 
goal() -> 100.
 
hold( Player, Game ) -> Game ! {next_player, Player}.
 
players_totals( Game ) -> ask( Game, players_totals ).
 
player_name( Game ) -> ask( Game, name ).
 
quit( Player, Game ) -> Game ! {quit, Player}.
 
roll( Player, Game ) -> Game ! {roll, Player}.
 
score( Game ) -> ask( Game, score ).
 
task() ->
Game = game( ["Player1", "Player2"] ),
Play = erlang:spawn( fun() -> play_loop( Game ) end ),
receive
{pig, Result, Game} ->
erlang:exit( Play, kill ),
task_display( Result ),
Result
end.
 
 
 
ask( Game, Question ) ->
Game ! {Question, erlang:self()},
receive
{Question, Answer, Game} -> Answer
end.
 
game_loop( [], _Goal, Report_pid ) -> Report_pid ! {pig, game_over_all_quite. erlang:self()};
game_loop( [#player{name=Name}=Player | T]=Players, Goal, Report_pid ) ->
receive
{name, Pid} ->
Pid ! {name, Player#player.name, erlang:self()},
game_loop( Players, Goal, Report_pid );
{next_player, Name} ->
New_players = game_loop_next_player( Player#player.total + Player#player.score, Players, Goal, Report_pid ),
game_loop( New_players, Goal, Report_pid );
{players_totals, Pid} ->
Pid ! {players_totals, [{X#player.name, X#player.total} || X <- Players], erlang:self()},
game_loop( Players, Goal, Report_pid );
{quit, Name} -> game_loop( T, Goal, Report_pid );
{roll, Name} ->
New_players = game_loop_roll( random:uniform(6), Players ),
game_loop( New_players, Goal, Report_pid );
{score, Pid} ->
Pid ! {score, Player#player.score, erlang:self()},
game_loop( Players, Goal, Report_pid )
end.
 
game_loop_next_player( Total, [Player | T], Goal, Report_pid ) when Total >= Goal ->
Report_pid ! {pig, [{X#player.name, X#player.total} || X <- [Player | T]]. erlang:self()},
[];
game_loop_next_player( Total, [Player | T], _Goal, _Report_pid ) ->
T ++ [Player#player{score=0, total=Total}].
 
game_loop_roll( 1, [Player | T] ) -> T ++ [Player#player{score=0}];
game_loop_roll( Score, [#player{score=Old_score}=Player | T] ) -> [Player#player{score=Old_score + Score} | T].
 
play_loop( Game ) ->
Name = player_name( Game ),
io:fwrite( "Currently ~p.~n", [players_totals(Game)] ),
io:fwrite( "Name ~p.~n", [Name] ),
roll( Name, Game ),
Score = score( Game ),
io:fwrite( "Rolled, score this round ~p.~n", [Score] ),
play_loop_next( Score, Name, Game ),
play_loop( Game ).
 
play_loop_command( {ok, ["y" ++ _T]}, _Name, _Game ) -> ok;
play_loop_command( {ok, ["n" ++ _T]}, Name, Game ) -> hold( Name, Game );
play_loop_command( {ok, ["q" ++ _T]}, Name, Game ) -> quit( Name, Game );
play_loop_command( {ok, _T}, Name, Game ) -> play_loop_command( io:fread("Roll again (y/n/q): ", "~s"), Name, Game ).
 
play_loop_next( 0, _Name, _Game ) -> io:fwrite( "~nScore 0, next player.~n" );
play_loop_next( _Score, Name, Game ) -> play_loop_command( io:fread("Roll again (y/n/q): ", "~s"), Name, Game ).
 
task_display( Results ) when is_list(Results) ->
[{Name, Total} | Rest] = lists:reverse( lists:keysort(2, Results) ),
io:fwrite( "Winner is ~p with total of ~p~n", [Name, Total] ),
io:fwrite( "Then follows: " ),
[io:fwrite("~p with ~p~n", [N, T]) || {N, T} <- Rest];
task_display( Result ) -> io:fwrite( "Result: ~p~n", [Result] ).
 
Output:

Start of game:

2> pig_dice:task().
Currently [{"Player1",0},{"Player2",0}].
Name "Player1".
Rolled, score this round 3.
Roll again (y/n/q): y
Currently [{"Player1",0},{"Player2",0}].
Name "Player1".
Rolled, score this round 8.
Roll again (y/n/q): y
Currently [{"Player1",0},{"Player2",0}].
Name "Player1".
Rolled, score this round 14.
Roll again (y/n/q): n
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 4.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 6.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 10.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 16.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 21.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 24.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 28.
Roll again (y/n/q): y
Currently [{"Player2",0},{"Player1",14}].
Name "Player2".
Rolled, score this round 0.

Score 0, next player.
Currently [{"Player1",14},{"Player2",0}].
Name "Player1".
Rolled, score this round 2.
Roll again (y/n/q): 

[edit] Forth

Works with: 4tH version 3.62.1
include lib/choose.4th
include lib/yesorno.4th
 
: turn ( n1 -- n2)
." Player " . ." is up" cr \ which player is up
0 begin \ nothing so far
s" Rolling" yes/no? \ stand or roll?
while \ now roll the dice
6 choose 1+ dup ." Rolling " . dup 1 =
if drop drop 0 else + ." (" dup 0 .r ." )" then cr dup 0=
until \ until player stands or 1 is rolled
;
 
: pigthedice ( --)
2 0 1 over \ setup players
begin over turn + dup ." Total score: " . cr cr dup 100 < while 2swap repeat
." Player " swap . ." won with " . ." points." cr
." Player " swap . ." lost with " . ." points." cr
; \ show the results
 
pigthedice

[edit] Groovy

Currently hard coded for 2 players, but will work for multiple players

 
class PigDice {
 
final static int maxScore = 100;
final static yesses = ["yes", "y", "", "Y", "YES"]
 
static main(args) {
def playersCount = 2
Scanner sc = new Scanner(System.in)
Map scores = [:]
def current = 0
def player = 0
def gameOver = false
def firstThrow = true
Random rnd = new Random()
 
// Initialise the players' scores
(0..(playersCount-1)).each{ it->
scores[it] = 0
}
 
// Game starts
while (!gameOver) {
def nextPlayer = false
String ln
 
// Automatic rolls for the first dice roll
if (firstThrow){
println "player ${player+1} Auto Rolling... "
ln = 'y'
firstThrow = false
} else {
println "player ${player+1} Rolling? Yes(y) or No(n) "
ln = sc.nextLine()
}
 
if (ln in yesses){
// if yes then roll the dice
int rolled = rnd.nextInt(6) + 1
print "The Roll was $rolled --- "
 
if (rolled == 1) {
println " Bust! Player ${player+1} loses $current but keep ${scores[player]}"
current = 0
nextPlayer = true
firstThrow = true
} else {
// dice rolls 2 to 6
current = current + rolled
if ((current + scores[player]) > maxScore){
gameOver = true
}else{
// as a session score gets larger the message returned changes
switch (current){
case 6..15:
print "Good. "
break
case 15..29:
print "lucky! "
break
case 29..39:
print "Great! "
break
default:
print "Amazing "
}
println "Player ${player+1} now has $current this session (possible score of ${current + scores[player]})"
}
}
} else{
// if no then bank the session score
nextPlayer = true
firstThrow = true
scores[player] = scores[player] + current
current = 0
println "chicken! player ${player+1} now has ${scores[player]} and $gameOver"
println "Current scores :"
for (i in scores){
println "player ${i.key + 1}| ${i.value} "
}
println "------------------------------"
 
}
println ""
 
if (nextPlayer) {
player = (player+1)%playersCount
println "** Next player is ${player+1}"
}
}
 
// Game ends
println "Player ${player+1} wins"
}
}
 

[edit] J

require'misc'
 
status=:3 :0
'pid cur tot'=. y
player=. 'player ',":pid
potential=. ' potential: ',":cur
total=. ' total: ',":tot
smoutput player,potential,total
)
 
getmove=:3 :0
whilst.1~:+/choice do.
choice=.'HRQ' e. prompt ' Roll the dice or Hold or Quit? [R or H or Q]: '
end.
choice#'HRQ'
)
 
NB. simulate an y player game of pig
pigsim=:3 :0
smoutput (":y),' player game of pig'
scores=.y#0
while.100>>./scores do.
for_player.=i.y do.
pid=.1+I.player
smoutput 'begining of turn for player ',":pid
current=. 0
whilst. (1 ~: roll) *. 'R' = move do.
status pid, current, player+/ .*scores
move=. getmove''
roll=. 1+?6
if.'R'=move do.
smoutput 'rolled a ',":roll
current=. (1~:roll)*current+roll
end.
end.
scores=. scores+(current*player)+100*('Q'e.move)*-.player
smoutput 'player scores now: ',":scores
end.
end.
smoutput 'player ',(":1+I.scores>:100),' wins'
)

Example game:

   pigsim 2
2 player game of pig
begining of turn for player 1
player 1 potential: 0 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 3
player 1 potential: 3 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 1 potential: 9 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 4
player 1 potential: 13 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 1 potential: 19 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 2
player 1 potential: 21 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: H
player scores now: 21 0
begining of turn for player 2
player 2 potential: 0 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 3
player 2 potential: 3 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 2 potential: 9 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 4
player 2 potential: 13 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 2 potential: 19 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 3
player 2 potential: 22 total: 0
Roll the dice or Hold or Quit? [R or H or Q]: H
player scores now: 21 22
begining of turn for player 1
player 1 potential: 0 total: 21
Roll the dice or Hold or Quit? [R or H or Q]: R
 
...
 
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 1 potential: 22 total: 62
Roll the dice or Hold or Quit? [R or H or Q]: H
player scores now: 84 90
begining of turn for player 2
player 2 potential: 0 total: 90
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 2 potential: 6 total: 90
Roll the dice or Hold or Quit? [R or H or Q]: R
rolled a 6
player 2 potential: 12 total: 90
Roll the dice or Hold or Quit? [R or H or Q]: H
player scores now: 84 102
player 2 wins

[edit] Java

Translation of: D
import java.util.*;
 
public class PigDice {
 
public static void main(String[] args) {
final int maxScore = 100;
final int playerCount = 2;
final String[] yesses = {"y", "Y", ""};
 
int[] safeScore = new int[2];
int player = 0, score = 0;
 
Scanner sc = new Scanner(System.in);
Random rnd = new Random();
 
while (true) {
System.out.printf(" Player %d: (%d, %d) Rolling? (y/n) ", player,
safeScore[player], score);
if (safeScore[player] + score < maxScore
&& Arrays.asList(yesses).contains(sc.nextLine())) {
final int rolled = rnd.nextInt(6) + 1;
System.out.printf(" Rolled %d\n", rolled);
if (rolled == 1) {
System.out.printf(" Bust! You lose %d but keep %d\n\n",
score, safeScore[player]);
} else {
score += rolled;
continue;
}
} else {
safeScore[player] += score;
if (safeScore[player] >= maxScore)
break;
System.out.printf(" Sticking with %d\n\n", safeScore[player]);
}
score = 0;
player = (player + 1) % playerCount;
}
System.out.printf("\n\nPlayer %d wins with a score of %d",
player, safeScore[player]);
}
}
Works with: Java version 8+
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
import java.util.stream.IntStream;
 
public interface PigDice {
public static void main(String... arguments) {
final int maxScore = 100;
final int playerCount = 2;
final String[] yesses = {"y", "Y", ""};
 
final Scanner scanner = new Scanner(System.in);
final Random random = new Random();
 
final int[] safeScore = new int[2];
final int[] score = new int[2];
 
IntStream.iterate(0, player -> (player + 1) % playerCount)
.map(player -> {
boolean isRolling = true;
while (isRolling) {
System.out.printf(
"Player %d: (%d, %d) Rolling? (y/n) ",
player,
safeScore[player],
score[player]
);
isRolling =
safeScore[player] + score[player] < maxScore
&& Arrays.asList(yesses).contains(scanner.nextLine())
;
if (isRolling) {
final int rolled = random.nextInt(6) + 1;
System.out.printf("Rolled %d\n", rolled);
if (rolled == 1) {
System.out.printf(
"Bust! You lose %d but keep %d\n\n",
score[player],
safeScore[player]
);
return -1;
} else {
score[player] += rolled;
}
} else {
safeScore[player] += score[player];
if (safeScore[player] >= maxScore) {
return player;
}
System.out.printf("Sticking with %d\n\n", safeScore[player]);
}
}
score[player] = 0;
return -1;
})
.filter(player -> player > -1)
.findFirst()
.ifPresent(player ->
System.out.printf(
"\n\nPlayer %d wins with a score of %d",
player,
safeScore[player]
)
)
;
}
}
 Player 0: (0, 0) Rolling? (y/n) y 
 Rolled 3
 Player 0: (0, 3) Rolling? (y/n) Y
 Rolled 5
 Player 0: (0, 8) Rolling? (y/n) 
 Rolled 2
 Player 0: (0, 10) Rolling? (y/n) n
 Sticking with 10

 Player 1: (0, 0) Rolling? (y/n) 
 Rolled 1
 Bust! You lose 0 but keep 0

 Player 0: (10, 0) Rolling? (y/n) 
 Rolled 1
 Bust! You lose 0 but keep 10

 Player 1: (0, 0) Rolling? (y/n) 
 Rolled 4
 Player 1: (0, 4) Rolling? (y/n) 
 Rolled 5
 Player 1: (0, 9) Rolling? (y/n) 
 Rolled 1
 Bust! You lose 9 but keep 0

(...)

 Player 1: (96, 0) Rolling? (y/n) 
 Rolled 4
 Player 1: (96, 4) Rolling? (y/n) 
 Rolled 2
 Player 1: (96, 6) Rolling? (y/n) n

Player 1 wins with a score of 102

[edit] Mathematica

DynamicModule[{score, players = {1, 2}, roundscore = 0, 
roll}, (score@# = 0) & /@ players;
Panel@Dynamic@
Column@{Grid[
Prepend[{#, score@#} & /@ players, {"Player", "Score"}],
Background -> {None, 2 -> Gray}], roundscore,
If[ValueQ@roll, Row@{"Rolled ", roll}, ""],
If[IntegerQ@roundscore,
Row@{Button["Roll", roll = RandomInteger[{1, 6}];
If[roll == 1, roundscore = 0; players = RotateLeft@players,
roundscore += roll]],
Button["Hold", score[players[[1]]] += roundscore;
roundscore = 0;
If[score[players[[1]]] >= 100, roll =.;
roundscore = Row@{players[[1]], " wins."},
players = RotateLeft@players]]},
Button["Play again.",
roundscore = 0; (score@# = 0) & /@ players]]}]

[edit] Objeck

 
class Pig {
function : Main(args : String[]) ~ Nil {
player_count := 2;
max_score := 100;
safe_score := Int->New[player_count];
player := 0; score := 0;
 
while(true) {
safe := safe_score[player];
" Player {$player}: ({$safe}, {$score}) Rolling? (y/n) "->PrintLine();
rolling := IO.Console->ReadString();
if(safe_score[player] + score < max_score & (rolling->Equals("y") | rolling->Equals("yes"))) {
rolled := ((Float->Random() * 100.0)->As(Int) % 6) + 1;
" Rolled {$rolled}"->PrintLine();
if(rolled = 1) {
safe := safe_score[player];
" Bust! you lose {$score} but still keep your previous {$safe}\n"->PrintLine();
score := 0;
player := (player + 1) % player_count;
}
else {
score += rolled;
};
}
else {
safe_score[player] += score;
if(safe_score[player] >= max_score) {
break;
};
safe := safe_score[player];
" Sticking with {$safe}\n"->PrintLine();
score := 0;
player := (player + 1) % player_count;
};
};
safe := safe_score[player];
"\n\nPlayer {$player} wins with a score of {$safe}"->PrintLine();
}
}
 
 Player 0: (0, 0) Rolling? (y/n) 
y
 Rolled 3
 Player 0: (0, 3) Rolling? (y/n) 
y
 Rolled 2
 Player 0: (0, 5) Rolling? (y/n) 
...
 Rolled 4
 Player 1: (56, 30) Rolling? (y/n) 
n
 Sticking with 86

 Player 0: (94, 0) Rolling? (y/n) 
y
 Rolled 6
 Player 0: (94, 6) Rolling? (y/n) 
n
...
 Rolled 4
 Player 1: (56, 30) Rolling? (y/n) 
n
 Sticking with 86

 Player 0: (94, 0) Rolling? (y/n) 
y
 Rolled 6
 Player 0: (94, 6) Rolling? (y/n) 
n

[edit] Perl

You can have as many players as you want, simply provide their names on the command line.

#!perl
use strict;
use warnings;
my @players = @ARGV;
@players = qw(Joe Mike);
my @scores = (0) x @players;
while( 1 ) {
PLAYER: for my $i ( 0 .. $#players ) {
my $name = $players[$i];
my $score = $scores[$i];
my $roundscore = 1 + int rand 6;
print "$name, your score so far is $score.\n";
print "You rolled a $roundscore.\n";
next PLAYER if $roundscore == 1;
while($score + $roundscore < 100) {
print "Roll again, or hold [r/h]: ";
my $answer = <>;
$answer = 'h' unless defined $answer;
if( $answer =~ /^h/i ) {
$score += $roundscore;
$scores[$i] = $score;
print "Your score is now $score.\n";
next PLAYER;
} elsif( $answer =~ /^r/ ) {
my $die = 1 + int rand 6;
print "$name, you rolled a $die.\n";
next PLAYER if $die == 1;
$roundscore += $die;
print "Your score for the round is now $roundscore.\n";
} else {
print "I did not understand that.\n";
}
}
$score += $roundscore;
print "With that, your score became $score.\n";
print "You won!\n";
exit;
}
}
__END__
 

[edit] Perl 6

Works with: niecza version 2012-09-12
constant DIE = 1..6;
 
sub MAIN (Int :$players = 2, Int :$goal = 100) {
my @safe = 0 xx $players;
for ^$players xx * -> $player {
say "\nOK, player #$player is up now.";
my $safe = @safe[$player];
my $ante = 0;
until $safe + $ante >= $goal or
prompt("#$player, you have $safe + $ante = {$safe+$ante}. Roll? [Yn] ") ~~ /:i ^n/
{
given DIE.roll {
say " You rolled a $_.";
when 1 {
say " Bust! You lose $ante but keep your previous $safe.";
$ante = 0;
last;
}
when 2..* {
$ante += $_;
}
}
}
$safe += $ante;
if $safe >= $goal {
say "\nPlayer #$player wins with a score of $safe!";
last;
}
@safe[$player] = $safe;
say " Sticking with $safe." if $ante;
}
}

The game defaults to the specified task, but we'll play a shorter game with three players for our example:

Output:
> pig help
Usage:
  pig [--players=<Int>] [--goal=<Int>]
> pig --players=3 --goal=20

OK, player #0 is up now.
#0, you have 0 + 0 = 0. Roll? [Yn] 
  You rolled a 6.
#0, you have 0 + 6 = 6. Roll? [Yn] 
  You rolled a 6.
#0, you have 0 + 12 = 12. Roll? [Yn] n
  Sticking with 12.

OK, player #1 is up now.
#1, you have 0 + 0 = 0. Roll? [Yn] 
  You rolled a 4.
#1, you have 0 + 4 = 4. Roll? [Yn] 
  You rolled a 6.
#1, you have 0 + 10 = 10. Roll? [Yn] 
  You rolled a 6.
#1, you have 0 + 16 = 16. Roll? [Yn] n
  Sticking with 16.

OK, player #2 is up now.
#2, you have 0 + 0 = 0. Roll? [Yn] 
  You rolled a 5.
#2, you have 0 + 5 = 5. Roll? [Yn] 
  You rolled a 1.
  Bust!  You lose 5 but keep your previous 0.

OK, player #0 is up now.
#0, you have 12 + 0 = 12. Roll? [Yn] 
  You rolled a 1.
  Bust!  You lose 0 but keep your previous 12.

OK, player #1 is up now.
#1, you have 16 + 0 = 16. Roll? [Yn] n

OK, player #2 is up now.
#2, you have 0 + 0 = 0. Roll? [Yn] 
  You rolled a 6.
#2, you have 0 + 6 = 6. Roll? [Yn] 
  You rolled a 6.
#2, you have 0 + 12 = 12. Roll? [Yn] 
  You rolled a 4.
#2, you have 0 + 16 = 16. Roll? [Yn] 
  You rolled a 6.

Player #2 wins with a score of 22!

[edit] PHP

Translation of: D
error_reporting(E_ALL & ~ ( E_NOTICE | E_WARNING ));
 
define('MAXSCORE', 100);
define('PLAYERCOUNT', 2);
 
$confirm = array('Y', 'y', '');
 
while (true) {
printf(' Player %d: (%d, %d) Rolling? (Yn) ', $player,
$safeScore[$player], $score);
if ($safeScore[$player] + $score < MAXSCORE &&
in_array(trim(fgets(STDIN)), $confirm)) {
$rolled = rand(1, 6);
echo " Rolled $rolled \n";
if ($rolled == 1) {
printf(' Bust! You lose %d but keep %d \n\n',
$score, $safeScore[$player]);
} else {
$score += $rolled;
continue;
}
} else {
$safeScore[$player] += $score;
if ($safeScore[$player] >= MAXSCORE)
break;
echo ' Sticking with ', $safeScore[$player], '\n\n';
}
$score = 0;
$player = ($player + 1) % PLAYERCOUNT;
}
printf('\n\nPlayer %d wins with a score of %d ',
$player, $safeScore[$player]);
 
C:\UniServer\usr\local\php\php pig.php
 Player 0: (0, 0) Rolling? (Yn)
 Rolled 2
 Player 0: (0, 2) Rolling? (Yn)
 Rolled 1
 Bust! You lose 2 but keep 0

 Player 1: (0, 0) Rolling? (Yn)
 Rolled 2
 Player 1: (0, 2) Rolling? (Yn)
 Rolled 1
 Bust! You lose 2 but keep 0

 Player 0: (0, 0) Rolling? (Yn)
 Rolled 3
 Player 0: (0, 3) Rolling? (Yn)
 Rolled 6
 Player 0: (0, 9) Rolling? (Yn) n
 sticking with 9

 Player 1: (0, 0) Rolling? (Yn)
 Rolled 5
 Player 1: (0, 5) Rolling? (Yn)
 Rolled 3
 Player 1: (0, 8) Rolling? (Yn) n
 sticking with 8

 (...)
 
 Player 1: (93, 0) Rolling? (Yn)
 Rolled 5
 Player 1: (93, 5) Rolling? (Yn)
 Rolled 3
 Player 1: (93, 8) Rolling? (Yn)

Player 1 wins with a score of 101

[edit] Python

#!/usr/bin/python3
 
'''
See: http://en.wikipedia.org/wiki/Pig_(dice)
 
This program scores and throws the dice for a two player game of Pig
 
'''

 
from random import randint
 
playercount = 2
maxscore = 100
safescore = [0] * playercount
player = 0
score=0
 
while max(safescore) < maxscore:
rolling = input("Player %i: (%i, %i) Rolling? (Y) "
 % (player, safescore[player], score)).strip().lower() in {'yes', 'y', ''}
if rolling:
rolled = randint(1, 6)
print(' Rolled %i' % rolled)
if rolled == 1:
print(' Bust! you lose %i but still keep your previous %i'
 % (score, safescore[player]))
score, player = 0, (player + 1) % playercount
else:
score += rolled
else:
safescore[player] += score
if safescore[player] >= maxscore:
break
print(' Sticking with %i' % safescore[player])
score, player = 0, (player + 1) % playercount
 
print('\nPlayer %i wins with a score of %i' %(player, safescore[player]))
Samples from a game
Player 0: (0, 0) Rolling? (Y) 
  Rolled 6
Player 0: (0, 6) Rolling? (Y) 
  Rolled 5
Player 0: (0, 11) Rolling? (Y) 
  Rolled 1
  Bust! you lose 11 but still keep your previous 0
Player 1: (0, 0) Rolling? (Y) 
  Rolled 3
Player 1: (0, 3) Rolling? (Y) 
  Rolled 4
Player 1: (0, 7) Rolling? (Y) 
  Rolled 6
Player 1: (0, 13) Rolling? (Y) n
  Sticking with 13
...
Player 0: (78, 10) Rolling? (Y) n
  Sticking with 88
Player 1: (63, 0) Rolling? (Y) 
  Rolled 6
Player 1: (63, 6) Rolling? (Y) 
  Rolled 1
  Bust! you lose 6 but still keep your previous 63
Player 0: (88, 0) Rolling? (Y) n
  Sticking with 88
Player 1: (63, 0) Rolling? (Y) n
  Sticking with 63
Player 0: (88, 0) Rolling? (Y) 
  Rolled 6
Player 0: (88, 6) Rolling? (Y) 
  Rolled 4
Player 0: (88, 10) Rolling? (Y) 
  Rolled 3
Player 0: (88, 13) Rolling? (Y) n

Player 0 wins with a score of 101

[edit] Racket

 
#lang racket
 
(define (pig-the-dice #:print? [print? #t] . players)
(define prn (if print? (λ xs (apply printf xs) (flush-output)) void))
(define names (for/list ([p players] [n (in-naturals 1)]) n))
(define points (for/list ([p players]) (box 0)))
(with-handlers ([(negate exn?) identity])
(for ([nm (in-cycle names)] [tp (in-cycle points)] [pl (in-cycle players)])
(prn (string-join (for/list ([n names] [p points])
(format "Player ~a, ~a points" n (unbox p)))
"; " #:before-first "Status: " #:after-last ".\n"))
(let turn ([p 0] [n 0])
(prn "Player ~a, round #~a, [R]oll or [P]ass? " nm (+ 1 n))
(define roll? (pl (unbox tp) p n))
(unless (eq? pl human) (prn "~a\n" (if roll? 'R 'P)))
(if (not roll?) (set-box! tp (+ (unbox tp) p))
(let ([r (+ 1 (random 6))])
(prn " Dice roll: ~s => " r)
(if (= r 1) (prn "turn lost\n")
(let ([p (+ p r)]) (prn "~a points\n" p) (turn p (+ 1 n)))))))
(prn "--------------------\n")
(when (<= 100 (unbox tp)) (prn "Player ~a wins!\n" nm) (raise nm)))))
 
(define (human total-points turn-points round#)
(case (string->symbol (car (regexp-match #px"[A-Za-z]?" (read-line))))
[(R r) #t] [(P p) #f] [else (human total-points turn-points round#)]))
 
(pig-the-dice #:print? #t human human)
 

[edit] REXX

This REXX program has the following features:

  • any number of human players can play
  • any number of computer players can play
  • human and computers can play together (humans always go first)
  • names of the human players can be specified
  • names of the computer players can be specified
  • the score needed to win may be specified
  • verbosity was chosen as it's assumed that a human is playing
  • code was written to allow for an   N   sided die
  • names are used for the die faces (in addition to the pip value)
  • a simple (but aggressive) strategy is used (that favors a human player)
/*REXX program plays pig the dice game (any # of CBLFs and/or silicons).*/
signal on syntax; signal on novalue /*handle REXX program errors. */
sw=linesize()-1 /*get the width of the terminal. */
parse arg hp cp win die _ . '(' names ")" /*obtain optional arguments.*/
/*names with blanks should use _ */
if _\=='' then call err 'too many arguments were specified: ' _
@nhp = 'number of human players'  ; hp =scrutinize( hp,@nhp , 0, 0, 0)
@ncp = 'number of computer players'; cp =scrutinize( cp,@ncp , 0, 0, 2)
@sn2w = 'score needed to win'  ; win=scrutinize(win,@sn2w, 1,1e6,60)
@nsid = 'number of sides in die'  ; die=scrutinize(die,@nsid, 2,999, 6)
if hp==0 & cp==0 then cp=2 /*if both counts are zero, 2 HALs*/
if hp==1 & cp==0 then cp=1 /*if one human, then use 1 HAL.*/
name.= /*nullify all names (to a blank).*/
L=0 /*maximum length of a player name*/
do i=1 for hp+cp /*get the player's names, maybe. */
if i>hp then @='HAL_'i"_the_computer" /*use this for default.*/
else @='player_'i /* " " " " */
name.i = translate( word( strip( word(names,i)) @, 1),,'_')
L=max(L, length(name.i)) /*use L for nice name formatting.*/
end /*i*/ /*underscores are changed─►blanks*/
 
hpn=hp; if hpn==0 then hpn='no' /*use normal English for display.*/
cpn=cp; if cpn==0 then cpn="no" /* " " " " " */
say 'Pig (the dice game) is being played with:' /*introduction to pig.*/
if cpn\==0 then say right(cpn,9) 'computer player's(cp)
if hpn\==0 then say right(hpn,9) 'human player's(hp)
say 'and the' @sn2w "is: " win ' (or greater).'
!.=; dieNames='ace deuce trey square nickle boxcar' /*die face names.*/
/*note: snake eyes is for 2 aces.*/
!w=0; do i=1 for die;  !.i=' ['word(dieNames,i)"]"
 !w=max(!w, length(!.i)) /*!w ──► maximum length die name.*/
end /*i*/
s.=0 /*set all player's scores to zero*/
!w=!w+length(die)+3 /*pad the die number and die name*/
@=copies('─',9) /*an eyecatcher (for prompting). */
@jra='just rolled a '; @ati='and the inning' /*nice literals to have.*/
/*──────────────────────────────────────────────────let's play some pig.*/
do game=1; in.=0 /*set each inning's score to zero*/
say; say copies('█',sw) /*display a fence for da eyeballs*/
 
do k=1 for hp+cp /*display the scores (as a recap)*/
say 'The score for ' left(name.k,L) " is " right(s.k,length(win))'.'
end /*k*/
 
say copies('█',sw) /*display a fence for da eyeballs*/
 
do j=1 for hp+cp /*let each player roll their dice*/
say; say copies('─',sw); /*display a fence for da eyeballs*/
it=name.j
say it', your total score (so far) in this pig game is: ' s.j"."
 
do until stopped /*keep prompting/rolling 'til not*/
r=random(1,die) /*get a random die face (number).*/
 !=left(space(r !.r','), !w) /*for color, use a die-face name.*/
in.j=in.j+r /*add die-face number to inning. */
if r==1 then do; say it @jra ! || @ati "is a bust."; leave; end
say it @jra ! || @ati "total is: " in.j
stopped=what2do(j) /*determine|ask to stop rolling.*/
if j>hp & stopped then say ' and' name.j "elected to stop rolling."
end /*until stopped*/
 
if r\==1 then s.j=s.j+in.j /*if not a bust, then add inning.*/
if s.j>=win then leave game /*we have a winner, so game ends.*/
end /*j*/ /*that's the end of the players. */
end /*game*/
 
say; say; say; say; say center(''name.j "won! ",sw,'═'); say; say; exit
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────S subroutine────────────────────────*/
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1) /*plural?*/
/*──────────────────────────────────SCRUTINIZE subroutine───────────────*/
scrutinize: parse arg ?,what,min,max /*? is the number, or maybe not. */
if ?=='' |  ?==',' then return arg(5)
if \datatype(?,'N') then call err what "isn't numeric: "  ?;  ?=?/1
if \datatype(?,'W') then call err what "isn't an integer: " ?
if ?==0 & min>0 then call err what "can't be zero."
if ?<min then call err what "can't be less than" min': '  ?
if ?==0 & max>0 then call err what "can't be zero."
if ?>max & max\==0 then call err what "can't be greater than" max': '  ?
return ?
/*──────────────────────────────────what2do subroutine──────────────────*/
what2do: parse arg who /*"who" is a human or a computer.*/
if j>hp & s.j+in.j>=win then return 1 /*an easy choice for HAL.*/
if j>hp & in.j>=win%4 then return 1 /*a simple stategy for HAL.*/
if j>hp then return 0 /*HAL says, keep truckin'! */
say @ name.who', what do you want to do? (a QUIT will stop the game),'
say @ 'press ENTER to roll again, or anything else to STOP rolling.'
pull action; action=space(action) /*remove any superfluous blanks. */
if \abbrev('QUIT',action,1) then return action\==''
say; say; say; say center(' quitting. ',sw,'─'); say; say; say; exit
/*───────────────────────────────error handling subroutines and others.─*/
err: say; say; say center(' error! ',max(40,linesize()%2),"*"); say
do j=1 for arg(); say arg(j); say; end; say; exit 13
 
novalue: syntax: call err 'REXX program' condition('C') "error",,
condition('D'),'REXX source statement (line' sigl"):",,
sourceline(sigl)

This REXX program makes use of   LINESIZE   REXX program (or BIF) which is used to determine the screen width (or linesize) of the terminal (console).
The   LINESIZE.REX   REXX program is included here ──► LINESIZE.REX.

output when using the input of:   0 2 44 ( HAL R2D2
[This plays a simulated game with no humans, two computers, and the score to win is 44, player names are specified.]

Pig (the dice game) is being played with:
        2 computer players
       no human players
and the score needed to win is:  44    (or greater).

███████████████████████████████████████████████████████████████████████████████
The score for  HAL   is   0.
The score for  R2D2  is   0.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL,  your total score (so far) in this pig game is:  0.
HAL just rolled a  6 [boxcar],  and the inning total is:  6
HAL just rolled a  2 [deuce],   and the inning total is:  8
HAL just rolled a  3 [trey],    and the inning total is:  11
 and HAL elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
R2D2,  your total score (so far) in this pig game is:  0.
R2D2 just rolled a  3 [trey],    and the inning total is:  3
R2D2 just rolled a  6 [boxcar],  and the inning total is:  9
R2D2 just rolled a  1 [ace],     and the inning is a bust.

███████████████████████████████████████████████████████████████████████████████
The score for  HAL   is  11.
The score for  R2D2  is   0.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL,  your total score (so far) in this pig game is:  11.
HAL just rolled a  2 [deuce],   and the inning total is:  2
HAL just rolled a  6 [boxcar],  and the inning total is:  8
HAL just rolled a  5 [nickle],  and the inning total is:  13
 and HAL elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
R2D2,  your total score (so far) in this pig game is:  0.
R2D2 just rolled a  6 [boxcar],  and the inning total is:  6
R2D2 just rolled a  6 [boxcar],  and the inning total is:  12
 and R2D2 elected to stop rolling.

███████████████████████████████████████████████████████████████████████████████
The score for  HAL   is  24.
The score for  R2D2  is  12.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL,  your total score (so far) in this pig game is:  24.
HAL just rolled a  5 [nickle],  and the inning total is:  5
HAL just rolled a  3 [trey],    and the inning total is:  8
HAL just rolled a  2 [deuce],   and the inning total is:  10
HAL just rolled a  5 [nickle],  and the inning total is:  15
 and HAL elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
R2D2,  your total score (so far) in this pig game is:  12.
R2D2 just rolled a  1 [ace],     and the inning is a bust.

███████████████████████████████████████████████████████████████████████████████
The score for  HAL   is  39.
The score for  R2D2  is  12.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL,  your total score (so far) in this pig game is:  39.
HAL just rolled a  2 [deuce],   and the inning total is:  2
HAL just rolled a  2 [deuce],   and the inning total is:  4
HAL just rolled a  3 [trey],    and the inning total is:  7
 and HAL elected to stop rolling.




═══════════════════════════════════HAL won! ═══════════════════════════════════

[edit] Ruby

Features:

  • arbitrary number of players, max score, and die sides
  • players with names
  • transparent game logic
class PigGame
Player = Struct.new(:name, :safescore, :score) do
def bust!() self.score = safescore end
def stay!() self.safescore = score end
def roll!(die_sides) rand(1..die_sides) end
def wants_to_roll?
print("#{name} (#{safescore}, #{score})", ": Roll? (Y) ")
['Y','y',''].include?(gets.chomp)
end
end
 
def bust?(roll) roll==1 ? (puts("Busted!",'') || true) : false end
 
def play(names, maxscore=100, die_sides=6)
rotation = names.map {|name| Player.new(name,0,0) }.cycle
 
while player = rotation.next
loop do
if player.wants_to_roll?
puts "Rolled: #{roll=player.roll!(die_sides)}"
if bust?( roll )
player.bust! && break
else
player.score += roll
return player if player.score >= maxscore
end
else
player.stay! && puts("Staying with #{player.safescore}!", '')
break
end
end
end
end
end
 
print PigGame.new.play( %w|Samuel Elizabeth| ).name, " wins!"
Samples from a game
Samuel (0, 0): Roll? (Y) 
Rolled: 2
Samuel (0, 2): Roll? (Y) 
Rolled: 4
Samuel (0, 6): Roll? (Y) 
Rolled: 1
Busted!

Elizabeth (0, 0): Roll? (Y) 
Rolled: 3
Elizabeth (0, 3): Roll? (Y) 
Rolled: 5
Elizabeth (0, 8): Roll? (Y) 
Rolled: 2
Elizabeth (0, 10): Roll? (Y) n
Staying with 10!

Samuel (0, 0): Roll? (Y) 
Rolled: 4
Samuel (0, 4): Roll? (Y) 
Rolled: 1
Busted!

Elizabeth (10, 10): Roll? (Y) 
Rolled: 2
Elizabeth (10, 12): Roll? (Y) 
Rolled: 6
Elizabeth (10, 18): Roll? (Y) n
Staying with 18!
...
Elizabeth (83, 97): Roll? (Y) 
Rolled: 5
Elizabeth wins!

[edit] Run BASIC

numPlayers	= 2
maxScore = 100
dim safeScore(numPlayers)
 
[loop]
for player = 1 to numPlayers
score = 0
 
while safeScore(player) < maxScore
input "Player ";player;" Rolling? (Y) ";rolling$
if upper$(rolling$) = "Y" then
rolled = int(rnd(0) * 5) + 1
print "Player ";player;" rolled ";rolled
if rolled = 1 then
print "Bust! you lose player ";player;" but still keep your previous score of ";safeScore(plater)
exit while
end if
score = score + rolled
else
safeScore(player) = safeScore(player) + score
end if
wend
next player
goto [loop]
[winner]
print "Player ";plater;" wins with a score of ";safeScore(player)

[edit] Tcl

Works with: Tcl version 8.6
or alternatively with Tcl 8.5 and
Library: TclOO
package require TclOO
 
oo::class create Player {
variable me
constructor {name} {
set me $name
}
method name {} {
return $me
}
 
method wantToRoll {safeScore roundScore} {}
method stuck {score} {}
method busted {score} {}
method won {score} {}
 
method rolled {who what} {
if {$who ne [self]} {
#puts "[$who name] rolled a $what"
}
}
method turnend {who score} {
if {$who ne [self]} {
puts "End of turn for [$who name] on $score"
}
}
method winner {who score} {
if {$who ne [self]} {
puts "[$who name] is a winner, on $score"
}
}
}
 
proc rollDie {} {
expr {1+int(rand() * 6)}
}
proc rotateList {var} {
upvar 1 $var l
set l [list {*}[lrange $l 1 end] [lindex $l 0]]
}
proc broadcast {players message score} {
set p0 [lindex $players 0]
foreach p $players {
$p $message $p0 $score
}
}
 
proc pig {args} {
set players $args
set scores [lrepeat [llength $args] 0]
while 1 {
set player [lindex $players 0]
set safe [lindex $scores 0]
set s 0
while 1 {
if {$safe + $s >= 100} {
incr safe $s
$player won $safe
broadcast $players winner $safe
return $player
}
if {![$player wantToRoll $safe $s]} {
lset scores 0 [incr safe $s]
$player stuck $safe
break
}
set roll [rollDie]
broadcast $players rolled $roll
if {$roll == 1} {
$player busted $safe
break
}
incr s $roll
}
broadcast $players turnend $safe
rotateList players
rotateList scores
}
}

Demonstrating with human players:

oo::class create HumanPlayer {
variable me
superclass Player
method wantToRoll {safeScore roundScore} {
while 1 {
puts -nonewline "$me (on $safeScore+$roundScore) do you want to roll? (Y/n)"
flush stdout
if {[gets stdin line] < 0} {
# EOF detected
puts ""
exit
}
if {$line eq "" || $line eq "y" || $line eq "Y"} {
return 1
}
if {$line eq "n" || $line eq "N"} {
return 0
}
}
}
method stuck {score} {
puts "$me sticks with score $score"
}
method busted {score} {
puts "Busted! ($me still on score $score)"
}
method won {score} {
puts "$me has won! (Score: $score)"
}
}
 
pig [HumanPlayer new "Alex"] [HumanPlayer new "Bert"]
Sample output:
Alex (on 0+0) do you want to roll? (Y/n)y
Busted! (Alex still on score 0)
End of turn for Alex on 0
Bert (on 0+0) do you want to roll? (Y/n)
Bert (on 0+2) do you want to roll? (Y/n)
Bert (on 0+5) do you want to roll? (Y/n)
Bert (on 0+11) do you want to roll? (Y/n)
Bert (on 0+13) do you want to roll? (Y/n)
Bert (on 0+15) do you want to roll? (Y/n)
Bert (on 0+18) do you want to roll? (Y/n)
Bert (on 0+22) do you want to roll? (Y/n)n
Bert sticks with score 22
End of turn for Bert on 22
...
Bert (on 87+0) do you want to roll? (Y/n)
Bert (on 87+5) do you want to roll? (Y/n)
Bert (on 87+8) do you want to roll? (Y/n)
Bert has won! (Score: 101)
Bert is a winner, on 101

[edit] XPL0

include c:\cxpl\codes;          \intrinsic 'code' declarations
integer Player, Die, Points, Score(2);
[Score(0):= 0; Score(1):= 0; \starting scores for each player
Player:= 1; \second player
repeat Player:= if Player = 1 then 0 else 1; \next player
Points:= 0; \points for current turn
loop [Text(0, "Player "); IntOut(0, Player+1);
Text(0, " is up. Roll or hold (r/h)? ");
OpenI(0); \discard any chars in keyboard buffer (like CR)
if ChIn(0) = ^h then quit \default is 'r' to roll
else [Die:= Ran(6)+1; \roll the die
Text(0, "You get "); IntOut(0, Die); CrLf(0);
if Die = 1 then [Points:= 0; quit];
Points:= Points + Die; \add up points for turn
Text(0, "Total points are "); IntOut(0, Points);
Text(0, " for a tentative score of ");
IntOut(0, Score(Player)+Points); CrLf(0);
];
];
Score(Player):= Score(Player) + Points; \show scores
Text(0, "Player 1 has "); IntOut(0, Score(0));
Text(0, " and player 2 has "); IntOut(0, Score(1)); CrLf(0);
until Score(Player) >= 100;
Text(0, "Player "); IntOut(0, Player+1); Text(0, " WINS!!!");
]

Output:

Player 1 is up. Roll or hold (r/h)? r
You get 5
Total points are 5 for a tentative score of 5
Player 1 is up. Roll or hold (r/h)? r
You get 6
Total points are 11 for a tentative score of 11
Player 1 is up. Roll or hold (r/h)? r
You get 6
Total points are 17 for a tentative score of 17
Player 1 is up. Roll or hold (r/h)? r
You get 6
Total points are 23 for a tentative score of 23
Player 1 is up. Roll or hold (r/h)? h
Player 1 has 23 and player 2 has 0
Player 2 is up. Roll or hold (r/h)? r
You get 2
Total points are 2 for a tentative score of 2
Player 2 is up. Roll or hold (r/h)? r
You get 6
Total points are 8 for a tentative score of 8
Player 2 is up. Roll or hold (r/h)? r
You get 1
Player 1 has 23 and player 2 has 0
...
Player 1 has 94 and player 2 has 57
Player 1 is up. Roll or hold (r/h)? r
You get 6
Total points are 6 for a tentative score of 100
Player 1 is up. Roll or hold (r/h)? h
Player 1 has 100 and player 2 has 57
Player 1 WINS!!!
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox