Check a .udc section multiplier against the list the file names
MultWindowType names the list N1MM validates a received section against, and every exchange that was not all digits counted as a multiplier here. Four of N1MM's lists are held now -- the ARRL sections, the US states, the Canadian provinces and the 165 OK/OM districts, which came out of N1MM's own exe -- and a file naming one of them counts only the values on it. A file naming any of the hundred-odd others keeps the old rule. The 2023 OK/OM DX log now scores contact for contact as N1MM did. Two contacts in the 2026 log still differ: the district code is stored with a trailing space, which N1MM matches against its list untrimmed, so it counts no multiplier where this counts one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
This commit is contained in:
26
src/Nonemm.Contests/Multipliers/OkOmDistricts.cs
Normal file
26
src/Nonemm.Contests/Multipliers/OkOmDistricts.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
namespace Nonemm.Contests.Multipliers;
|
||||
|
||||
/// The 165 district codes the OK/OM DX contest exchanges. N1MM keeps the same
|
||||
/// list in its admin database under the name `OKOMDX`, which is the name a
|
||||
/// `.udc` file gives in `MultWindowType`.
|
||||
public static class OkOmDistricts
|
||||
{
|
||||
public static readonly IReadOnlySet<string> All = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
"APA", "APB", "APC", "APD", "APE", "APF", "APG", "APH", "API", "APJ", "BBE",
|
||||
"BBN", "BKD", "BKH", "BKO", "BMB", "BME", "BNY", "BPB", "BPV", "BPZ", "BRA",
|
||||
"CBU", "CCK", "CJH", "CPE", "CPI", "CPR", "CST", "CTA", "DCH", "DDO", "DKL",
|
||||
"DKV", "DPJ", "DPM", "DPS", "DRO", "DSO", "DTA", "ECH", "ECL", "EDE", "EJA",
|
||||
"ELI", "ELO", "ELT", "EMO", "ETE", "EUL", "FCR", "FHB", "FHK", "FJI", "FNA",
|
||||
"FPA", "FRK", "FSE", "FSV", "FTR", "FUO", "GBL", "GBM", "GBR", "GBV", "GHO",
|
||||
"GJI", "GKR", "GPR", "GTR", "GUH", "GVY", "GZL", "GZN", "GZS", "HBR", "HFM",
|
||||
"HJE", "HKA", "HNJ", "HOL", "HOP", "HOS", "HPR", "HSU", "HVS", "BAA", "BAB",
|
||||
"BAC", "BAD", "BAE", "MAL", "PEZ", "SEN", "DST", "GAL", "HLO", "PIE", "SEA",
|
||||
"SKA", "TRN", "BAN", "ILA", "MYJ", "NMV", "PAR", "PBY", "PRI", "PUC", "TNC",
|
||||
"KOM", "LVC", "NIT", "NZA", "SAL", "TOP", "ZMO", "BYT", "CAD", "DKU", "KNM",
|
||||
"LMI", "MAR", "NAM", "RUZ", "TTE", "TVR", "ZIL", "BBY", "BRE", "BST", "DET",
|
||||
"KRU", "LUC", "POL", "REV", "RSO", "VKR", "ZAR", "ZIH", "ZVO", "GEL", "KEA",
|
||||
"KEB", "KEC", "KED", "KEO", "MIC", "ROZ", "SNV", "SOB", "TRE", "BAR", "HUM",
|
||||
"KEZ", "LEV", "MED", "POP", "PRE", "SAB", "SLU", "SNI", "STR", "SVI", "VRT",
|
||||
};
|
||||
}
|
||||
21
src/Nonemm.Contests/Multipliers/SectionLists.cs
Normal file
21
src/Nonemm.Contests/Multipliers/SectionLists.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace Nonemm.Contests.Multipliers;
|
||||
|
||||
/// The lists N1MM checks a received section against, by the name a contest's
|
||||
/// `MultWindowType` gives. N1MM holds well over a hundred of them in its admin
|
||||
/// database; the ones here are the lists this program already has, plus the
|
||||
/// OK/OM districts.
|
||||
///
|
||||
/// A name with no list gives null, and the caller then counts whatever the
|
||||
/// operator typed.
|
||||
public static class SectionLists
|
||||
{
|
||||
public static IReadOnlySet<string>? For(string multWindowType) =>
|
||||
multWindowType.Trim().ToUpperInvariant() switch
|
||||
{
|
||||
"SECTION" => ArrlSections.All,
|
||||
"STATE" => StatesAndProvinces.AllStates,
|
||||
"PROVINCE" => StatesAndProvinces.Provinces,
|
||||
"OKOMDX" => OkOmDistricts.All,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Nonemm.Contests.Multipliers;
|
||||
using Nonemm.Core;
|
||||
|
||||
namespace Nonemm.Contests.Udc;
|
||||
@@ -17,6 +18,7 @@ public sealed class UdcMultiplier
|
||||
private readonly IReadOnlyList<string> onlyFor;
|
||||
private readonly IReadOnlyList<string> notFor;
|
||||
private readonly IReadOnlyList<string> onlyForSections;
|
||||
private readonly IReadOnlySet<string>? sections;
|
||||
|
||||
public UdcMultiplier(int index, UdcFile file, UdcMultiplierScope shared)
|
||||
{
|
||||
@@ -32,6 +34,7 @@ public sealed class UdcMultiplier
|
||||
onlyFor = file.List($"CountMultOnlyFor{suffix}");
|
||||
notFor = file.List($"DoNotCountMultOnlyFor{suffix}");
|
||||
onlyForSections = file.List($"CountMultOnlyForSec{suffix}");
|
||||
sections = SectionLists.For(file.Text("MultWindowType"));
|
||||
}
|
||||
|
||||
public bool IsDefined => source.Length > 0;
|
||||
@@ -127,16 +130,24 @@ public sealed class UdcMultiplier
|
||||
|
||||
private static string Upper(string text) => text.Trim().ToUpperInvariant();
|
||||
|
||||
/// A section multiplier ignores a value that is all digits. N1MM checks the
|
||||
/// received exchange against the section list the contest names, and a file
|
||||
/// whose section column also carries the serial numbers the other side of
|
||||
/// the contest sends — OK/OM DX SSB is one — would otherwise count every
|
||||
/// serial number as a multiplier. The section lists themselves are not held
|
||||
/// here.
|
||||
private static string? SectionName(string text)
|
||||
/// A section multiplier counts only a value on the list `MultWindowType`
|
||||
/// names, which is what N1MM checks it against. Without a list — this
|
||||
/// program holds four of N1MM's, and N1MM has over a hundred — anything
|
||||
/// that is not all digits counts, so a file whose section column also
|
||||
/// carries the serial numbers the other side of the contest sends — OK/OM
|
||||
/// DX SSB is one — does not count every serial number as a multiplier.
|
||||
private string? SectionName(string text)
|
||||
{
|
||||
string section = Upper(text);
|
||||
return section.Length > 0 && section.All(char.IsAsciiDigit) ? null : section;
|
||||
if (section.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (sections is not null)
|
||||
{
|
||||
return sections.Contains(section) ? section : null;
|
||||
}
|
||||
return section.All(char.IsAsciiDigit) ? null : section;
|
||||
}
|
||||
|
||||
private static string? LastLetter(string call)
|
||||
|
||||
Reference in New Issue
Block a user