Files
OpenSquawk/shared/utils/transponder.ts
itsrubberduck a9f6e6df42 fix(clearance): generate octal squawks and skip reserved codes
genSquawk() drew a decimal number in 1000-8999, so clearances could contain
the digits 8 or 9 — codes no transponder can dial. Replace it with a shared
generateSquawk() that draws four octal digits and re-rolls the reserved codes
(7500/7600/7700, 7000, 2000, 1200, 0000).

shared/learn/scenario.ts had its own octal generator that could still draw an
emergency code; it now uses the same helper.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-26 19:27:21 +02:00

40 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Transponder (SSR) code generation.
*
* A squawk is an *octal* four-digit code — every digit is 07, because each
* digit is encoded in three pulse positions. A code containing 8 or 9 cannot be
* dialled into a real transponder, so it must never reach a clearance.
*/
/**
* Codes ATC will not assign as a discrete code.
*
* 7500/7600/7700 are the ICAO emergency codes (unlawful interference, radio
* failure, general emergency); 7000 is the European VFR conspicuity code and
* 1200 its US equivalent; 2000 is the code for entering from a non-SSR area;
* 0000 is a non-code used to indicate a transponder fault.
*/
export const RESERVED_SQUAWKS = new Set([
'7500', '7600', '7700', '7000', '2000', '1200', '0000',
])
/** True when `code` is a well-formed, assignable discrete squawk. */
export function isValidSquawk(code: string): boolean {
if (!/^[0-7]{4}$/.test(code)) return false
return !RESERVED_SQUAWKS.has(code)
}
/** A random assignable discrete squawk: four octal digits, no reserved code. */
export function generateSquawk(): string {
// The reserved set is tiny next to the 4096-code space, so re-rolling
// terminates immediately in practice; the bound just makes that guaranteed.
for (let attempt = 0; attempt < 20; attempt++) {
let code = ''
for (let digit = 0; digit < 4; digit++) {
code += String(Math.floor(Math.random() * 8))
}
if (isValidSquawk(code)) return code
}
return '1000'
}