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:
@@ -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)
|
||||
@@ -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"
|
||||
Executable
BIN
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
|
||||
Reference in New Issue
Block a user