Pig the dice game: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|D}}: corrected indentation)
(→‎{{header|REXX}}: added the REXX language. -- ~~~~)
Line 573: Line 573:


Player 0 wins with a score of 101</pre>
Player 0 wins with a score of 101</pre>

=={{header|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 (as well as the pip value)
<lang rexx>/*REXX program plays pig (the dice game) with at least one human player.*/
parse arg hp cp win die names; sw=80-1 /*the LINESIZE bif would be nicer*/
@nhp = 'number of human players' ; hp = scrutinize( hp, @nhp ,0, 0)
@ncp = 'number of computer players'; cp = scrutinize( cp, @ncp ,0, 0)
@sn2w = 'score needed to win' ; win = scrutinize(win, @sn2w ,1,100)
@nsid = 'number of sides in die' ; die = scrutinize(die, @nsid ,1, 6)
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*/

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.*/
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'
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 duece trey square nickle boxcar' /*die face names.*/
/*note: snake eys is for two aces*/
do i=1 for 6; !.i=' ['word(dieNames,i)"] "; end /*i*/
s.=0 /*set all player's scores to zero*/
@=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=word('You It', 1 + (j>hp)) /*pronoun choice: You or It */
say name.j', your total score (so far) in this pig game is:' s.j"."

do until stopped /*keep prompting/rolling 'til not*/
r=random(1,die); !=space(r !.r) /*for color, use a die-face name.*/
in.j=in.j+r
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,minimum /*? is the number, or maybe not. */
if ?=='' | ?==',' then return arg(4)
if \datatype(?,'N') then call err what "isn't numeric: " ?; ?=?/1
if \datatype(?,'W') then call err what "isn't an integer: " ?
if ?==0 & minimum>0 then call err what "can't be zero."
if ?<minimum then call err what "can't be less than" minimum': ' ?
return ?
/*──────────────────────────────────what2do subroutine──────────────────*/
what2do: parse arg who /*"who" is a human or a computer.*/
if j>hp | r+in.j>=win then return r>4 /*a easy choice for HAL: go|nogo */
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</lang>
'''output''' when using the input of: <tt> 0 2 33 </tt>
<pre style="height:50ex;overflow:scroll">
Pig (the dice game) is being played with
2 computer players
no human players
and the score needed to win is: 33 (or greater).

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is 0.
The score for HAL 2 the computer is 0.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer, your total score (so far) in this pig game is: 0.
It just rolled a 3 [trey], and the inning total is: 3
It just rolled a 5 [nickle], and the inning total is: 8
and HAL 1 the computer elected to stop rolling.

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

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is 8.
The score for HAL 2 the computer is 6.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer, your total score (so far) in this pig game is: 8.
It just rolled a 2 [duece], and the inning total is: 2
It just rolled a 3 [trey], and the inning total is: 5
It just rolled a 3 [trey], and the inning total is: 8
It just rolled a 4 [square], and the inning total is: 12
It just rolled a 5 [nickle], and the inning total is: 17
and HAL 1 the computer elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
HAL 2 the computer, your total score (so far) in this pig game is: 6.
It just rolled a 2 [duece], and the inning total is: 2
It just rolled a 5 [nickle], and the inning total is: 7
and HAL 2 the computer elected to stop rolling.

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is 25.
The score for HAL 2 the computer is 13.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer, your total score (so far) in this pig game is: 25.
It just rolled a 6 [boxcar], and the inning total is: 6
and HAL 1 the computer elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
HAL 2 the computer, your total score (so far) in this pig game is: 13.
It just rolled a 2 [duece], and the inning total is: 2
It just rolled a 1 [ace], and the inning is a bust.

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is 31.
The score for HAL 2 the computer is 13.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer, your total score (so far) in this pig game is: 31.
It just rolled a 6 [boxcar], and the inning total is: 6
and HAL 1 the computer elected to stop rolling.




═══════════════════════════HAL 1 the computer won! ════════════════════════════
</pre>


=={{header|XPL0}}==
=={{header|XPL0}}==

Revision as of 00:46, 16 December 2012

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.

Reference
Cf

Common Lisp

<lang 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)))</lang>
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

D

Translation of: Python

<lang d>import std.stdio, std.string, std.algorithm, std.random;

void main() {

   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]);

}</lang>

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

J

<lang 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'

)</lang>

Example game:

<lang> 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</lang>

Java

Translation of: D

<lang java>import java.util.*;

public class PigDice {

   public static void main(String[] args) {
       final int maxScore = 100;
       final int playerCount = 2;
       int[] safeScore = new int[2];
       int player = 0, score = 0;
       Scanner sc = new Scanner(System.in);
       String[] yesses = {"yes", "y", ""};
       Random rnd = new Random();
       while (true) {
           System.out.printf(" Player %d: (%d, %d) Rolling? (Yn) ", player,
                   safeScore[player], score);
           String ln = sc.nextLine();
           if (Arrays.asList(yesses).contains(ln.trim().toLowerCase())) {
               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("\nPlayer %d wins with a score of %d",
               player, safeScore[player]);
   }

}</lang>

 Player 0: (0, 0) Rolling? (Yn) 
 Rolled 3
 Player 0: (0, 3) Rolling? (Yn) 
 Rolled 5
 Player 0: (0, 8) Rolling? (Yn) 
 Rolled 2
 Player 0: (0, 10) Rolling? (Yn) n
 Sticking with 10

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

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

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

(...)

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

Player 1 wins with a score of 102

Perl 6

Works with: niecza version 2012-09-12

<lang perl6>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;

   }

}</lang> 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!

