The three differences left after replaying the log were ours on purpose. A log has to score the same in both programs, so they now follow N1MM: - ARRL DX and CQ WW RTTY count the 14 Canadian areas N1MM lists as `48SDC14P`, which keeps Newfoundland apart from Labrador. A station sending the postal code is counted as the area the contest names. - A maritime mobile is scored from the call it signs. CQ WW says it counts for the zone alone; N1MM gives it the country, and so do we. - A callsign the country file cannot place counts as a multiplier with an empty value, so every unplaceable call worked on a band shares one multiplier. 29 of the 37 contest instances in the log now agree with N1MM on every contact and on the totals. What is left is the country file of the day and rows whose cached points N1MM never worked out again after a call was corrected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RoGtneMQaz4M9w7Kk49AVD
167 lines
5.5 KiB
C#
167 lines
5.5 KiB
C#
using Nonemm.Contests.Rules;
|
|
using Nonemm.Core;
|
|
|
|
namespace Nonemm.Contests.Tests;
|
|
|
|
public class WaeTests
|
|
{
|
|
private static readonly Wae Cw = new(ModeCategory.Cw);
|
|
private static readonly Wae Rtty = new(ModeCategory.Digital);
|
|
|
|
private static ContestLog LogFor(Contest contest, StationInfo me) =>
|
|
new(contest, me, TestLog.CountryFile);
|
|
|
|
private static Qso On(string call, double kilohertz, Mode? mode = null) =>
|
|
TestLog.Contact(call, kilohertz: kilohertz, mode: mode ?? Modes.Cw, exchange: WaeQtc.Contact);
|
|
|
|
[Fact]
|
|
public void EveryContactOnAContestBandIsOnePoint()
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Assert.Equal(1, log.Judge(On("JA1XYZ", 14_025)).Points);
|
|
}
|
|
|
|
/// WAE does not run on the WARC bands.
|
|
[Fact]
|
|
public void AContactOnAWarcBandScoresNothing()
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Assert.Equal(0, log.Judge(On("JA1XYZ", 18_080)).Points);
|
|
}
|
|
|
|
[Fact]
|
|
public void EuropeDoesNotWorkEuropeOnCw()
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Verdict verdict = log.Judge(On("IK2XYZ", 14_025));
|
|
|
|
Assert.Equal(0, verdict.Points);
|
|
Assert.Empty(verdict.NewMultipliers);
|
|
}
|
|
|
|
[Fact]
|
|
public void OnRttyEverybodyWorksEverybody()
|
|
{
|
|
ContestLog log = LogFor(Rtty, TestLog.Germany);
|
|
Verdict verdict = log.Judge(On("IK2XYZ", 14_080, Modes.Rtty));
|
|
|
|
Assert.Equal(1, verdict.Points);
|
|
Assert.Single(verdict.NewMultipliers);
|
|
}
|
|
|
|
/// A multiplier is worth four on 80 metres, three on 40 and two higher up.
|
|
[Theory]
|
|
[InlineData(3_530, 4)]
|
|
[InlineData(7_030, 3)]
|
|
[InlineData(14_030, 2)]
|
|
[InlineData(21_030, 2)]
|
|
[InlineData(28_030, 2)]
|
|
public void AMultiplierIsWorthMoreOnTheLowBands(double kilohertz, int weight)
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Multiplier multiplier = Assert.Single(log.Judge(On("JA1XYZ", kilohertz)).NewMultipliers);
|
|
|
|
Assert.Equal(weight, multiplier.Weight);
|
|
Assert.Equal("JA1", multiplier.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void TheWeightGoesIntoTheScore()
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
log.Add(On("JA1XYZ", 3_530));
|
|
|
|
Assert.Equal(1, log.Tally.Points);
|
|
Assert.Equal(4, log.Tally.TotalMultipliers);
|
|
Assert.Equal(4, log.TotalScore);
|
|
}
|
|
|
|
/// The countries with call areas count each area separately.
|
|
[Theory]
|
|
[InlineData("K1ABC", "K1")]
|
|
[InlineData("W6XYZ", "K6")]
|
|
[InlineData("JA1XYZ", "JA1")]
|
|
[InlineData("PY2ABC", "PY2")]
|
|
public void ACallAreaIsAMultiplierOfItsOwn(string call, string expected)
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Multiplier multiplier = Assert.Single(log.Judge(On(call, 14_025)).NewMultipliers);
|
|
|
|
Assert.Equal(expected, multiplier.Value);
|
|
}
|
|
|
|
/// Asiatic Russia goes by the call area digit whatever the prefix on the
|
|
/// air, so RM0W and UA0AB are the same multiplier.
|
|
[Theory]
|
|
[InlineData("RM0W")]
|
|
[InlineData("UA0AB")]
|
|
public void AsiaticRussiaCountsByCallArea(string call)
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Multiplier multiplier = Assert.Single(log.Judge(On(call, 14_025)).NewMultipliers);
|
|
|
|
Assert.Equal("UA0", multiplier.Value);
|
|
}
|
|
|
|
/// A callsign the country file cannot place still counts, with an empty
|
|
/// value, so the log scores the same here as in N1MM. All the unplaceable
|
|
/// calls worked on a band share the one multiplier between them.
|
|
[Fact]
|
|
public void ACallWithNoCountryCountsOncePerBand()
|
|
{
|
|
ContestLog log = LogFor(Cw, TestLog.Germany);
|
|
Assert.Equal("", Assert.Single(log.Judge(On("D1M", 14_025)).NewMultipliers).Value);
|
|
log.Add(On("D1M", 14_025));
|
|
Assert.Empty(log.Judge(On("D2X", 14_025)).NewMultipliers);
|
|
}
|
|
|
|
[Fact]
|
|
public void AQtcIsAPointAndNothingElse()
|
|
{
|
|
ContestLog log = LogFor(Rtty, TestLog.Germany);
|
|
Qso qtc = new WaeQtc(
|
|
Callsign.Parse("JA1XYZ"), IsSent: true, 1, 10, "1435", Callsign.Parse("DL9XYZ"), 42)
|
|
.ApplyTo(On("JA1XYZ", 14_080, Modes.Rtty));
|
|
|
|
Verdict verdict = log.Judge(qtc);
|
|
Assert.Equal(1, verdict.Points);
|
|
Assert.Empty(verdict.NewMultipliers);
|
|
}
|
|
|
|
/// The station is worked once and then reported to ten times over; those
|
|
/// rows must not read as dupes of the contact.
|
|
[Fact]
|
|
public void QtcTrafficWithAStationAlreadyWorkedIsNotADupe()
|
|
{
|
|
ContestLog log = LogFor(Rtty, TestLog.Germany);
|
|
log.Add(On("JA1XYZ", 14_080, Modes.Rtty));
|
|
Qso qtc = new WaeQtc(
|
|
Callsign.Parse("JA1XYZ"), IsSent: true, 1, 10, "1435", Callsign.Parse("DL9XYZ"), 42)
|
|
.ApplyTo(On("JA1XYZ", 14_080, Modes.Rtty));
|
|
|
|
Assert.False(log.Judge(qtc).IsDupe);
|
|
log.Add(qtc);
|
|
Assert.Equal(2, log.Tally.Points);
|
|
Assert.Equal(2, log.Tally.TotalMultipliers);
|
|
}
|
|
|
|
[Fact]
|
|
public void AQtcGoesIntoTheLogTheWayN1mmKeepsIt()
|
|
{
|
|
WaeQtc qtc = new(
|
|
Callsign.Parse("H2X"), IsSent: true, 9, 10, "0107", Callsign.Parse("OH1SIC"), 7);
|
|
Qso row = qtc.ApplyTo(On("H2X", 14_099, Modes.Rtty));
|
|
|
|
Assert.Equal("SQTC", row.Exchange1);
|
|
Assert.Equal("9/10", row.MiscText);
|
|
Assert.Equal("0107", row.SentReport);
|
|
Assert.Equal("OH1SIC", row.ReceivedReport);
|
|
Assert.Equal(7, row.SentNumber);
|
|
Assert.Equal(qtc, WaeQtc.From(row));
|
|
}
|
|
|
|
[Fact]
|
|
public void AnOrdinaryContactIsNotAQtc() =>
|
|
Assert.Null(WaeQtc.From(On("JA1XYZ", 14_025)));
|
|
}
|