[Back to MISC SWAG index]  [Back to Main SWAG index]  [Original]


unit Dices;
(*
  Handy if you need to throw dices.
  Can only handle the basic notation "AdB+C"


  If you have any improvement ideas, or you use this unit in
  your programs, send me email. 
  
  Feel free to do whatever you wish with this.

            pkalli@cs.joensuu.fi
*)

interface

type
     Dicenum = integer; {could be longint}
     Dice = object
                  private
                  times,
                  sides,
                  bonus:Dicenum;  (*AdB+C*)

                  public
                  procedure Init(tim,sid,bon:Dicenum);
                  procedure InitRange(minimum,maximum:Dicenum);
                  function  Throw:longint;
                  function  Dice2Str:string;
                  function  Str2Dice(st:string):boolean;
                  function  Min:longint;
                  function  Max:longint;
            end;


implementation

const
     plussign  = '+';
     minussign = '-';
     Dicesign  = 'd';
     Dicesign2 = 'D';

procedure Dice.Init(tim,sid,bon:Dicenum);
(*Sets Dice values*)
begin
     times:=tim;
     sides:=sid;
     bonus:=bon;
end; (*Dice.Init*)

procedure Dice.InitRange(minimum,maximum:Dicenum);
(*Sets Dice range. 
  Ugh! What code. But it seems to work, so...*)
var tmp:Dicenum;
    tmp2:Dicenum;
begin
     times:=0;
     sides:=0;
     bonus:=0;
     if minimum>maximum then begin
        tmp:=minimum;
        minimum:=maximum;
        maximum:=tmp;
     end;
     tmp:=0;
     tmp2:=0;
     if minimum=maximum then begin
        bonus:=minimum;
     end else begin
         if minimum=0 then begin
            inc(minimum);
            inc(maximum);
            inc(tmp2);
         end else
         if minimum<1 then begin
            inc(tmp2,abs(minimum*2));
            inc(minimum,tmp2);
            inc(maximum,tmp2);
         end;
         while ((maximum mod minimum)<>0) and (minimum>1) do begin
              dec(minimum);
              dec(maximum);
              inc(tmp);
         end;
         if (maximum mod minimum)=0 then begin
               bonus:=(maximum mod minimum)+tmp-tmp2;
               sides:= maximum div minimum;
               times:= minimum;
         end else begin
             writeln('koe!');
                bonus:=minimum-1-tmp-tmp2;
                sides:=maximum-minimum+1;
                times:=1;
         end;
     end;
end; (*Dice.InitRange*)

function Dice.Throw:longint;
(*Throws the Dices*)
var x:longint;
    tmp:dicenum;
begin
     x:=0;
     tmp:=times;
     while (tmp>0) do begin
        inc(x,Random(sides)+1);
        dec(tmp);
     end;
     inc(x,bonus);
     if x<0 then x:=0;
     Throw:=x;
end; (*Dice.Throw*)

function Dice.Dice2Str:string;
(*Converts Dice to String*)
var st,t:string;
begin
     st:='';
     if (times>0) then begin
        str(times,t);
        st:=st+t+Dicesign;
        str(sides,t);
        st:=st+t;
        if bonus>0 then st:=st+plussign;
     end;
     if (bonus<>0) then begin
        str(bonus,t);
        st:=st+t;
     end else if (sides=0) and (times=0) then st:='0';
     Dice2Str:=st;
end; (*Dice.Dice2Str*)

function Dice.Str2Dice(st:string):boolean;
(*Converts String to Dice.
  Returns true if there occurred any errors, false otherwise*)
const sign:char = '+';
var errcode,errcount:integer;
    dsign:char;
begin
     sides:=0;
     times:=0;
     bonus:=0;
     errcount:=0;
     if pos(Dicesign,st)>0 then dsign:=Dicesign else dsign:=Dicesign2;
     if (pos(Dsign,st)>0) then begin
        Val(copy(st,1,pos(dsign,st)-1),times,errcode);
        if errcode<>0 then times:=1;
        if (pos(minussign,st)>0) then sign:=st[pos(minussign,st)];
        if (pos(sign,st)>0) then begin

Val(copy(st,pos(dsign,st)+1,pos(sign,st)-pos(dsign,st)-1),sides,errcode);
           inc(errcount,errcode);
           Val(copy(st,pos(sign,st),length(st)),bonus,errcode);
           inc(errcount,errcode);
        end else begin
            Val(copy(st,pos(dsign,st)+1,length(st)),sides,errcode);
        end;
     end else begin
         val(st,bonus,errcode);
         inc(errcount,errcode);
     end;
     Str2Dice:=(errcount<>0);
end; (*Dice.Str2Dice*)

function Dice.Min:longint;
(*Returns the min. number dice can give*)
begin
     Min:=bonus+times;
end; (*Dice.Min*)

function Dice.Max:longint;
(*Returns the max. number dice can give*)
begin
     Max:=bonus+(times*sides);
end; (*Dice.Max*)

begin
     Randomize;
end.


[Back to MISC SWAG index]  [Back to Main SWAG index]  [Original]