using Nonemm.Core; namespace Nonemm.Contests.Rules; /// The Oceania DX contest, CW and phone. Only contacts with Oceania count for /// a station outside it, and they are worth more the lower the band: 20 points /// on 160 metres, 10 on 80, 5 on 40 and 1 on the higher bands. Each prefix /// worked counts once per band. public sealed class OceaniaDx : Contest { private readonly ModeCategory mode; public OceaniaDx(ModeCategory mode) => this.mode = mode; public string Name => mode == ModeCategory.Cw ? "OceaniaCW" : "OceaniaSSB"; public string DisplayName => $"Oceania DX {ModeLabel()}"; public string CabrilloName => mode == ModeCategory.Cw ? "Oceania-DX-CW" : "Oceania-DX-SSB"; public IReadOnlyList ExchangeFieldsFor(StationInfo me) => [ new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false), new ExchangeField("SntNR", ExchangeSlot.SentNumber, ExchangeFieldKind.Number, IsRequired: false), new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), new ExchangeField("RcvNR", ExchangeSlot.SerialNumber, ExchangeFieldKind.Number), ]; public IReadOnlyList MultiplierNamesFor(StationInfo me) => ["Prefixes"]; public DupeScope DupeScope => DupeScope.PerBand; public bool HasSerialNumbers => true; public IReadOnlyList Modes => [mode]; public string SentExchangeFor(StationInfo me) => "001"; public int PointsFor(QsoContext qso) => IsWorkable(qso) ? PointsOn(qso.Band) : 0; public IReadOnlyList MultipliersFor(QsoContext qso) => IsWorkable(qso) && qso.Qso.Call.WpxPrefix() is { } prefix ? [new Multiplier(1, prefix, qso.Band?.Name ?? "")] : []; 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($"{qso.SentNumber:000}", 4), ], [ new CabrilloField(qso.Call.Text, 13), new CabrilloField(qso.ReceivedReport, 3), new CabrilloField($"{qso.ReceivedNumber:000}", 4), ]); /// One side of every contact has to be in Oceania. public bool IsWorkable(QsoContext qso) => qso.Continent == "OC" || qso.Me.Continent == "OC"; /// What a contact is worth on each of the contest's six bands. The high /// bands pay more than 20 metres, which is the other way round from most /// contests: from Oceania they are the hard ones. A band that is not in /// this table is not in the contest — the WARC bands and 6 metres — and /// scores nothing, which is how N1MM's `COceania.ComputePoints` ends as /// well. private static int PointsOn(Band? band) => band?.Name switch { "160M" => 20, "80M" => 10, "40M" => 5, "20M" => 1, "15M" => 2, "10M" => 3, _ => 0, }; private string ModeLabel() => mode == ModeCategory.Cw ? "CW" : "SSB"; }