import std/math const FRAME_BITS* = 83 SELF_BITS* = 40 WINDOW_SIZE* = 10 TOTAL_BITS* = FRAME_BITS * WINDOW_SIZE + SELF_BITS # 870 type BinaryVector* = array[TOTAL_BITS, uint8] EnemyScanFrame* = object bearing*: float # → sin/cos, 8+8 bits distance*: float # → %, 7 bits velocity*: float # → 5 bits heading*: float # → sin/cos, 8+8 bits enemyWallN*: float # 7 bits enemyWallS*: float # 7 bits enemyWallE*: float # 7 bits enemyWallW*: float # 7 bits enemyEnergy*: float # 11 bits SelfState* = object myWallN*: float # 7 bits myWallS*: float # 7 bits myWallE*: float # 7 bits myWallW*: float # 7 bits myEnergy*: float # 11 bits canFire*: bool # 1 bit const MAX_DISTANCE = 1414.0 # diagonal of 1000x1000 arena NUM_FRAME_FIELDS* = 9 # for CSV output: bearing_sin, bearing_cos, distance, velocity, heading_sin, heading_cos, enemy_x, enemy_y, energy FIELD_NAMES* = ["bearing_sin", "bearing_cos", "distance", "velocity", "heading_sin", "heading_cos", "wallN", "wallS", "energy"] proc toGray(value: int): int = value xor (value shr 1) proc toBits(value: int, bits: int): seq[uint8] = result = newSeq[uint8](bits) let gray = toGray(value) for i in 0.. 0: result &= "," result &= $cnt proc formatFrameBinary*(frame: array[FRAME_BITS, uint8]): string = for b in frame: result &= (if b == 1: "1" else: "0") proc formatFrameDecimal*(frame: array[FRAME_BITS, uint8]): string = # Nine decimal fields from the frame bits # bearing_sin (0-199), bearing_cos (0-199), distance (0-99), velocity (0-15), heading_sin (0-199), heading_cos (0-199), wall (0-99), wall (0-99), energy (0-1500/10) result = "199,199,99,15,199,199,99,99,150" # placeholder max values proc decodeFrameFields*(frame: array[FRAME_BITS, uint8]): array[9, float] = # Decode frame to 9 decimal field values (enemy X, Y for field indices 6, 7) # This is a placeholder—actual decoding would reverse the toBits() encoding result = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 50.0, 50.0, 100.0] # Output encoding ------------------------------------------------------- const OUTPUT_BITS* = 7 AIM_MIN* = -60.0 AIM_MAX* = 60.0 type OutputVector* = array[OUTPUT_BITS, uint8] proc encodeOutput*(angle: float): OutputVector = let clamped = clamp(angle, AIM_MIN, AIM_MAX) let intVal = int((clamped - AIM_MIN) / (AIM_MAX - AIM_MIN) * 127.0) let gray = toGray(intVal) for i in 0.. 0: binary = binary xor mask mask = mask shr 1 result = AIM_MIN + (float(binary) / 127.0) * (AIM_MAX - AIM_MIN)