Skip to content

ENOWARS 2024 Scoring Formula

Scoring formula for Enowars 8 organized by ENOFLAG.

Summary

The total score of each team is calculated from offense, defense and sla components of every team for each of their services and rounds played.

The checker returns one of three results for each service: up, recovering and down. A service is considered recovering if SLA checks both suceeded and failed for one round (each) in the recovery period.

The following python pseudo-code captures the team score calculation:1

SLA = 100.0
ATTACK = 1000.0
DEF = -50.0

def sla(rnd, team, service):
    if checker_status(rnd, team, service) == 'ok':
        return SLA
    if checker_status(rnd, team, service) == 'recovering':
        return 0.5 * SLA
    else:
        return 0.0

def attack(rnd, team, service):
    attack = 0.0
    for captured_flag in captured_flags(rnd, team, service):
        attack += ATTACK / total_captures_of(captured_flag) \
                         / service.flagstores / len(services)
    return attack

def def(rnd, team, service):
    defense = 0.0
    for flag in flags_owned_by(rnd, team, service):
        if flag.lost:
            defense += DEF / service.flagstores / len(services)
    return defense

def round_score(rnd, team):
    score = 0
    for service in services:
        score += attack(rnd, team) + defense(rnd, team) + def(rnd, team)
    return score

def scores():
    return {rnd: {team: score(rnd, team} for team in teams} for rnd in rounds}

Review

  • Only small differences to FaustCTF 2024 and SaarCTF 2024, inherits most of the same strengths (simple, easy to implement) and weaknesses (score recalculation). scoring formulas
  • Flag value is scaled via the number of flag stores of each service, not the total number of flagstores, thereby violating Tenet 8

  1. We've removed the per-service weights applied to attack, defense and SLA points from the formula, since historically they we're rarely changed and typically set to 1.