Updated game structure
This commit is contained in:
82
tests/GravityTests.cpp
Normal file
82
tests/GravityTests.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <catch2/catch_approx.hpp>
|
||||
#include <iostream>
|
||||
#include "core/GravityManager.h"
|
||||
|
||||
TEST_CASE("GravityManager basic ms calculation", "[gravity]") {
|
||||
GravityManager g;
|
||||
g.setGlobalMultiplier(1.0);
|
||||
double ms0 = g.getMsForLevel(0);
|
||||
REQUIRE(ms0 > 0);
|
||||
double ms29 = g.getMsForLevel(29);
|
||||
REQUIRE(ms29 >= 1.0);
|
||||
}
|
||||
|
||||
// Additional tests
|
||||
TEST_CASE("frames_to_ms_exact", "[gravity][exact]") {
|
||||
// Reuse the reference constants (must match GravityManager implementation)
|
||||
constexpr double NES_FPS = 60.0988;
|
||||
constexpr double FRAME_MS = 1000.0 / NES_FPS;
|
||||
constexpr int FRAMES_TABLE[30] = {
|
||||
48, 43, 38, 33, 28, 23, 18, 13, 8, 6,
|
||||
5, 5, 5, 4, 4, 4, 3, 3, 3, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
|
||||
GravityManager g;
|
||||
g.setGlobalMultiplier(1.0);
|
||||
|
||||
for (int lvl = 0; lvl <= 29; ++lvl) {
|
||||
double expected = static_cast<double>(FRAMES_TABLE[lvl]) * FRAME_MS * 1.0;
|
||||
double actual = g.getMsForLevel(lvl);
|
||||
// GravityManager clamps to minimum 1.0ms; expected for these levels is >> 1.0 except possibly level 29
|
||||
if (expected < 1.0) expected = 1.0;
|
||||
if (!(actual == Catch::Approx(expected).epsilon(1e-6))) {
|
||||
std::cerr << "DEBUG: lvl=" << lvl << ", levelMultiplier=" << g.getLevelMultiplier(lvl)
|
||||
<< ", FRAMES_TABLE[lvl]=" << FRAMES_TABLE[lvl]
|
||||
<< ", actual=" << actual << ", expected=" << expected << std::endl;
|
||||
}
|
||||
REQUIRE(actual == Catch::Approx(expected).epsilon(1e-6));
|
||||
REQUIRE(g.getFpsForLevel(lvl) == Catch::Approx(1000.0 / actual).epsilon(1e-6));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("multiplier_effects", "[gravity][multiplier]") {
|
||||
GravityManager g;
|
||||
g.setGlobalMultiplier(1.0);
|
||||
|
||||
double base = g.getMsForLevel(5); // level 5 baseline
|
||||
g.setLevelMultiplier(5, 2.0);
|
||||
double doubled = g.getMsForLevel(5);
|
||||
REQUIRE(doubled == Catch::Approx(base * 2.0).epsilon(1e-6));
|
||||
|
||||
// global multiplier scales all levels
|
||||
g.setGlobalMultiplier(0.5);
|
||||
double afterGlobal = g.getMsForLevel(5);
|
||||
REQUIRE(afterGlobal == Catch::Approx(doubled * 0.5).epsilon(1e-6));
|
||||
}
|
||||
|
||||
TEST_CASE("clamping_and_edges", "[gravity][clamp]") {
|
||||
GravityManager g;
|
||||
// global multiplier clamped to [0.01,100.0]
|
||||
g.setGlobalMultiplier(0.0001);
|
||||
REQUIRE(g.getGlobalMultiplier() == Catch::Approx(0.01).epsilon(1e-12));
|
||||
g.setGlobalMultiplier(500.0);
|
||||
REQUIRE(g.getGlobalMultiplier() == Catch::Approx(100.0).epsilon(1e-12));
|
||||
|
||||
// per-level multiplier clamps
|
||||
g.setLevelMultiplier(100, 200.0);
|
||||
REQUIRE(g.getLevelMultiplier(100) == Catch::Approx(100.0).epsilon(1e-12));
|
||||
// negative level queries map to level 0
|
||||
REQUIRE(g.getLevelMultiplier(-5) == Catch::Approx(g.getLevelMultiplier(0)).epsilon(1e-12));
|
||||
}
|
||||
|
||||
TEST_CASE("min_ms_enforced", "[gravity][min]") {
|
||||
GravityManager g;
|
||||
// Force very small multipliers then ensure minimum 1.0ms enforced
|
||||
g.setLevelMultiplier(29, 0.01);
|
||||
g.setGlobalMultiplier(0.01);
|
||||
double ms29 = g.getMsForLevel(29);
|
||||
REQUIRE(ms29 >= 1.0);
|
||||
REQUIRE(ms29 == Catch::Approx(1.0).epsilon(1e-12));
|
||||
}
|
||||
Reference in New Issue
Block a user