using Nonemm.Core; namespace Nonemm.Contests.Rules; /// IARU HF World Championship. The exchange is an ITU zone or, for a society /// headquarters station, its abbreviation; both count as multipliers per band. /// /// The received zone or abbreviation goes in the section column, which is where /// N1MM keeps it. public sealed class IaruHf : Contest { public string Name => "IARU"; public string DisplayName => "IARU HF World Championship"; public string CabrilloName => "IARU-HF"; public IReadOnlyList ExchangeFieldsFor(StationInfo me) => [ new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false), new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), new ExchangeField("ITU-Zone", ExchangeSlot.Section, ExchangeFieldKind.Text) { Width = 6 }, ]; public IReadOnlyList MultiplierNamesFor(StationInfo me) => ["Zones", "HQ"]; public bool UsesItuZones => true; public DupeScope DupeScope => DupeScope.PerBandAndMode; public bool HasSerialNumbers => false; public IReadOnlyList Modes => [ModeCategory.Cw, ModeCategory.Phone]; public string SentExchangeFor(StationInfo me) => me.ItuZone.ToString(); public int PointsFor(QsoContext qso) { string exchange = Exchange(qso); if (!IsZone(exchange)) { return 1; } if (int.TryParse(exchange, out int zone) && zone == qso.Me.ItuZone) { return 1; } return qso.IsSameContinent ? 3 : 5; } public IReadOnlyList MultipliersFor(QsoContext qso) { string exchange = Exchange(qso); if (exchange.Length == 0) { return []; } string band = qso.Band?.Name ?? ""; return [new Multiplier(IsZone(exchange) ? 1 : 2, exchange, band)]; } public int TotalScore(ScoreTally tally, ContestEntry entry) => tally.Points * tally.TotalMultipliers; public CabrilloExchange CabrilloExchange(Qso qso, StationInfo me, ContestEntry entry) => new( [ new CabrilloField(me.Callsign, 13), new CabrilloField(qso.SentReport, 3), new CabrilloField(me.ItuZone.ToString(), 6), ], [ new CabrilloField(qso.Call.Text, 13), new CabrilloField(qso.ReceivedReport, 3), new CabrilloField(qso.Section, 6), ]); private static string Exchange(QsoContext qso) => qso.Qso.Section.Trim().ToUpperInvariant(); private static bool IsZone(string exchange) => exchange.Length > 0 && exchange.All(char.IsAsciiDigit); }