using Nonemm.Core; namespace Nonemm.Contests.Rules; /// The IARU Region 1 Field Day. A portable station is worth 5 points, a station /// in Region 1 operating from home 2, and one outside Region 1 3. The exchange /// is a serial number and the countries are multipliers, once per band. public sealed class FieldDayRegionOne : Contest { public string Name => "FDREG1"; public string DisplayName => "IARU Region 1 Field Day"; public string CabrilloName => "FIELDDAY-REGION-1"; public IReadOnlyList ExchangeFieldsFor(StationInfo me) => [ 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("Nr", ExchangeSlot.SerialNumber, ExchangeFieldKind.Number), ]; public IReadOnlyList MultiplierNamesFor(StationInfo me) => ["Countries"]; public DupeScope DupeScope => DupeScope.PerBandAndMode; public bool HasSerialNumbers => true; public IReadOnlyList Modes => [ModeCategory.Cw, ModeCategory.Phone]; public string SentExchangeFor(StationInfo me) => "001"; public int PointsFor(QsoContext qso) { if (IsPortable(qso.Qso.Call)) { return 5; } return IsRegionOne(qso.Continent) ? 2 : 3; } public IReadOnlyList MultipliersFor(QsoContext qso) => qso.CountryPrefix.Length == 0 ? [] : [new Multiplier(1, qso.CountryPrefix, 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), ]); /// A field day station signs portable, mobile or /A. private static bool IsPortable(Callsign call) => call.Text.EndsWith("/P", StringComparison.OrdinalIgnoreCase) || call.Text.EndsWith("/M", StringComparison.OrdinalIgnoreCase) || call.Text.EndsWith("/A", StringComparison.OrdinalIgnoreCase); /// Region 1 is Europe, Africa and the Middle East. The country file has a /// continent for the first two; the Middle East is inside Asia, which is /// split between regions, and the continent alone does not separate them. private static bool IsRegionOne(string continent) => continent is "EU" or "AF"; }