{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 ****************************************************}