Program Pontuacao_FBVP_REV_5; // // SCRIPT para uso no SeeYou Competition // // Tradução e revisão para FBVP feita por Valença em outubro de 2018 com base no // Anexo A do FAI Sporting Code Section 3 (FAI SC S3) de 01 de outubro de 2018 // // Este Script serve para Provas RACING e Provas de ÁREA // // ATENÇÃO: para provas racing colocar ZERO no tempo da prova // // NOTA: A versão original deste Script foi obtida no Forum da Nativer em sua versão 3.30 datada de 10.01.2013 // // REV 0 (out-2018) // - atualização das regras do Anexo A do FAI Sporting Code Section 3 (FAI SC S3) de 01 de outubro de 2018 // - tropicalização para a FBVV, distâncias para 1.000 pontos e mínimas para validar o dia por classe: // Classe D1 Dm // --------- ---- ---- // KW-1 200 80 // Clube 250 100 // Racing 300 120 // Open 350 140 // // REV 1 (nov-2018) // - evita emitir a mensagem "ERRO: Tag do Dia não é uma classe válida: KW-1, Clube, Racing, Open, Unica" quando nenhum voo foi lançado ainda // - incluido mensagem para informar que menos de 25% dos voos alcançou a distância mínima (Dm) - Prova não validada // - corrigir a divisão por zero // - reduzir a quantidade de informação divulgada, excluindo a última linha e informando a Dm da Classe // // REV 2 (mai-2019) // - passar a utilizar a nova variável ClassName (Nome da Classe criada no Soaring Spot) para definir a Dm e D1, ao inves do Tag do dia. // // // REV 3 (ago-2020) // - nova regra do Manual FBVP 2020 que estabelce tempo minimo = tempo do voo quando a distância voada é >= 95% da distância máxima da prova. // caso "Tag" do dia tenha o texto "MaxDis xxx.y" onde xxx.y = distância máxima da prova, o script informar o tempo mínimo. É necessário alterar // o tempo da prova e reprocessar, até a mensagem desaparecer // // REV 3a (jan-2023) // - ajuste no nome das classes para ficar igual ao Manual Esportivo da FBVP // // REV 3b (set-2023) // - limpar Info4 // // REV 4 (nov-2023) // - nova regra dos 95%, valido apenas para os pilotos que fez distância > 95% // // REV 5 (out-2025) // // - D1 = 300 e Dm = 120 tendo como base o handicap 100 (Jantar Std) aplicado para todas as classes, inclusive qq unica. // // - Mantida as variáveis das classes originais, inclusive KW1, só por simplificação e fórmulas (não fazer alteração significativa no script, neste // momento). var Dt, n1, n2, n3, n4, N, D0, V0, T0, T0h, T0m, T0s, H0, Td, T95, T95h, T95m, T95s, Pm, Pdm, Pvm, Pn, F, Fcr, Day : Double; D, D1, Dm, D250, H, Dh, M, MaxDis, T, Dc, Pd, V, Vh, Pv : 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; // Cálculo dos parâmetros basicos begin info4 := ''; // Define distância mínima para Fator do Dia (Dm) e Pontuação Máxima (D1) e H0 (Handicap de referência, maior da tabela LIVV, ver comentário Rev 0) Dm := 0; D1 := 0; if Pos('KW-1', Task.ClassName) = 1 Then begin Dm := 120000; // distância mínima (m) para validar o dia - classe KW-1 D1 := 300; // distância mínima (Km) para 1.000 pontos - classe KW-1 H0 := 100 end; if Pos('Clube', Task.ClassName) = 1 Then begin Dm := 120000; // distância mínima (m) para validar o dia - classe Clube D1 := 300; // distância mínima (Km) para 1.000 pontos - classe Clube H0 := 100; end; if Pos('Racing', Task.ClassName) = 1 Then begin Dm := 120000; // distância mínima (m) para validar o dia - classe Racing D1 := 300; // distância mínima (Km) para 1.000 pontos - classe Racing H0 := 100; end; if Pos('Open', Task.ClassName) = 1 Then begin Dm := 120000; // distância mínima (m) para validar o dia - classe Open D1 := 300; // distância mínima (Km) para 1.000 pontos - classe Open H0 := 100; end; if Pos('Unica', Task.ClassName) = 1 Then begin Dm := 120000; // distância mínima (m) para validar o dia - classe Unica, qualquer combinação D1 := 300; // distância mínima (Km) para 1.000 pontos - classe Unica, qualquer combinação H0 := 100; end; If Dm = 0 Then begin Info1 := 'ERRO: Nome da classe deve começar com: KW-1, Clube, Racing, Open ou Unica XXX'; Exit; end; N := 0; n1 := 0; n3 := 0; n4 := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].dis*H0/Pilots[i].Hcap >= Dm Then n1 := n1+1; // Número de pilotos que conseguiram a Dm If Pilots[i].dis*H0/Pilots[i].Hcap >= Dm/2 Then n4 := n4+1; // Número de pilotos que conseguiram a Dm/2 If Pilots[i].takeoff >= 0 Then N := N+1; // Número de pilotos que decolaram no dia If Pilots[i].sfinish <> -1 Then n3 := n3+1; // Número de pilotos que concluiram a prova end; end; If N = 0 Then begin Info1 := 'ATENÇÃO: Nenhum piloto decolou no dia'; Exit; end; If N1 = 0 Then begin Info1 := 'ATENÇÃO: Nenhum voo alcançou a distância mínima corrigida de '+FormatFloat('0',Dm/1000)+'Km - A PROVA NÃO FOI VALIDADA'; Exit; end; Td := Task.TaskTime; D0 := 0; T0 := 0; V0 := 0; // Verifica se algum piloto ultrapassou 95% da Distância Máxima abaixo do tempo mínimo e corrige a velocidade pelo tempo do voo MaxDis := 1000000; If Pos('MaxDis', DayTag) = 1 Then begin Delete(DayTag, 1, 7); MaxDis := StrToFloat(DayTag)*0.95*1000; If MaxDis = 0 then begin Info1 := '*** MaxDis não é um número válido ***'; Exit; end; end; for i:=0 to GetArrayLength(Pilots)-1 do begin If Pilots[i].finish > 0 Then If Pilots[i].dis >= MaxDis Then if (Pilots[i].finish-Pilots[i].start) < Td then begin Pilots[i].speed := Pilots[i].dis / (Pilots[i].finish-Pilots[i].start); Pilots[i].warning := 'Distância > 95% - considerado tempo do voo'; end; end; // Principal for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin // Determinar a maior distância corrigida do dia (após Handicap) If Pilots[i].dis*H0/Pilots[i].Hcap > D0 Then D0 := Pilots[i].dis*H0/Pilots[i].Hcap; // determinar a maior velocidade corrigida do dia (após Handicap) // e o correspondente tempo If Pilots[i].speed*H0/Pilots[i].Hcap = V0 Then // em caso de empate aplicar o menor tempo begin If (Pilots[i].finish-Pilots[i].start) < T0 Then begin V0 := Pilots[i].speed*H0/Pilots[i].Hcap; T0 := Pilots[i].finish-Pilots[i].start; end end Else begin If Pilots[i].speed*H0/Pilots[i].Hcap > V0 Then begin V0 := Pilots[i].speed*H0/Pilots[i].Hcap; T0 := Pilots[i].finish-Pilots[i].start; If T0 < Td Then T0 := Td; // Se T0 menor que o tempo mínimo da prova, usar o tempo mínimo end; end; end; end; If D0=0 Then begin Info1 := 'ATENÇÃO: Maior distância é ZERO'; Exit; end; // Número máximo de pontos do dia PmaxDistance := 1250*(D0/1000/D1)-250; PmaxTime := (400.0*T0/3600.0)-200; If T0 <= 0 Then PmaxTime := 1000; Pm := MinValue( PmaxDistance, PmaxTime, 1000.0 ); // Fator do Dia (F) F := 1.25 * n1/N; If F>1 Then F := 1; // Número de pilotos que ultrapassou 2/3 da maior velocidade do dia V0 n2 := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].speed*H0/Pilots[i].Hcap > (2.0/3.0*V0) Then begin n2 := n2+1; end; end; end; // Fator Completion Ratio (Fcr) Fcr := 1.2 * (n2/n1) + 0.6; If Fcr>1 then Fcr := 1; Pvm := 2.0/3.0 * (n2/N) * Pm; // Pontuação máxima por velocidade do dia Pdm := Pm-Pvm; // Pontuação máxima por distância do dia for i:=0 to GetArrayLength(Pilots)-1 do begin // Para quem completou a prova If Pilots[i].finish > 0 Then begin Pv := Pvm * (Pilots[i].speed*H0/Pilots[i].Hcap - 2.0/3.0*V0)/(1.0/3.0*V0); Pd := Pdm; If Pilots[i].speed*H0/Pilots[i].Hcap < (2.0/3.0*V0) Then Pv := 0; end Else // Para quem não completou a prova begin Pv := 0; Pd := Pdm * (Pilots[i].dis*H0/Pilots[i].Hcap/D0); end; // Total de pontos do pilotos Pilots[i].Points := Round( F * Fcr * (Pd+Pv) - Pilots[i].Penalty ); end; // Dados para divulgação dos resultados 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; // Distância Real Pilots[i].user_str1:=FormatFloat('0.0',0.001*Pilots[i].dis*H0/Pilots[i].Hcap); // Distância Corrigida Pilots[i].sspeed:=Pilots[i].speed; // Velocidade Real Pilots[i].user_str2:=FormatFloat('0.0',3.6*Pilots[i].speed*H0/Pilots[i].Hcap); // Velocidade Corrigida end; // Campos adicionais T0h := 0; T0m := 0; T0s := 0; If T0>0 then begin T0h := T0/3600; T0m := (T0h - Trunc(T0h))*60; T0s := (T0m - Trunc(T0m))*60; end; Info1 := 'Pontuação Máxima: '+IntToStr(Round(Pm))+' - '+IntToStr(Round(Pvm))+' por Velocidade e '+IntToStr(Round(Pdm))+' por Distância, D1 = ' +FormatFloat('0',D1)+'Km'; Info2 := 'Vel Corr. Máxima (V0) = '+FormatFloat('0.0',V0*3.6)+' - Dist Corr. Máxima (D0) = '+FormatFloat('0.0',D0*0.001)+' - Melhor tempo (T0) = '+FormatFloat('00',Trunc(T0h))+':'+FormatFloat('00',Trunc(T0m))+':'+FormatFloat('00',T0s); Info3 := 'Dm = '+FormatFloat('0',Dm/1000)+'Km, Fator do DIA (F) = '+FormatFloat('0.000',F)+' e (Fcr) = '+FormatFloat('0.000',Fcr); If n1/N < 1/4 Then Info4 := '*** ATENÇÃO: Menos de 25% dos voos com distância mínima corrigida de '+FormatFloat('0',Dm/1000)+'Km - A PROVA NÃO FOI VALIDADA ***'; end.