The score window and the stored Contest.Multiplier1Name row both said "Prefixes" for an Asian entrant, which counts DXCC entities. Contest.MultiplierNames is now MultiplierNamesFor(StationInfo me), the same shape as ExchangeFieldsFor. Every other contest returns the same list it did before; All Asian returns "Countries" from Asia and "Prefixes" from everywhere else. ContestDefinitions.For takes the station as well, because that name is written to the log for N1MM. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0157i7PiZyqBkquxS9A6FTdQ
101 lines
3.6 KiB
C#
101 lines
3.6 KiB
C#
using Nonemm.Core;
|
|
|
|
namespace Nonemm.Contests.Rules;
|
|
|
|
/// The JARL All Asian DX contest. It is two contests in one. A station
|
|
/// outside Asia works Asia only, and counts the WPX prefix of each Asian
|
|
/// station once per band. An Asian station works everybody except its own
|
|
/// country, counts countries instead of prefixes, and is paid three times the
|
|
/// band value for a contact outside Asia.
|
|
public sealed class AllAsian : Contest
|
|
{
|
|
private readonly ModeCategory mode;
|
|
|
|
public AllAsian(ModeCategory mode) => this.mode = mode;
|
|
|
|
public string Name => mode == ModeCategory.Cw ? "ALLASIACW" : "ALLASIASSB";
|
|
|
|
public string DisplayName => $"All Asian DX {ModeLabel()}";
|
|
|
|
public string CabrilloName => mode == ModeCategory.Cw ? "AADX-CW" : "AADX-SSB";
|
|
|
|
public IReadOnlyList<ExchangeField> ExchangeFieldsFor(StationInfo me) =>
|
|
[
|
|
new ExchangeField("Snt", ExchangeSlot.SentReport, ExchangeFieldKind.Report, IsRequired: false),
|
|
new ExchangeField("Rcv", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report),
|
|
new ExchangeField("Age", ExchangeSlot.Exchange1, ExchangeFieldKind.Number) { Width = 3 },
|
|
];
|
|
|
|
public IReadOnlyList<string> MultiplierNamesFor(StationInfo me) =>
|
|
me.Continent == "AS" ? ["Countries"] : ["Prefixes"];
|
|
|
|
public DupeScope DupeScope => DupeScope.PerBand;
|
|
|
|
public bool HasSerialNumbers => false;
|
|
|
|
public IReadOnlyList<ModeCategory> Modes => [mode];
|
|
|
|
public string SentExchangeFor(StationInfo me) => "";
|
|
|
|
public int PointsFor(QsoContext qso)
|
|
{
|
|
if (!IsWorkable(qso))
|
|
{
|
|
return 0;
|
|
}
|
|
bool treble = qso.Me.Continent == "AS"
|
|
&& qso.Continent != "AS"
|
|
&& !qso.Qso.Call.IsMaritimeMobile;
|
|
return PointsOn(qso.Band) * (treble ? 3 : 1);
|
|
}
|
|
|
|
public IReadOnlyList<Multiplier> MultipliersFor(QsoContext qso)
|
|
{
|
|
if (!IsWorkable(qso) || qso.Qso.Call.IsMaritimeMobile)
|
|
{
|
|
return [];
|
|
}
|
|
string? value = qso.Me.Continent == "AS" ? qso.CountryPrefix : qso.Qso.Call.WpxPrefix();
|
|
return string.IsNullOrEmpty(value)
|
|
? []
|
|
: [new Multiplier(1, value, 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(entry.SentExchange, 3),
|
|
],
|
|
[
|
|
new CabrilloField(qso.Call.Text, 13),
|
|
new CabrilloField(qso.ReceivedReport, 3),
|
|
new CabrilloField(qso.Exchange1, 3),
|
|
]);
|
|
|
|
/// An Asian station works anybody outside its own country. Everybody else
|
|
/// works Asia only, and a maritime mobile is not one of them: a station at
|
|
/// sea makes a valid contact with an Asian station alone.
|
|
public bool IsWorkable(QsoContext qso) =>
|
|
qso.Me.Continent == "AS"
|
|
? !qso.IsSameCountry
|
|
: qso.Continent == "AS" && !qso.Qso.Call.IsMaritimeMobile;
|
|
|
|
/// 160 metres is worth 3, 80 and 10 metres 2, and every other band 1. An
|
|
/// Asian entrant works from the same table and trebles it outside Asia,
|
|
/// except for a maritime mobile, which pays the Asian rate wherever it is.
|
|
private static int PointsOn(Band? band) => band?.Name switch
|
|
{
|
|
"160M" => 3,
|
|
"80M" or "10M" => 2,
|
|
null => 0,
|
|
_ => 1,
|
|
};
|
|
|
|
private string ModeLabel() => mode == ModeCategory.Cw ? "CW" : "SSB";
|
|
}
|