using Nonemm.Contests.Multipliers; using Nonemm.Core; using Nonemm.Core.Country; namespace Nonemm.Contests.Rules; /// The ARRL 10 metre contest. A CW contact is 4 points and a phone contact 2. /// US, Canadian and Mexican stations send a state or province, everyone else a /// serial number, and both the states and the countries are multipliers, each /// counted once per mode: the contest is one band, and CW and phone count /// separately. public sealed class Arrl10Metre : Contest { public string Name => "ARRL10M"; public string DisplayName => "ARRL 10 Metre Contest"; public string CabrilloName => "ARRL-10"; /// One box takes the state, province or serial number the other station /// sends, as N1MM has it. The sent serial box is there only where this /// station sends a number rather than a state. public IReadOnlyList ExchangeFieldsFor(StationInfo me) => SendsState(me.CountryPrefix) ? [ new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false), new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), new ExchangeField("Exch", ExchangeSlot.Exchange1, ExchangeFieldKind.Text) { Width = 6 }, ] : [ new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false), new ExchangeField("SentNR", ExchangeSlot.SentNumber, ExchangeFieldKind.Number, IsRequired: false), new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), new ExchangeField("Exch", ExchangeSlot.Exchange1, ExchangeFieldKind.Text) { Width = 6 }, ]; /// A number is a serial and anything else is a state or province. public Qso FromExchange1(Qso qso, string typed) => int.TryParse(typed, out int number) ? qso with { ReceivedNumber = number, Section = "" } : qso with { ReceivedNumber = 0, Section = typed.Trim().ToUpperInvariant() }; public IReadOnlyList MultiplierNames => ["States", "Countries"]; public DupeScope DupeScope => DupeScope.PerMode; public bool HasSerialNumbers => true; public IReadOnlyList Modes => [ModeCategory.Cw, ModeCategory.Phone]; public string SentExchangeFor(StationInfo me) => SendsState(me.CountryPrefix) ? me.State.Length > 0 ? me.State : me.Province : "001"; /// What went out on this contact. A US or Canadian station sends the same /// state or province every time; everyone else sends a serial, and ARRL /// asks for the serial of that contact, so the Cabrillo file reads the /// contact's own number and not the first one. N1MM sends it unpadded. private string SentExchangeOn(Qso qso, StationInfo me) => SendsState(me.CountryPrefix) ? SentExchangeFor(me) : $"{qso.SentNumber}"; public int PointsFor(QsoContext qso) => qso.ModeCategory == ModeCategory.Cw ? 4 : 2; public IReadOnlyList MultipliersFor(QsoContext qso) { string mode = qso.ModeCategory.ToString(); string area = StatesAndProvinces.ArrlDxArea(qso.Qso.Section); if (StatesAndProvinces.ArrlDxMultipliers.Contains(area)) { return [new Multiplier(1, area, mode)]; } return qso.CountryPrefix.Length == 0 ? [] : [new Multiplier(2, qso.CountryPrefix, mode)]; } 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(SentExchangeOn(qso, me), 6), ], [ new CabrilloField(qso.Call.Text, 13), new CabrilloField(qso.ReceivedReport, 3), new CabrilloField(qso.Section.Length > 0 ? qso.Section : qso.Exchange1, 6), ]); /// The states and provinces of the US, Canada and Mexico are the exchange; /// the rest of the world sends a number. private static bool SendsState(string countryPrefix) => countryPrefix is "K" or "VE" or "XE"; }