Resultatmoduler

Uppdaterad: 2015-01-17

En resultatmodul kan användas om du vill räkna ut resultatet enligt speciella regler, t.ex. Det är främst fantasin som sätter begränsningen.

En resultatmodul består av ett antal resultatregler skriva i MRL (MeOS Result Language). Du skapar och ändrar resultatmoduler på sidan Listor genom funktionen Resultatmoduler.

Sedan måste du skapa en lista som pekar ut listmodulen i inställningen Resultatuträkning under listegenskaper. Ofta vill du också sortera listan i enlighet med resultatuträkningen, och då väljer du Egen sortering i inställningen Global sorteringsordning. Dessutom måste du för varje listpost som ska använda resultat från resultatmodulen (T.ex. deltagares status/placering/tid), markera rutan Data från resultatmodul.

Det sista kravet kan tyckas onödigt, men tillåter dig att skapa en lista baserad på en justerad tid från en egen resultatuträkning, men som också visar den ojusterade/faktiska tiden inom parentes.

Resultatregler

Uppdaterad: 2015-01-17

Det finns två uppsättningar regler i en resultatmodul: en för individuella lopp och en för lag. Syftet med regeluppsättningarna är desamma, men vilka symboler som är tillgängliga skiljer sig förstås mellan deltagare och lag. För en deltagare finns till exempel Course som är deltagarens bana, medan ett lag har RunnerTime som är löptiderna för lagets deltagare.

Det är inte nödvändigt att själv skriva kod för de rutiner där standardreglerna fungerar. Och hanterar man bara individuella lopp, så fyller reglerna för lag förstås ingen funktion.

Statusberäkning

Statusregeln beräknar deltagarens status (Godkänd, diskad osv). Standardmetoden returnerar Status, som är symbolen för deltagarens/lagets status enligt standardreglerna. Rutinen måste returnera någon av symbolerna. Returvärdet måste vara någon av symbolerna: StatusOK, StatusDNS, StatusMP, StatusDNF, StatusDQ, StatusMAX, StatusUnknown, eller StatusNotCompetiting.

Tidsberäkning

Rutinen används för att beräkna tiden, i sekunder, för deltagaren eller laget. Standardmetoden returnerar symbolen Time.

Poängberäkning

Rutinen används för att beräkna en poäng (eller annat tal som kan visas i listan); tolkningen av poängen beror helt på rutinen placeringspoäng.

Placeringspoäng

Detta är den viktigaste rutinen. Den beräknar en intern poäng som används för att sortera deltagarna/lagen och tilldela placering. Lägre poäng innebär högre placering. Lika poäng innebär samma placering. Standardmetoden returnerar Time om deltagaren/laget är godkänd, annars 900000 + Status. Den snabbaste godkända får då lägst placeringspoäng och vinner. Ej godkända får högre poäng än alla godkända.

MRL – MeOS Result Language

Uppdaterad: 2015-01-16

MRL (MeOS Result Language) är MeOS språk för att beskriva resultatuträkning. För att kunna skapa egna resultatuträkningsregler är en viss programmeringskunskap nödvändig. Har du skrivit programsnuttar i Java, PHP, C++, C# eller liknande språk har du troligtvis de förkunskaper som krävs.

Grunder

En MRL-rutin består av en följd av satser som separeras genom semikolon (;). Semikolonet kan uteslutas för den sista satsen i rutinen.

Kommentarer i koden kan ges efter genom att skriva // på en rad, varefter resten av denna rad ignoreras. Exempel:

if (Status != StatusOK)
  return 10000; // Return a number higher than any valid time.
else
  return ComputedTime;

Varje MLR-rutin beräknar och returnerar ett heltal (som tolkas som en tid i sekunder, en poäng eller en löparstatus) utifrån indata (tillgängliga symboler). Det sist beräknade värdet i rutinen blir returvärdet. För att returnera ett specifikt värde används konstruktionen

return <värde>;

som i exemplet ovan.

Symboler

I varje MRL-rutin finns ett antal symboler tillgängliga, t.ex Status, Time och Course, som varje gång rutinen körs innehåller aktuell data för den deltagare eller det lag som behandlas.

Symboler kan vara av skalär typ (ex. Time, som håller deltagarens eller lagets tid), av vektortyp (ex. Course, som innehåller en deltagares bana), eller av matristyp (ex RunnerCourse, som innehåller alla banor för ett lags deltagare.).

