using Nonemm.Core; namespace Nonemm.Contests.Rules; /// The JARL All Asian DX contest. Only contacts with Asia count for a station /// outside it. The exchange is the operator's age, the points go by band, and /// each prefix worked counts once per band. An Asian station scores three /// times what a station outside Asia scores for the same contact. public sealed class AllAsian : Contest { private readonly ModeCategory mode; public AllAsian(ModeCategory mode) => this.mode = mode; public string Name => mode == ModeCategory.Cw ? "ALLASIACW" : "ALLASIASSB"; public string DisplayName => $"All Asian DX {ModeLabel()}"; public string CabrilloName => mode == ModeCategory.Cw ? "AADX-CW" : "AADX-SSB"; public IReadOnlyList ExchangeFieldsFor(StationInfo me) => [ new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false), new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), new ExchangeField("Age", ExchangeSlot.Exchange1, ExchangeFieldKind.Number) { Width = 3 }, ]; public IReadOnlyList MultiplierNames => ["Prefixes"]; public DupeScope DupeScope => DupeScope.PerBand; public bool HasSerialNumbers => false; public IReadOnlyList Modes => [mode]; public string SentExchangeFor(StationInfo me) => ""; public int PointsFor(QsoContext qso) { if (!IsWorkable(qso)) { return 0; } return PointsOn(qso.Band) * (qso.Me.Continent == "AS" ? 3 : 1); } 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(entry.SentExchange, 3), ], [ new CabrilloField(qso.Call.Text, 13), new CabrilloField(qso.ReceivedReport, 3), new CabrilloField(qso.Exchange1, 3), ]); /// One side of every contact has to be in Asia. public bool IsWorkable(QsoContext qso) => qso.Continent == "AS" || qso.Me.Continent == "AS"; /// 160 metres is worth 3, 80 and 10 metres 2, and every other band 1. private static int PointsOn(Band? band) => band?.Name switch { "160M" => 3, "80M" or "10M" => 2, null => 0, _ => 1, }; private string ModeLabel() => mode == ModeCategory.Cw ? "CW" : "SSB"; }