Files
Nonemm/tests/Nonemm.Contests.Tests/CqWpxTests.cs
T
erikbrockoandClaude Opus 5 7ba0b44fc1 Take serial numbers from a pool the whole entry shares
Each station worked out its next number as the highest in its log plus one,
so two operators typing at the same moment both sent the same number and
one of the two contacts was wrong in the sponsor's log.

SerialNumberPool holds the highest number taken per band, which is N1MM's
QSONumbers array. A number is taken at the first character of the callsign,
as N1MM takes it, and ReserveNr tells the other stations before the contact
is worked. A number at or below one this station has used is answered with
the whole pool, N1MM's QSONRS, and the station that is behind counts on from
there. The pool also goes out when a contest is opened and when the numbers
are started again.

Contest.NumbersByBand says whether the numbers run per band or as one
sequence for the station. CQ WPX runs one per band for a multi-two and a
multi-multi; every other contest here runs one sequence. The band index in
the message is N1MM's, so the array lines up with theirs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015NZkFxHde1iifAQemFTHxf
2026-09-10 11:56:49 +00:00

101 lines
3.6 KiB
C#

using Nonemm.Contests.Rules;
using Nonemm.Core;
namespace Nonemm.Contests.Tests;
public class CqWpxTests
{
private static ContestLog LogFor(StationInfo me, ModeCategory mode = ModeCategory.Cw) =>
new(new CqWpx(mode), me, TestLog.CountryFile);
[Theory]
[InlineData(14_025, 3)]
[InlineData(21_025, 3)]
[InlineData(7_025, 6)]
[InlineData(3_525, 6)]
public void DifferentContinentDoublesBelowFourteenMegahertz(double kilohertz, int expected)
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(expected, log.Judge(TestLog.Contact("JA1XYZ", kilohertz)).Points);
}
[Fact]
public void SameContinentScoresOneOnTheHighBands()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(1, log.Judge(TestLog.Contact("IK2XYZ")).Points);
Assert.Equal(2, log.Judge(TestLog.Contact("IK2XYZ", 7_025)).Points);
}
[Fact]
public void NorthAmericansScoreDoubleWithinNorthAmerica()
{
ContestLog log = LogFor(TestLog.UnitedStates);
Assert.Equal(2, log.Judge(TestLog.Contact("VE3XYZ")).Points);
Assert.Equal(4, log.Judge(TestLog.Contact("VE3XYZ", 7_025)).Points);
}
[Fact]
public void OwnCountryScoresOneOnEveryBand()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Equal(1, log.Judge(TestLog.Contact("DL9XYZ")).Points);
Assert.Equal(1, log.Judge(TestLog.Contact("DL9XYZ", 3_525)).Points);
}
[Fact]
public void RttyScoresOwnCountryTwiceOnTheLowBands()
{
ContestLog log = LogFor(TestLog.Germany, ModeCategory.Digital);
Assert.Equal(1, log.Judge(TestLog.Contact("DL9XYZ", mode: Modes.Rtty)).Points);
Assert.Equal(2, log.Judge(TestLog.Contact("DL9XYZ", 3_525, Modes.Rtty)).Points);
}
[Fact]
public void PrefixCountsOnceForTheWholeContest()
{
ContestLog log = LogFor(TestLog.Germany);
log.Add(TestLog.Contact("JA1XYZ"));
Assert.Empty(log.Judge(TestLog.Contact("JA1ZZZ", 7_025)).NewMultipliers);
Assert.Single(log.Judge(TestLog.Contact("JA2ZZZ", 7_025)).NewMultipliers);
}
[Fact]
public void MaritimeMobileBringsNoPrefix()
{
ContestLog log = LogFor(TestLog.Germany);
Assert.Empty(log.Judge(TestLog.Contact("DL1ABC/MM")).NewMultipliers);
}
/// A tuning carrier logged by accident, or any contact in a mode the
/// contest does not run, scores nothing. The prefix still counts, which is
/// what N1MM logs.
[Fact]
public void AContactInAnotherModeScoresNothingAndKeepsItsMultiplier()
{
ContestLog log = new(new CqWpx(ModeCategory.Phone), TestLog.Germany, TestLog.CountryFile);
Verdict verdict = log.Judge(TestLog.Contact("IK2XYZ", mode: Modes.Rtty, number: 5));
Assert.Equal(0, verdict.Points);
Assert.Single(verdict.NewMultipliers);
}
/// A multi-two and a multi-multi run a serial number sequence per band; a
/// single operator and a multi-one run one sequence. N1MM asks its
/// contests the same question before it takes a number.
[Theory]
[InlineData("SINGLE-OP", "ONE", false)]
[InlineData("MULTI-ONE", "ONE", false)]
[InlineData("MULTI-TWO", "TWO", true)]
[InlineData("MULTI-MULTI", "UNLIMITED", true)]
[InlineData("MULTI-OP", "TWO", true)]
[InlineData("MULTI-OP", "UNLIMITED", true)]
public void OnlyAMultiTwoOrMultiMultiNumbersPerBand(string operators, string transmitters, bool byBand) =>
Assert.Equal(
byBand,
new CqWpx(ModeCategory.Cw).NumbersByBand(new ContestEntry
{
OperatorCategory = operators,
TransmitterCategory = transmitters,
}));
}