# HG changeset patch # User Josef 'Jeff' Sipek # Date 1727359269 14400 # Thu Sep 26 10:01:09 2024 -0400 # Node ID 151e00cb5882b87fbf3b2bdf11bb4f9d9cf5d5be # Parent 00509bf120566411a64858c67c40fab9320bf3ba WIP: xlua: switch CQ-WW-VHF to grid helper diff --git a/xlua/scripts/contests/CQ-WW-VHF.lua b/xlua/scripts/contests/CQ-WW-VHF.lua --- a/xlua/scripts/contests/CQ-WW-VHF.lua +++ b/xlua/scripts/contests/CQ-WW-VHF.lua @@ -1,5 +1,5 @@ -- --- Copyright (c) 2022-2024 Josef 'Jeff' Sipek +-- Copyright (c) 2022-2025 Josef 'Jeff' Sipek -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal @@ -25,13 +25,6 @@ [6000] = 1, } -local dup_table = {} -local mults = {} - -for band, _ in pairs(ALLOWED_BANDS) do - dup_table[band] = {} -end - local function mkgrid(g) if g == nil then return "" @@ -40,61 +33,16 @@ return g:sub(1,4) end -local function hash(mgrid, tgrid) - return string.format("%s-%s", mkgrid(mgrid), mkgrid(tgrid)) -end - -local function duphash(qso) - local mgrid = mkgrid(qso.tx.grid) - local tgrid = mkgrid(qso.rx.grid) - +local function duphash(qso, tx, rx) return string.format("%s-%s-%s-%s", - mgrid, qso.rx.station_call, tgrid, qso.tx.band) + qso.rx.station_call, + qso.tx.band, + mkgrid(tx), + mkgrid(rx)) end -local function check(band, who, mgrid, tgrid) - local where = hash(mgrid, tgrid) - local info = dup_table[band][who] - - if info == nil then - return 1 -- callsign not seen before on this band ==> not dup - end - - if info[where] then - return 3 -- exact match ==> dup - end - - for cur, _ in pairs(info) do - if cur:find(where, 1, true) == 1 then - return 2 -- where is a prefix of cur ==> maybe dup - end - end - - return 1 -- no prefix found ==> not dup -end - -local function update_dup_table(qso) - local where = hash(qso.tx.grid, qso.rx.grid) - local mult = string.format("%u-%s", qso.tx.band, where) - - if dup_table[qso.tx.band][qso.rx.station_call] == nil then - dup_table[qso.tx.band][qso.rx.station_call] = {} - end - dup_table[qso.tx.band][qso.rx.station_call][where] = true - - mults[mult] = true -end - -local function qso_done(qso) - if not ALLOWED_BANDS[qso.tx.band] then - return -- ignore out-of-band contacts - end - - qso.additional['contest-id'] = 'CQ-WW-VHF' - qso.additional['contest-year'] = contest.year - - update_dup_table(qso) -end +-- The object keeping all the state +local vhf -- -- Annunciator color @@ -102,31 +50,20 @@ -- There are three colors we can display: "not a dup", "maybe a dup", and -- "definitely a dup". When we have full information (i.e., callsign and -- grid), it is easy to check and return either "not a dup" or "definitely a --- dup". Things get more complicated when we don't have all the info. In --- general, we try to do a prefix match with the entered grid square. This --- allows us to indicate whether or not there is some chance of a dup. -local function is_dup(qso, band, color_none, color_warn, color_dup) - local colors = { color_none, color_warn, color_dup } - local who = qso.rx.station_call - local where = qso.rx.grid - +-- dup". When we don't have full information (i.e., 4-digit grid), we just +-- warn that it may be a duplicate. +local function is_dup(qso, color_none, color_warn, color_dup) -- -- complete information -- - if where ~= nil and where:len() >= 4 then - local colors = { color_none, nil, color_dup } - - return colors[check(band, who, qso.tx.grid, where)] + if qso.rx.grid ~= nil and qso.rx.grid:len() >= 4 then + return vhf:is_dup(qso) and color_dup or color_none end -- -- incomplete information -- - if where ~= nil then - return colors[check(band, who, qso.tx.grid, where)] - end - - return colors[check(band, who, qso.tx.grid, "")] + return color_warn end local function field_changed(qso, fields, field) @@ -142,79 +79,53 @@ error(string.format("Unknown field '%s' encountered", field)) end - if not ALLOWED_BANDS[qso.tx.band] then - return -- ignore out-of-band contacts - end - return nil, { - ["2m"] = is_dup(qso, 2000, "green", "magenta", "off"), - ["6m"] = is_dup(qso, 6000, "green", "magenta", "off"), - ["DUP"] = is_dup(qso, qso.tx.band, "black", "black", "red"), + ["DUP"] = is_dup(qso, "black", "black", "red"), + ["OOB"] = ALLOWED_BANDS[qso.tx.band] ~= nil and "black" or "red", } end -local function add_entry(all, dups, qso) - if qso.additional['contest-id'] ~= "CQ-WW-VHF" or - qso.additional['contest-year'] ~= contest.year then - return +local function qexchange(side, ex) + if ex == nil then + return "????", false + else + return mkgrid(ex), true end - - if qso.tx.band == nil then - print(string.format("Error: %s QSO lacks band info", qso.uuid)) - return - end - - assert(qso.tx.station_call ~= nil) - - local dupkey = duphash(qso) - - table.insert(all, qso) - dups[dupkey] = qso end -local function mkexchange(side) - local ok = true - local out = mkgrid(side.grid) +local function qpoints(qso, tx, rx) + return ALLOWED_BANDS[qso.tx.band] +end - if out == "" then - ok = false - out = "??" - end - - return out, ok +local function qmult(qso, tx, rx) + return string.format("%u-%s-%s", qso.tx.band, mkgrid(tx), mkgrid(rx)) end local function export(outfname) - local all = {} - local dups = {} + local all + local station + local ops + local points + local mults - for qso in hlog.index.history(true) do - add_entry(all, dups, qso) - end + all, station, ops, points, mults = vhf:export_prep(contest.id, contest.year, + qpoints, qmult, qexchange) - local qpoints = 0 - local mults = {} - for _, qso in pairs(dups) do - qpoints = qpoints + ALLOWED_BANDS[qso.tx.band] - mults[string.format("%s-%s-%s", - mkgrid(qso.tx.grid), - mkgrid(qso.rx.grid), - qso.tx.band)] = true - end + hlog.cabrillo.print_header(contest.id, + station, + ops:as_array(), + points * mults:count_items()) - local score = qpoints * hlog.utils.count_items(mults) - - -- TODO: print cabrillo header - - for _, qso in ipairs(all) do - local tx, txok = mkexchange(qso.tx, qso.additional['contest-tx']) - local rx, rxok = mkexchange(qso.rx, qso.additional['contest-rx']) - local xqso = not txok or not rxok + for _, rec in ipairs(all) do + local qso = rec[1] + local tx = rec[2] + local rx = rec[3] + local xqso = not rec[4] hlog.cabrillo.print_qso(qso, tx, rx, xqso) end - -- TODO: print cabrillo footer + hlog.cabrillo.print_footer() end return { @@ -231,17 +142,20 @@ }, annunciators = { - { 0, 31, "DUP", "black" }, - { 0, 35, "6m", "black" }, - { 0, 38, "2m", "black" }, + { 0, 31, "OOB", "black" }, + { 0, 35, "DUP", "black" }, }, events = { + export = export, startup = function(template) + vhf = hlog.contest_helper.grid(contest.id, contest.year, duphash) + + -- load previous contacts from history for qso in hlog.index.history(true) do if qso.additional['contest-id'] == 'CQ-WW-VHF' and qso.additional['contest-year'] == contest.year then - update_dup_table(qso) + vhf:qso_load(qso) end end @@ -255,11 +169,14 @@ template.tx.operator_call = op end, - export = export, qso_init = function(qso) contest.lcd(mkgrid(qso.tx.grid)) end, - qso_done = qso_done, + qso_done = function(qso) + if ALLOWED_BANDS[qso.tx.band] then + vhf:qso_done(qso) + end + end, field_changed = field_changed, }, }