Program Speed_Task_Club; // Version 3.00, Date 23.07.2006 // // Version 3.0 // . Added Hmin instead of H0. Score is now calculated using minimum handicap as opposed to maximum handicap as before // Version 3.01 // . Changed If Pilots[i].takeoff > 0 to If Pilots[i].takeoff >= 0. It is theoretically possible that one takes off at 00:00:00 UTC // . Changed If Pilots[i].start > 0 to If Pilots[i].start >= 0. It is theoretically possible that one starts at 00:00:00 UTC const Dm = 100000; // Minimum Handicapped Distance to validate the Day [meters] var Dt, n1, n2, N, D0, V0, T0, Hmin, Td, Pm, Pdm, Pvm, Pn, F, Day: Double; D, H, Dh, M, T, Dc, Pd, V, Vh, Pv, S : double; PmaxDistance, PmaxTime : double; i : integer; Function MinValue( a,b,c : double ) : double; var m : double; begin m := a; If b < m Then m := b; If c < m Then m := c; MinValue := m; end; begin // Calculation of basic parameters N := 0; // Number of pilots having had a competition launch N1 := 0; // Number of pilots with Marking distance greater than Dm - normally 100km Hmin := 100000; // Lowest Handicap of all competitors in the class Td := 0; // Designated time for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].Hcap < Hmin Then Hmin := Pilots[i].Hcap; // Lowest Handicap of all competitors in the class end; end; If Hmin=0 Then Exit; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].dis*Hmin/Pilots[i].Hcap >= Dm Then n1 := n1+1; // Competitors who have achieved at least Dm If Pilots[i].takeoff >= 0 Then N := N+1; // Number of competitors in the class having had a competition launch that Day If Pilots[i].tstart >= 0 Then Td := Pilots[i].tfinish-Pilots[i].tstart; // Calculate designated time end; end; If N=0 Then Exit; // Outlanding Penalty (Distance reduction) for i:=0 to GetArrayLength(Pilots)-1 do begin if Pilots[i].finish <= 0 Then begin M := 1.0/2.0 * Pilots[i].DisToGoal*Hmin/Pilots[i].Hcap; // Pilots[i].dis := Pilots[i].dis - M; // Uncomment this line if you wish to use the Outlanding Penalty end; end; D0 := 0; T0 := 0; V0 := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin // Find the highest Corrected distance If Pilots[i].dis*Hmin/Pilots[i].Hcap > D0 Then D0 := Pilots[i].dis*Hmin/Pilots[i].Hcap; // Find the highest finisher's speed of the day // and corresponding Task Time If Pilots[i].speed*Hmin/Pilots[i].Hcap = V0 Then // in case of a tie, lowest Task Time applies begin If (Pilots[i].finish-Pilots[i].start) < T0 Then begin V0 := Pilots[i].speed*Hmin/Pilots[i].Hcap; T0 := Pilots[i].finish-Pilots[i].start; end; end Else begin If Pilots[i].speed*Hmin/Pilots[i].Hcap > V0 Then begin V0 := Pilots[i].speed*Hmin/Pilots[i].Hcap; T0 := Pilots[i].finish-Pilots[i].start; If T0 < Td Then // If marking time is shorter than Designated time, Designated time must be used for computations T0 := Td; end; end; end; end; If D0=0 Then Exit; // Maximum available points for the Day PmaxDistance := (5*D0/1000)-250; PmaxTime := (400*T0/3600.0)-200; If T0 <= 0 Then PmaxTime := 1000; Pm := MinValue( PmaxDistance, PmaxTime, 1000.0 ); // Day Factor F := 1.25* n1/N; If F>1 Then F := 1; // Number of competitors who have achieved at least 2/3 of best speed for the day V0 n2 := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].speed*Hmin/Pilots[i].Hcap > (2.0/3.0*V0) Then begin n2 := n2+1; end; end; end; Pvm := 2.0/3.0 * (n2/N) * Pm; // maximum available Speed Points for the Day Pdm := Pm-Pvm; // maximum available Distance Points for the Day for i:=0 to GetArrayLength(Pilots)-1 do begin // For any finisher If Pilots[i].finish > 0 Then begin Pv := Pvm * (Pilots[i].speed*Hmin/Pilots[i].Hcap - 2.0/3.0*V0)/(1.0/3.0*V0); If Pilots[i].speed*Hmin/Pilots[i].Hcap < (2.0/3.0*V0) Then Pv := 0; Pd := Pdm; If Pilots[i].dis*Hmin/Pilots[i].Hcap < (2.0/3.0*D0) Then Pd := Pdm*Pilots[i].dis*Hmin/Pilots[i].Hcap/(2.0/3.0*D0); end Else //For any non-finisher begin Pv := 0; Pd := Pdm * (Pilots[i].dis*Hmin/Pilots[i].Hcap/D0); end; // Pilot's score Pilots[i].Points := Round( F*(Pd+Pv) - Pilots[i].Penalty ); end; // Data which is presented in the score-sheets for i:=0 to GetArrayLength(Pilots)-1 do begin Pilots[i].sstart:=Pilots[i].start; Pilots[i].sfinish:=Pilots[i].finish; Pilots[i].sdis:=Pilots[i].dis; Pilots[i].sspeed:=Pilots[i].speed; end; // Info fields, also presented on the Score Sheets Info1 := 'Maximum Points: '+IntToStr(Round(Pm)); Info2 := 'Day factor = '+FormatFloat('0.000',F); end.