Pascal Version, Listing




{Start of file BBallP.Pas **************************************************}

{$I-} {do our own i/o error checks}
{$N+} {Uses numeric coprocessor}
{$R+} {index Range checking}
{$DEFINE Debug}
{$UNDEF Debug}

program BBallP; {Baseball probability}

uses
  Printer, Crt; {Turbo Pascal 5.0 interface}

const
  Name    = 'BBallP - Baseball probability (if each game is a 50-50 chance).';
  Version = 'Pascal Version 2.03, last revised: 1993-09-27, 0600 hours';
  Author  = 'Copyright (c) 1981-1993 by author: Harry J. Smith,';
  Address = '19628 Via Monte Dr., Saratoga CA 95070.  All rights reserved.';

{***************************************************************************}

{Computes the probability that the 1st place team will beat the 2nd place}
{team for the division title, assuming each has a 50-50 chance of winning}
{any given future game. Uses a bivariate binomial distribution as a model.}

{Developed in Turbo Pascal 5.0}

const ESC = Chr( 27);

var
  TN1  : String[10]; {Team's name, 1st place team}
  TN2  : String[10]; {Team's name, 2nd place team}
  GL1  : Integer; {Games Left to play, 1st place team}
  GL2  : Integer; {Games Left to play, 2nd place team}
  GE   : Integer; {Games to play each other}
  GA   : Double;  {Games 1st place team is ahead. 0, 0.5, ...}
  GA2  : Integer; {Twice games ahead = 2 * GA, 0, 1, ...}
  MNT1 : Integer; {Magic Number to tie for 1st place team}
  MNW1 : Integer; {Magic Number to win for 1st place team}
  MNT2 : Integer; {Magic Number to tie for 2nd place team}
  MNW2 : Integer; {Magic Number to win for 2nd place team}
  P    : Double;  {Probability that 1st place team beats 2nd place team}
  Q    : Double;  {Probability that 2nd place team beats 1st place team}
  Ch   : Char;

procedure ReadInt( Mess : String; Min, Max, Nom : Integer;
          var I : Integer); forward;  {Read in an integer from keyboard}

procedure ReadReal( Mess : String; Min, Max, Nom : Double;
          var R : Double); forward;  {Read in a Real from keyboard}

{--------------------------------------}
procedure Init; {Initialize program}
begin
  TextBackground( Blue);
  TextColor( Yellow);
  ClrScr;
  WriteLn;
  WriteLn( Name);
  WriteLn( Version);
  WriteLn( Author);
  WriteLn( Address);
  WriteLn;
end; {Init}

{--------------------------------------}
procedure GetCase; {Get data for a case to compute}
var
  I : Integer;
begin
{ Giants, Braves 1993}
  TN1:= 'Braves';  TN2:= 'Giants';
  GL1:=  6;  GL2:=  7;  GE:= 0;  GA:= 1.5; { 1993-09-27, 1 / Q =   4.7175}
  ReadInt('Games Left to play, 1st place team (-2 => Exit, -1 => Test case)',
    -2, 162, -1, I);
  if I = -2  then Halt(0);
  if I >= 0 then begin
    TN1:= '        ';  TN2:= '        ';
    GL1:= I;
    ReadInt('Games Left to play, 2nd place team', 0, 162, GL1, GL2);
    ReadInt('Games to play each other', 0, 24, 0, GE);
    repeat
      ReadReal('Games ahead, 0, 0.5, ...', 0, 162, 0, GA);
    until (Frac( GA + GA) = 0);
  end;
end; {GetCase}

{--------------------------------------}
procedure ExpandCase; {Compute related data}
var
  I : Integer;
begin
  GA2:= Round(2 * GA);
  I:= GL1 + GL2 - GA2;
  if Odd(I) then begin
    WriteLn('Error in data');
    WriteLn('Press any key to continue...');  Ch:= ReadKey;
  end;
  MNT1:= I div 2;           MNW1:= MNT1 + 1;
  MNT2:= GL1 + GL2 - MNT1;  MNW2:= MNT2 + 1;
end; {ExpandCase}

{--------------------------------------}
procedure DisplayCase;
begin
  WriteLn( GL1:8,  ' = Games Left to play, 1st place team (', TN1, ')');
  WriteLn( GL2:8,  ' = Games Left to play, 2nd place team (', TN2, ')');
  WriteLn( GE :8,  ' = Games to play each other');
  WriteLn( GA :8:1,' = Games 1st place team is ahead.  0, 0.5, ...');
  WriteLn( MNT1:8,  ' = Magic Number to tie for 1st place team');
  WriteLn( MNW1:8,  ' = Magic Number to win for 1st place team');
  WriteLn( MNT2:8,  ' = Magic Number to tie for 2nd place team');
  WriteLn( MNW2:8,  ' = Magic Number to win for 2nd place team');
    WriteLn;
end; {DisplayCase}

{--------------------------------------}
procedure ComputeProb; {Compute probability using a bivariate binomial
distribution as a model}
var
  I, J : Integer;
  A, B : Double;
  E : Array[0..24] of Double; {Binomial coefficients, games to play each other}
  S : Array[0..24] of Double; {Running sum of 2 * E[I]}
  F : Array[0..162] of Double; {B. C., games not played with each other}
  G : Array[0..162] of Double; {Sum of 2 * E[I] for 2nd place team win,}
                               {  E[I] for tie}
begin
  A:= GL1 + GL2 - GE - GE; {A = not played with each other games}
  B:= 1.0;
  F[0]:= 1.0;
  for I:= 1 to MNT1 do begin {Compute binomial coefficients}
    F[I]:= F[I - 1] * A / B;
    A:= A - 1.0;
    B:= B + 1.0;
  end;
  A:= GE;
  B:= 1.0;
  E[0]:= 1.0;
  S[0]:= 2.0;
  for I:= 1 to GE do begin {Compute binomial coefficients}
    E[I]:= E[I - 1] * A / B;
    A:= A - 1.0;
    B:= B + 1.0;
    S[I]:= S[I - 1] + 2 * E[I];
  end;
  for I:= 0 to MNT1 do begin {Compute G[I]}
    J:= (MNT1 - I) div 2;
    if J <= GE then begin
      G[I]:= S[J];
      if (J + J) = (MNT1 - I) then  G[I]:= G[I] - E[J]; {Adjust for tie}
    end
    else
      G[I]:= S[GE];
  end;
{$IFDEF Debug}
  DisplayCase;
  for I:= 0 to MNT do begin
    WriteLn('F[', I, '] = ', F[I]:0:0);
  end;
  WriteLn;
  WriteLn('Press any key to continue...');  Ch:= ReadKey;
  WriteLn;
  for I:= 0 to GE do begin
    WriteLn('E[', I, '] = ', E[I]:0:0);
  end;
  WriteLn;
  WriteLn('Press any key to continue...');  Ch:= ReadKey;
  WriteLn;
  for I:= 0 to GE do begin
    WriteLn('S[', I, '] = ', S[I]:0:0);
  end;
  WriteLn;
  WriteLn('Press any key to continue...');  Ch:= ReadKey;
  WriteLn;
  for I:= 0 to MNT do begin
    WriteLn('G[', I, '] = ', G[I]:0:0);
  end;
  WriteLn;
  WriteLn('Press any key to continue...');  Ch:= ReadKey;
  WriteLn;
{$ENDIF}
  Q:= 0.0;
  for I:= 0 to MNT1 do begin {Compute probability that 2nd place team beats}
                             {  1st place team}
    Q:= Q + F[I] * G[I];
  end;
  A:= GL1 + GL2 - GE + 1;
  B:= Exp(A * Ln( 2.0)); {2 ** Flips}
  Q:= Q / B;
  P:= 1.0 - Q;
end; {ComputeProb}

{--------------------------------------}
procedure DisplayProb; {Display probability}
begin
  WriteLn( P:10:4,
             ' = P = Probability that 1st place team beats 2nd place team');
  WriteLn( Q:10:4,
             ' = Q = Probability that 2nd place team beats 1st place team');
  if Q > 0.0 then
    WriteLn(1.0 / Q:10:4, ' = 1 / Q, (Odds = ', P / Q:1:4, ' : 1)');
  WriteLn;
end; {DisplayProb}

{--------------------------------------}
procedure ReadInt( Mess : String; Min, Max, Nom : Integer;
          var I : Integer);   {Read in an integer from keyboard}
var
  St   : String[ 255];
  Stat : Integer;
  LI   : LongInt;
begin
  repeat
    repeat
      WriteLn( Mess);
      Write('  [', Min, ', ', Max, '] (ENTER => ', Nom, '): ');
      ReadLn( St);
    until IOResult = 0;
    Val( St, LI, Stat);
  until ((Stat = 0) and (LI >= Min) and (LI <= Max)) or (Length( St) = 0);
  if Length( St) = 0 then  LI:= Nom;
  I:= LI;
  WriteLn('Input = ', I);
  WriteLn;
end; {ReadInt}

{--------------------------------------}
procedure ReadReal( Mess : String; Min, Max, Nom : Double;
          var R : Double);  {Read in a Real from keyboard}
var
  St : String[ 255];
  Stat : Integer;
begin
  repeat
    repeat
      WriteLn(Mess);
      Write('  [', Min:0:1, ', ', Max:0:1, '] (ENTER => ', Nom:0:1, '): ');
      ReadLn(St);
    until IOResult = 0;
    Val(St, R, Stat);
  until ((Stat = 0) and (R >= Min) and (R <= Max)) or (Length(St) = 0);
  if Length(St) = 0 then  R:= Nom;
  WriteLn('Input = ', R:0:1);
  WriteLn;
end; {ReadReal}

{--------------------------------------}
begin {Main program, BBallP}
  repeat
    Init;
    GetCase;
    ExpandCase;
    ComputeProb;
    Init;
    DisplayCase;
    DisplayProb;
    WriteLn('Press any key to continue... (or ESC to exit)');  Ch:= ReadKey;
  until Ch = ESC;
  Halt(0);
end. {BBallP}

{End of file BBallP.Pas ****************************************************}

Return to Baseball Pennant Race Odds
Return to Harry's Home Page


This page accessed times since October 20, 2004.
Page created by: hjsmithh@sbcglobal.net
Changes last made on Saturday, 14-May-05 12:42:46 PDT

1