## Direct assertion that WaveSurfer decomposes an enemy's (heading, speed) into ## a world velocity with the Tank Royale angle convention: 0 degrees = EAST, ## angles increase counter-clockwise, so vx = cos(h)*s and vy = sin(h)*s. ## ## The classic-Robocode convention (0 = north, clockwise) would swap sin/cos; ## this test fails if anyone reintroduces that bug. import std/[math, unittest] import ../test_framework/adversaries/WaveSurfer/src/WaveSurfer const eps = 1e-9 proc close(a, b: float): bool = abs(a - b) < eps suite "WaveSurfer enemy velocity decomposition (TR: 0=east, CCW+)": test "east heading is +x": let v = enemyVelocity(0.0, 10.0) check close(v.vx, 10.0) check close(v.vy, 0.0) test "north heading (90 deg) is +y": let v = enemyVelocity(90.0, 10.0) check close(v.vx, 0.0) check close(v.vy, 10.0) test "west heading (180 deg) is -x": let v = enemyVelocity(180.0, 10.0) check close(v.vx, -10.0) check close(v.vy, 0.0) test "south heading (270 deg) is -y": let v = enemyVelocity(270.0, 10.0) check close(v.vx, 0.0) check close(v.vy, -10.0) test "diagonal 45 deg splits evenly": let v = enemyVelocity(45.0, 10.0) check close(v.vx, 10.0 / sqrt(2.0)) check close(v.vy, 10.0 / sqrt(2.0)) test "negative speed reverses the velocity": let v = enemyVelocity(0.0, -5.0) check close(v.vx, -5.0) check close(v.vy, 0.0) test "explicitly differs from the classic sin/cos swap": # The old (buggy) decomposition. If the implementation ever matches this # at a heading where cos != sin, the test fails. for heading in [30.0, 60.0, 90.0, 120.0]: let v = enemyVelocity(heading, 8.0) let swappedX = sin(degToRad(heading)) * 8.0 let swappedY = cos(degToRad(heading)) * 8.0 check not (close(v.vx, swappedX) and close(v.vy, swappedY))