PHP

Translation of: D

<lang php>error_reporting(E_ALL & ~ ( E_NOTICE | E_WARNING ));

define('MAXSCORE', 100); define('PLAYERCOUNT', 2);

$confirm = array('yes', 'y', );

while (true) {

   printf(' Player %d: (%d, %d) Rolling? (Yn) ', $player,
           $safeScore[$player], $score);
   if ($safeScore[$player] + $score < MAXSCORE &&
           in_array(strtolower(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]);

</lang>

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

Python

<lang 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]))</lang>

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

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 (as well as the pip value)

<lang rexx>/*REXX program plays pig (the dice game) with at least one human player.*/ parse arg hp cp win die names; sw=80-1 /*the LINESIZE bif would be nicer*/ @nhp = 'number of human players'  ; hp = scrutinize( hp, @nhp ,0, 0) @ncp = 'number of computer players'; cp = scrutinize( cp, @ncp ,0, 0) @sn2w = 'score needed to win'  ; win = scrutinize(win, @sn2w ,1,100) @nsid = 'number of sides in die'  ; die = scrutinize(die, @nsid ,1, 6) 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*/

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.*/ 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'

        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 duece trey square nickle boxcar' /*die face names.*/

                                      /*note: snake eys is for two aces*/
               do i=1  for 6;  !.i=' ['word(dieNames,i)"] ";  end   /*i*/

s.=0 /*set all player's scores to zero*/ @=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=word('You It', 1 + (j>hp))     /*pronoun choice:   You  or  It  */
    say name.j',  your total score (so far) in this pig game is:' s.j"."
      do  until stopped               /*keep prompting/rolling 'til not*/
      r=random(1,die); !=space(r !.r) /*for color, use a die-face name.*/
      in.j=in.j+r
      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,minimum /*? is the number, or maybe not. */ if ?== |  ?==',' then return arg(4) if \datatype(?,'N') then call err what "isn't numeric: "  ?;  ?=?/1 if \datatype(?,'W') then call err what "isn't an integer: " ? if ?==0 & minimum>0 then call err what "can't be zero." if ?<minimum then call err what "can't be less than" minimum': ' ? return ? /*──────────────────────────────────what2do subroutine──────────────────*/ what2do: parse arg who /*"who" is a human or a computer.*/ if j>hp | r+in.j>=win then return r>4 /*a easy choice for HAL: go|nogo */ 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</lang> output when using the input of: 0 2 33

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

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is   0.
The score for HAL 2 the computer is   0.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer,  your total score (so far) in this pig game is: 0.
It just rolled a  3 [trey],  and the inning total is: 3
It just rolled a  5 [nickle],  and the inning total is: 8
 and HAL 1 the computer elected to stop rolling.

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

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is   8.
The score for HAL 2 the computer is   6.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer,  your total score (so far) in this pig game is: 8.
It just rolled a  2 [duece],  and the inning total is: 2
It just rolled a  3 [trey],  and the inning total is: 5
It just rolled a  3 [trey],  and the inning total is: 8
It just rolled a  4 [square],  and the inning total is: 12
It just rolled a  5 [nickle],  and the inning total is: 17
 and HAL 1 the computer elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
HAL 2 the computer,  your total score (so far) in this pig game is: 6.
It just rolled a  2 [duece],  and the inning total is: 2
It just rolled a  5 [nickle],  and the inning total is: 7
 and HAL 2 the computer elected to stop rolling.

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is  25.
The score for HAL 2 the computer is  13.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer,  your total score (so far) in this pig game is: 25.
It just rolled a  6 [boxcar],  and the inning total is: 6
 and HAL 1 the computer elected to stop rolling.

───────────────────────────────────────────────────────────────────────────────
HAL 2 the computer,  your total score (so far) in this pig game is: 13.
It just rolled a  2 [duece],  and the inning total is: 2
It just rolled a  1 [ace],  and the inning is a bust.

███████████████████████████████████████████████████████████████████████████████
The score for HAL 1 the computer is  31.
The score for HAL 2 the computer is  13.
███████████████████████████████████████████████████████████████████████████████

───────────────────────────────────────────────────────────────────────────────
HAL 1 the computer,  your total score (so far) in this pig game is: 31.
It just rolled a  6 [boxcar],  and the inning total is: 6
 and HAL 1 the computer elected to stop rolling.




═══════════════════════════HAL 1 the computer won! ════════════════════════════

XPL0

<lang 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!!!"); ]</lang>

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!!!