How to resolve the algorithm Dice game probabilities step by step in the PL/I programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Dice game probabilities step by step in the PL/I programming language

Table of Contents

Problem Statement

Two players have a set of dice each. The first player has nine dice with four faces each, with numbers one to four. The second player has six normal dice with six faces each, each face has the usual numbers from one to six. They roll their dice and sum the totals of the faces. The player with the highest total wins (it's a draw if the totals are the same). What's the probability of the first player beating the second player? Later the two players use a different set of dice each. Now the first player has five dice with ten faces each, and the second player has six dice with seven faces each. Now what's the probability of the first player beating the second player? This task was adapted from the Project Euler Problem n.205: https://projecteuler.net/problem=205

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Dice game probabilities step by step in the PL/I programming language

Source code in the pl/i programming language

*process source attributes xref;
 dicegame: Proc Options(main);
 Call test(9, 4,6,6);
 Call test(5,10,6,7);
 test: Proc(w1,s1,w2,s2);
 Dcl (w1,s1,w2,s2,x,y) Bin Fixed(31);
 Dcl p1(100)    Dec Float(18) Init((100)0);
 Dcl p2(100)    Dec Float(18) Init((100)0);
 Dcl p2low(100) Dec Float(18) Init((100)0);
 Call pp(w1,s1,p1);
 Call pp(w2,s2,p2);
 Do x=w1 To w1*s1;
   Do y=0 To x-1;
     p2low(x)+=p2(y);
     End;
   End;
 pwin1=0;
 Do x=w1 To w1*s1;
  pwin1+=p1(x)*p2low(x);
  End;
 Put Edit('Player 1 has ',w1,' dice with ',s1,' sides each')
         (Skip,3(a,f(2)));
 Put Edit('Player 2 has ',w2,' dice with ',s2,' sides each')
         (Skip,3(a,f(2)));
 Put Edit('Probability for player 1 to win: ',pwin1)(Skip,a,f(20,18));
 Put Edit('')(Skip,a);
 End;
 pp: Proc(w,s,p);
 /*--------------------------------------------------------------------
 * Compute and assign probabilities to get a sum x
 * when throwing w dice each having s sides (marked from 1 to s)
 *-------------------------------------------------------------------*/
 Dcl (w,s)    Bin Fixed(31);
 Dcl p(100)   Dec Float(18);
 Dcl cnt(100) Bin Fixed(31);
 Dcl (a(12),e(12),v(12),sum,i,n) Bin Fixed(31);
 a=0;
 e=0;
 Do i=1 To w;
   a(i)=1;
   e(i)=s;
   End;
 n=0;
 cnt=0;
 Do v(1)=a(1) To e(1);
   Do v(2)=a(2) To e(2);
     Do v(3)=a(3) To e(3);
       Do v(4)=a(4) To e(4);
         Do v(5)=a(5) To e(5);
           Do v(6)=a(6) To e(6);
             Do v(7)=a(7) To e(7);
               Do v(8)=a(8) To e(8);
                 Do v(9)=a(9) To e(9);
                   Do v(10)=a(10) To e(10);
                     sum=0;
                     Do i=1 To 10;
                       sum=sum+v(i);
                       End;
                     cnt(sum)+=1;
                     n+=1;
                     End;
                   End;
                 End;
               End;
             End;
           End;
         End;
       End;
     End;
   End;
 Do k=w To w*s;
   p(k)=divide(cnt(k),n,18,16);
   End;
 End;
 End;

*process source attributes xref;
 dgf: Proc Options(main);
 Call test(9, 4,6,6);
 Call test(5,10,6,7);
 test: Proc(w1,s1,w2,s2);
 Dcl (w1,s1,w2,s2,x,y) Dec Float(18);
 Dcl 1 p1(100),
      2 nom      Dec Float(18) Init((100)0),
      2 denom    Dec Float(18) Init((100)1);
 Dcl 1 p2(100),
      2 nom      Dec Float(18) Init((100)0),
      2 denom    Dec Float(18) Init((100)1);
 Dcl 1 p2low(100),
      2 nom      Dec Float(18) Init((100)0),
      2 denom    Dec Float(18) Init((100)1);
 Dcl 1 pwin1,
      2 nom      Dec Float(18) Init(0),
      2 denom    Dec Float(18) Init(1);
 Dcl 1 prod Like pwin1;
 Call pp(w1,s1,p1);
 Call pp(w2,s2,p2);
 Do x=w1 To w1*s1;
   Do y=0 To x-1;
     Call fr_add(p2low(x),p2(y),p2low(x));
     End;
   End;
 Do x=w1 To w1*s1;
  Call fr_mult(p1(x),p2low(x),prod);
  Call fr_add(pwin1,prod,pwin1);
  End;
 Put Edit('Player 1 has ',w1,' dice with ',s1,' sides each')
         (Skip,3(a,f(2)));
 Put Edit('Player 2 has ',w2,' dice with ',s2,' sides each')
         (Skip,3(a,f(2)));
 Put Edit('Probability for player 1 to win: ',
          str(pwin1.nom),'/',str(pwin1.denom))(Skip,4(a));
 Put Edit('                              -> ',
          pwin1.nom/pwin1.denom)(Skip,a,f(20,18));
 Put Edit('')(Skip,a);
 End;

 pp: Proc(w,s,p);
 /*--------------------------------------------------------------------
 * Compute and assign probabilities to get a sum x
 * when throwing w dice each having s sides (marked from 1 to s)
 *-------------------------------------------------------------------*/
 Dcl (w,s)    Dec Float(18);
 Dcl 1 p(100),
      2 nom   Dec Float(18),
      2 denom Dec Float(18);
 Dcl cnt(100) Dec Float(18);
 Dcl (a(12),e(12),v(12),sum,i,n) Dec Float(18);
 a=0;
 e=0;
 Do i=1 To w;
   a(i)=1;
   e(i)=s;
   End;
 n=0;
 cnt=0;
 Do v(1)=a(1) To e(1);
   Do v(2)=a(2) To e(2);
     Do v(3)=a(3) To e(3);
       Do v(4)=a(4) To e(4);
         Do v(5)=a(5) To e(5);
           Do v(6)=a(6) To e(6);
             Do v(7)=a(7) To e(7);
               Do v(8)=a(8) To e(8);
                 Do v(9)=a(9) To e(9);
                   Do v(10)=a(10) To e(10);
                     sum=0;
                     Do i=1 To 10;
                       sum=sum+v(i);
                       End;
                     cnt(sum)+=1;
                     n+=1;
                     End;
                   End;
                 End;
               End;
             End;
           End;
         End;
       End;
     End;
   End;
 Do k=w To w*s;
   p(k).nom=cnt(k);
   p(k).denom=n;
   End;
 End;

 fr_add: Proc(a,b,res);
 Dcl 1 a,
      2 nom   Dec Float(18),
      2 denom Dec Float(18);
 Dcl 1 b Like a;
 Dcl res like a;
 /* Put Edit('fr_add',a.nom,a.denom,b.nom,b.denom)(Skip,a,4(f(15))); */
 res.nom=a.nom*b.denom+b.nom*a.denom;
 res.denom=a.denom*b.denom;
 Call fr_cancel(res,res);
 End;

 fr_mult: Proc(a,b,res);
 Dcl 1 a,
      2 nom   Dec Float(18),
      2 denom Dec Float(18);
 Dcl 1 b Like a;
 Dcl res like a;
 /* Put Edit('fr_mult',a.nom,a.denom,b.nom,b.denom)(Skip,a,4(f(15)));*/
 res.nom=a.nom*b.nom;
 res.denom=a.denom*b.denom;
 Call fr_cancel(res,res);
 End;

 fr_cancel: Proc(a,res);
 Dcl 1 a,
      2 nom   Dec Float(18),
      2 denom Dec Float(18);
 Dcl k Dec Float(18);
 Dcl 1 res like a;
 /* Put Edit('fr_cancel',a.nom,a.denom)(Skip,a,4(f(15)));            */
 k=ggt(a.nom,a.denom);
 res=a/k;
 End;

 ggt: Proc(a,b) Recursive Returns(Dec Float(18));
 /**********************************************************************
 * ggt (gcd) Greatest common Divisor
 * Recursive Proc(a,b)) as shown in PL/I
 **********************************************************************/
 Dcl (a,b) Dec Float(18);
 if b = 0 then return (abs(a));
 return (ggt(b,mod(a,b)));
 End;

 str: Proc(x) Returns(Char(20) Var);
 Dcl x Dec Float(18);
 Dcl res Char(20) Var;
 Put String(res) Edit(x)(f(20));
 Return (trim(res));
 End;

 End;

  

You may also check:How to resolve the algorithm Palindrome detection step by step in the min programming language
You may also check:How to resolve the algorithm Loops/Do-while step by step in the AWK programming language
You may also check:How to resolve the algorithm Phrase reversals step by step in the ALGOL 68 programming language
You may also check:How to resolve the algorithm Disarium numbers step by step in the dc programming language
You may also check:How to resolve the algorithm Empty program step by step in the Kotlin programming language