nextzlog / todo

ToDo lists for ATS-4, CW4ISR, QxSL, ZyLO.
https://nextzlog.dev
1 stars 0 forks source link

ALLJA1コンテストのデジタル部門の規約変更 #197

Closed JG1VPP closed 3 months ago

JG1VPP commented 3 months ago

問題意識

第36回ALLJA1コンテストでの規約変更により、デジタル部門もアナログ部門と同じコンテストナンバーを送信する。

解決方法

allja1.lispを修正し、ATS-4側でqxslのバージョンを更新する。

JG1VPP commented 3 months ago

テストコード

from datetime import datetime as dt

mults = set()

with open("src/main/resources/qxsl/local/city.ja") as f:
    for line in f.read().splitlines():
        _, _, mult = line.split()
        mults.add(mult)

def inner(rcvd):
    return len(rcvd) != 3 and int(rcvd[:2]) in range(10, 18)

def valid_num(rcvd):
    if rcvd not in mults:
        return False
    # prefecture
    if len(rcvd) == 2:
        return not inner(rcvd) and rcvd not in ["01", "48"]
    # sub-prefecture
    elif len(rcvd) == 3:
        return True
    else:
        return inner(rcvd)

MORSE = ["CW"]
PHONE = ["PH", "AM", "FM", "DSB", "LSB", "USB", "SSB"]
DIGIT = ["DG", "FT4", "FT8", "RTTY", "MFSK"]

def valid_qso(time, band, mode, call, rcvd):
    if not valid_num(rcvd):
        return False
    if 9 <= time.hour <= 11:
        return mode in MORSE + PHONE and band in ["14", "21", "28", "50"]
    elif 13 <= time.hour <= 14:
        return mode in DIGIT and band in ["7"]
    elif 16 <= time.hour <= 19:
        return (mode in MORSE + PHONE) and (band in ["1.9", "3.5", "7"])
    else:
        return False

inner_calls = set()
inner_codes = set()

outer_calls = set()
outer_codes = set()

with open("src/test/resources/qxsl/ruler/allja1.jarl") as f:
    for line in f.read().splitlines():
        if not line.startswith("DATE"):
            date, time, band, mode, call, _, _, _, rcvd, _, _ = line.split()
            time = dt.strptime(f"{date} {time}", "%Y-%m-%d %H:%M")
            if valid_qso(time, band, mode, call, rcvd):
                if mode in MORSE:
                    mode = 1
                elif mode in PHONE:
                    mode = 2
                elif mode in DIGIT:
                    mode = 3
                else:
                    continue
                if (band, mode, call) not in inner_calls:
                    inner_calls.add((band, mode, call))
                    inner_codes.add((band, rcvd))
                if inner(rcvd):
                    if (band, mode, call) not in outer_calls:
                        outer_calls.add((band, mode, call))
                        outer_codes.add((band, rcvd))

print(len(inner_calls), len(inner_calls) * len(inner_codes))
print(len(outer_calls), len(outer_calls) * len(outer_codes))

@jucky154 この計算手法で合っていますか?

jucky154 commented 3 months ago

inner_callsは1エリア内の人だった時の得点計算 outer_callsは1エリア外の人だった時の得点計算 のための配列的なものという自分の認識が正しい(このコードにないところで, sendのエリアを調べて, どちらを表示するかは変える)のであれば, 問題ないと思います.

JG1VPP commented 3 months ago

デプロイ済み