formation_system_test.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "systems/formation_system.h"
  2. #include <QVector3D>
  3. #include <gtest/gtest.h>
  4. using namespace Game::Systems;
  5. class FormationSystemTest : public ::testing::Test {
  6. protected:
  7. void SetUp() override {
  8. // FormationSystem is a singleton, instance is automatically initialized
  9. }
  10. };
  11. TEST_F(FormationSystemTest, RomanFormationCreatesRectangularGrid) {
  12. QVector3D center(0.0F, 0.0F, 0.0F);
  13. float spacing = 2.0F;
  14. int unit_count = 9; // 3x3 grid
  15. auto positions = FormationSystem::instance().get_formation_positions(
  16. FormationType::Roman, unit_count, center, spacing);
  17. EXPECT_EQ(positions.size(), 9);
  18. // Check that positions are arranged in a grid pattern
  19. // Roman formation uses rectangular layout with 0.7 aspect ratio
  20. for (const auto &pos : positions) {
  21. EXPECT_FLOAT_EQ(pos.y(), center.y());
  22. }
  23. }
  24. TEST_F(FormationSystemTest, CarthageFormationHasJitter) {
  25. QVector3D center(0.0F, 0.0F, 0.0F);
  26. float spacing = 2.0F;
  27. int unit_count = 9;
  28. auto positions1 = FormationSystem::instance().get_formation_positions(
  29. FormationType::Carthage, unit_count, center, spacing);
  30. // Carthage formation uses jitter, so positions won't be perfectly aligned
  31. EXPECT_EQ(positions1.size(), 9);
  32. // Check that all positions are near the center (within reasonable bounds)
  33. for (const auto &pos : positions1) {
  34. EXPECT_LT(std::abs(pos.x() - center.x()), spacing * 5.0F);
  35. EXPECT_LT(std::abs(pos.z() - center.z()), spacing * 5.0F);
  36. EXPECT_FLOAT_EQ(pos.y(), center.y());
  37. }
  38. }
  39. TEST_F(FormationSystemTest, BarbarianFormationIsLooser) {
  40. QVector3D center(0.0F, 0.0F, 0.0F);
  41. float spacing = 2.0F;
  42. int unit_count = 9;
  43. auto barbarian_positions =
  44. FormationSystem::instance().get_formation_positions(
  45. FormationType::Barbarian, unit_count, center, spacing);
  46. auto roman_positions = FormationSystem::instance().get_formation_positions(
  47. FormationType::Roman, unit_count, center, spacing);
  48. EXPECT_EQ(barbarian_positions.size(), 9);
  49. EXPECT_EQ(roman_positions.size(), 9);
  50. // Barbarian formation should use more spacing (1.8x vs 1.2x)
  51. // Calculate average distance from center for both formations
  52. float barbarian_avg_dist = 0.0F;
  53. float roman_avg_dist = 0.0F;
  54. for (size_t i = 0; i < 9; ++i) {
  55. QVector3D barbarian_vec = barbarian_positions[i] - center;
  56. QVector3D roman_vec = roman_positions[i] - center;
  57. barbarian_avg_dist += barbarian_vec.length();
  58. roman_avg_dist += roman_vec.length();
  59. }
  60. barbarian_avg_dist /= 9.0F;
  61. roman_avg_dist /= 9.0F;
  62. // Barbarian should have larger average distance due to looser spacing
  63. EXPECT_GT(barbarian_avg_dist, roman_avg_dist);
  64. }
  65. TEST_F(FormationSystemTest, HandlesZeroUnits) {
  66. QVector3D center(0.0F, 0.0F, 0.0F);
  67. auto positions = FormationSystem::instance().get_formation_positions(
  68. FormationType::Roman, 0, center, 1.0F);
  69. EXPECT_TRUE(positions.empty());
  70. }
  71. TEST_F(FormationSystemTest, HandlesSingleUnit) {
  72. QVector3D center(5.0F, 0.0F, 10.0F);
  73. auto positions = FormationSystem::instance().get_formation_positions(
  74. FormationType::Roman, 1, center, 1.0F);
  75. EXPECT_EQ(positions.size(), 1);
  76. EXPECT_FLOAT_EQ(positions[0].x(), center.x());
  77. EXPECT_FLOAT_EQ(positions[0].y(), center.y());
  78. EXPECT_FLOAT_EQ(positions[0].z(), center.z());
  79. }
  80. TEST_F(FormationSystemTest, FormationsScaleWithUnitCount) {
  81. QVector3D center(0.0F, 0.0F, 0.0F);
  82. float spacing = 2.0F;
  83. auto small_formation = FormationSystem::instance().get_formation_positions(
  84. FormationType::Roman, 4, center, spacing);
  85. auto large_formation = FormationSystem::instance().get_formation_positions(
  86. FormationType::Roman, 16, center, spacing);
  87. EXPECT_EQ(small_formation.size(), 4);
  88. EXPECT_EQ(large_formation.size(), 16);
  89. // Larger formations should spread wider
  90. float small_max_dist = 0.0F;
  91. float large_max_dist = 0.0F;
  92. for (const auto &pos : small_formation) {
  93. QVector3D vec = pos - center;
  94. small_max_dist = std::max(small_max_dist, vec.length());
  95. }
  96. for (const auto &pos : large_formation) {
  97. QVector3D vec = pos - center;
  98. large_max_dist = std::max(large_max_dist, vec.length());
  99. }
  100. EXPECT_GT(large_max_dist, small_max_dist);
  101. }