chore: rename libs→common_libs, all bot dirs to _garage suffix, fix all path refs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 18:18:41 +02:00
parent f8c0c871c6
commit b509195ee9
832 changed files with 4967 additions and 368 deletions
+38
View File
@@ -0,0 +1,38 @@
## Standalone radar lock module for Robocode Tank Royale (1v1).
## No bot-specific imports — takes plain floats, returns radarTurnRate.
##
## Tank Royale radar uses standard math convention: 0° = east, CCW positive.
## Angles are in degrees.
import std/math
const
MaxRadarTurn* = 45.0
DefaultOvershootDeg* = 5.0
var overShootDeg* = DefaultOvershootDeg
proc init*() =
## Reset module to defaults.
## In your bot's constructor set:
## adjustRadarForBodyTurn = true
## adjustRadarForGunTurn = true
overShootDeg = DefaultOvershootDeg
proc normalizeRelative(angle: float64): float64 {.inline.} =
result = angle mod 360.0
if result >= 180.0: result -= 360.0
elif result < -180.0: result += 360.0
proc doRadar*(currentRadarHeading, enemyBearing: float64): float64 =
## Returns radarTurnRate (degrees/tick, positive = clockwise).
##
## currentRadarHeading: current radar direction in degrees (0=east, CCW+).
## enemyBearing: absolute bearing to enemy in same coordinate system.
##
## Handles angle wrapping, clamps to [-45, +45], adds overshoot sweep.
var turn = normalizeRelative(enemyBearing - currentRadarHeading)
# Add overshoot in the same direction as the turn to maintain lock
if turn < 0.0: turn -= overShootDeg
else: turn += overShootDeg
result = turn.clamp(-MaxRadarTurn, MaxRadarTurn)
+8
View File
@@ -0,0 +1,8 @@
# Package
version = "1.0.0"
author = "Davide Cappellini"
description = "Standalone radar lock module for Robocode Tank Royale"
license = "Apache-2.0"
# Dependencies
requires "nim >= 2.0.0"
Binary file not shown.
@@ -0,0 +1,74 @@
import std/unittest
import std/math
import ../radar_lock
suite "radar_lock":
setup:
init()
# Basic lock: radar already on enemy — overshoot pushes it slightly
test "radar on enemy — returns overshoot only":
let rate = doRadar(90.0, 90.0)
check rate == DefaultOvershootDeg
# Cardinal directions
test "lock from 0 degrees":
let rate = doRadar(0.0, 0.0)
check rate == DefaultOvershootDeg
test "lock from 90 degrees":
let rate = doRadar(90.0, 90.0)
check rate == DefaultOvershootDeg
test "lock from 180 degrees":
let rate = doRadar(180.0, 180.0)
check rate == DefaultOvershootDeg
test "lock from 270 degrees":
let rate = doRadar(270.0, 270.0)
check rate == DefaultOvershootDeg
# Angle wrapping: radar at 350°, enemy at 10° → shortest path is +20°
test "wrapping 350 to 10 — turns right 20 + overshoot":
let rate = doRadar(350.0, 10.0)
check abs(rate - (20.0 + DefaultOvershootDeg)) < 1e-9
# Angle wrapping: radar at 10°, enemy at 350° → shortest path is -20°
test "wrapping 10 to 350 — turns left 20 + overshoot":
let rate = doRadar(10.0, 350.0)
check abs(rate - (-20.0 - DefaultOvershootDeg)) < 1e-9
# Clamping: enemy 100° away → raw turn+overshoot > 45°, must clamp
test "clamp positive — large gap":
let rate = doRadar(0.0, 100.0)
check rate == 45.0
test "clamp negative — large gap":
let rate = doRadar(100.0, 0.0)
check rate == -45.0
# Overshoot direction: turn right → positive overshoot
test "overshoot direction right":
let rate = doRadar(0.0, 30.0) # needs +30°, overshoot adds +5°
check abs(rate - 35.0) < 1e-9
# Overshoot direction: turn left → negative overshoot
test "overshoot direction left":
let rate = doRadar(30.0, 0.0) # needs -30°, overshoot adds -5°
check abs(rate - (-35.0)) < 1e-9
# Output never exceeds ±45
test "output bounded above":
let rate = doRadar(0.0, 179.0)
check rate <= 45.0
test "output bounded below":
let rate = doRadar(179.0, 0.0)
check rate >= -45.0
# init() resets overShootDeg
test "init resets overshoot":
overShootDeg = 20.0
init()
check overShootDeg == DefaultOvershootDeg