Symboler av vektortyp och matristyp indexeras från 0 med hakparenteser: Course[2] innebär den tredje kontrollen, RunnerCourse[2][0] innebär den första kontrollen för den tredje deltagaren i laget.

För att ta reda på en vektors eller matris storlek används syntaxen Course.size() respektive RunnerCourse[2].size(); (Antal kontroller för den tredje deltagaren i laget). Exempel (Beräkning av status för deltagare, sträcktid över 3 minuter medför diskning):

if (Status == StatusOK) {
  for (i = 0; i < SplitTimes.size(); i++) {
    if (SplitTimes[i] > 60*3)
      return StatusDQ; // Disqualified if split time over 3 minutes
  }
}
return Status;

Variabler

Variabler fungerar på liknande sätt som symboler, men du definierar dem själv genom att tilldela ett värde. Alla variabler är heltal eller vektorer av heltal. I exemplet ovan är i en variabel.

En variabel som är en vektor kan konstrueras genom att tilldela den värden för specifika index. Vektorn växer automatiskt för att räcka till och talet 0 fylls i där inget tal angivits. Om du skriver var[3] = 4 (och var inte var hade nåt värde sedan tidigare) blir var en vektor med innehåll [0,0,0,4].

En variabel vektor kan också bildas genom tilldelning av alla värden på en gång. Det händer om du skriver var = <namn> där namn är namnet på en symbol eller variabel som är en vektor självt.

Du kan sortera en vektorvariabel genom att skriva var.sort(). Exempel på funktion som returnerar tiden för den snabbaste lagmedlemmen:

times = RunnerTimes;
times.sort();
return times[0];

Operatorer

MRL innehåller de vanligaste aritmetiska och logiska operatorerna. Logiska operatorer evalueras till 1 om värdet är sant och 0 om värdet är falskt. Vanliga prioritetsregler gäller, använd parenteser vid behov.


Binära aritmetiska operatorer Binära logiska operatorer

En uttryck är sant om det inte är 0. Unära operatorer Operatorerna ++ och -- kommer i två varianter, en före och en efter variabeln. Skillnaden ligger i hur uttrycket själv evalueras. Står operatorn först blir resultatet uttrycket efter förändring, annars blir det uttrycket före förändring.

a = 0;
b = ++a;
c = a++;

Resultatet är att b är 1, c är också 1, och a är 2. Undvik att skriva b = ++a + a++;

Flödeskontroll

if/else satser För att räkna olika beroende på om ett logiskt uttryck är sant eller falskt, används en if/else sats. Konstruktionen är:

if (<uttryck>) {
  //kod som körs om <uttryck> är sant
} else {
  //kod som körs om <uttryck> är falskt
}

Delen med else kan utelämnas, om inga sådan uttryck ska köras. Man kan också välja mellan flera utfall, genom konstruktionen:

if (<uttryck1 >) {
  //kod som körs om <uttryck 1> är sant
} else if(<uttryck 2> {
  //kod som körs om  <uttryck 1> är falskt och <uttryck 2> är sant
} ... {
} else {
  //kod som körs om inget uttryck var sant.
}


for-loopar En for-loop används för att repetera en beräkning ett antal gånger. Konstruktionen är

for (<start>; <villkor>; <uppdatering>) {
  // Kod som körs.
}

Först utförs uttrycket <start>. Sedan körs loopen så länge <villkor> är sant. Efter varje varv i loopen, körs uttrycker <uppdatering>.

Följande exempel returnerar status godkänd om alla deltagare i ett lag är godkända.

for(i = 0; i < RunnerStatus.size(); i++) {
  if (RunnerStatus[i] != StatusOK)
    return RunnerStatus[i];
}
return StatusOK;


while-loopar While-loopar är ett alternativ till for-loopar, som saknar start och uppdatering, loopen körs så länge villkoret är sant. Konstruktionen är enklare:

while<villkor>) {
  // Kod som körs.
}


break Break används inne i en loop för att avbryta körningen, ovsätt villkoret i loopen. Exempel (beräknar en poäng beroende på antalet sträckor i rad man klarat på under 1 minut):

i=0;
while(++i<CardTimes.size()) {
  if (CardTimes[i] - CardTimes[i-1]>60)
    break;
}
return i-i;