From e6029eb1c480a8d4d55ed81fa20da9145c6064d9 Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Mon, 3 Feb 2025 00:17:16 +0100
Subject: [PATCH 01/12] Setup player class

---
 src/game/Player.cpp | 23 +++++++++++++++++++++++
 src/game/Player.hpp | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)
 create mode 100644 src/game/Player.cpp
 create mode 100644 src/game/Player.hpp

diff --git a/src/game/Player.cpp b/src/game/Player.cpp
new file mode 100644
index 0000000..8e6edf6
--- /dev/null
+++ b/src/game/Player.cpp
@@ -0,0 +1,23 @@
+#include "Player.hpp"
+
+namespace advanced_wars
+{
+
+Player::Player() {}
+
+Player::~Player() {}
+
+void Player::startTurn()
+{
+    // TODO reset availability of all allied units (all others are unavailable)
+    // TODO add calculated money to this player
+    // TODO set this player as the current active player
+}
+
+void Player::endTurn()
+{
+    // TODO set all allied units as unavailable
+    // TODO set this player as inactive
+}
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/game/Player.hpp b/src/game/Player.hpp
new file mode 100644
index 0000000..dafdcb7
--- /dev/null
+++ b/src/game/Player.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "Unit.hpp"
+
+namespace advanced_wars
+{
+
+enum class PlayerFaction
+{
+    RED,
+    BLUE,
+    GREEN,
+    YELLOW,
+    PURPLE
+};
+
+class Player
+{
+    private:
+        int           money;
+        bool          alive;
+        bool          activeTurn;
+        PlayerFaction faction;
+
+    public:
+        Player(/* args */);
+        ~Player();
+
+        void startTurn();
+        void endTurn();
+};
+
+} // namespace advanced_wars
-- 
GitLab


From 7274b1d43e8fea598d7ccdd0d7f0b296dd4c9f99 Mon Sep 17 00:00:00 2001
From: Frederik Keens <frederik@prasch.de>
Date: Mon, 3 Feb 2025 14:14:09 +0100
Subject: [PATCH 02/12] Add getter and setter for relevant data to Player

---
 src/game/Building.cpp |  5 +++++
 src/game/Building.hpp |  2 ++
 src/game/Unit.cpp     | 10 ++++++++++
 src/game/Unit.hpp     |  4 ++++
 4 files changed, 21 insertions(+)

diff --git a/src/game/Building.cpp b/src/game/Building.cpp
index efa12b6..4cbbec8 100644
--- a/src/game/Building.cpp
+++ b/src/game/Building.cpp
@@ -28,4 +28,9 @@ void Building::render(Engine& engine, int scale)
         &dst, 0, NULL, SDL_FLIP_NONE);
 }
 
+BuildingFaction Building::getFaction()
+{
+    return this->m_faction;
+}
+
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/game/Building.hpp b/src/game/Building.hpp
index 031c315..429e024 100644
--- a/src/game/Building.hpp
+++ b/src/game/Building.hpp
@@ -36,6 +36,8 @@ class Building
         BuildingFaction m_faction;
 
         void render(Engine& engine, int scale);
+
+        BuildingFaction getFaction();
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 657f24c..b85ccb8 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -216,4 +216,14 @@ bool Unit::inRange(Unit& enemy)
     return false;
 }
 
+UnitFaction Unit::getFaction()
+{
+    return this->m_faction;
+}
+
+void Unit::setState(UnitState state)
+{
+    this->m_state = state;
+}
+
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/game/Unit.hpp b/src/game/Unit.hpp
index 544c3d9..285ac13 100644
--- a/src/game/Unit.hpp
+++ b/src/game/Unit.hpp
@@ -116,6 +116,10 @@ class Unit
         */
         void on_left_click(SDL_Event event);
 
+        UnitFaction getFaction();
+
+        void setState(UnitState state);
+
     private:
         UnitFaction m_faction;
         UnitId      m_id;
-- 
GitLab


From 6a6442bf638dc0e6bfb6581243807c6e51f07863 Mon Sep 17 00:00:00 2001
From: Frederik Keens <frederik@prasch.de>
Date: Mon, 3 Feb 2025 14:31:44 +0100
Subject: [PATCH 03/12] Implement player class

---
 src/game/Player.cpp | 136 +++++++++++++++++++++++++++++++++++++++++---
 src/game/Player.hpp |  29 ++++++++--
 2 files changed, 151 insertions(+), 14 deletions(-)

diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 8e6edf6..92584f7 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -7,17 +7,137 @@ Player::Player() {}
 
 Player::~Player() {}
 
-void Player::startTurn()
+void Player::startTurn(
+    std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings)
 {
-    // TODO reset availability of all allied units (all others are unavailable)
-    // TODO add calculated money to this player
-    // TODO set this player as the current active player
+    for (auto& [id, unit] : lvUnits)
+    {
+        switch (m_faction)
+        {
+        case PlayerFaction::RED:
+            if (unit.getFaction() == UnitFaction::URED)
+            {
+                unit.setState(UnitState::IDLE);
+            }
+            break;
+        case PlayerFaction::BLUE:
+            if (unit.getFaction() == UnitFaction::UBLUE)
+            {
+                unit.setState(UnitState::IDLE);
+            }
+            break;
+        case PlayerFaction::GREEN:
+            if (unit.getFaction() == UnitFaction::UGREEN)
+            {
+                unit.setState(UnitState::IDLE);
+            }
+            break;
+        case PlayerFaction::YELLOW:
+            if (unit.getFaction() == UnitFaction::UYELLOW)
+            {
+                unit.setState(UnitState::IDLE);
+            }
+            break;
+        case PlayerFaction::PURPLE:
+            if (unit.getFaction() == UnitFaction::UPURPLE)
+            {
+                unit.setState(UnitState::IDLE);
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    int underControl = 0;
+
+    for (auto& [id, building] : lvBuildings)
+    {
+        switch (m_faction)
+        {
+        case PlayerFaction::RED:
+            if (building.getFaction() == BuildingFaction::RED)
+            {
+                underControl++;
+            }
+            break;
+        case PlayerFaction::BLUE:
+            if (building.getFaction() == BuildingFaction::BLUE)
+            {
+                underControl++;
+            }
+            break;
+        case PlayerFaction::GREEN:
+            if (building.getFaction() == BuildingFaction::GREEN)
+            {
+                underControl++;
+            }
+            break;
+        case PlayerFaction::YELLOW:
+            if (building.getFaction() == BuildingFaction::YELLOW)
+            {
+                underControl++;
+            }
+            break;
+        case PlayerFaction::PURPLE:
+            if (building.getFaction() == BuildingFaction::PURPLE)
+            {
+                underControl++;
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    m_money += 1000 * underControl;
+
+    m_activeTurn = true;
 }
 
-void Player::endTurn()
+void Player::endTurn(std::unordered_map<int, Unit> lvUnits)
 {
-    // TODO set all allied units as unavailable
-    // TODO set this player as inactive
-}
+    for (auto& [id, unit] : lvUnits)
+    {
+        switch (m_faction)
+        {
+        case PlayerFaction::RED:
+            if (unit.getFaction() == UnitFaction::URED)
+            {
+                unit.setState(UnitState::UNAVAILABLE);
+            }
+            break;
+        case PlayerFaction::BLUE:
+            if (unit.getFaction() == UnitFaction::UBLUE)
+            {
+                unit.setState(UnitState::UNAVAILABLE);
+            }
+            break;
+        case PlayerFaction::GREEN:
+            if (unit.getFaction() == UnitFaction::UGREEN)
+            {
+                unit.setState(UnitState::UNAVAILABLE);
+            }
+            break;
+        case PlayerFaction::YELLOW:
+            if (unit.getFaction() == UnitFaction::UYELLOW)
+            {
+                unit.setState(UnitState::UNAVAILABLE);
+            }
+            break;
+        case PlayerFaction::PURPLE:
+            if (unit.getFaction() == UnitFaction::UPURPLE)
+            {
+                unit.setState(UnitState::UNAVAILABLE);
+            }
+            break;
 
+        default:
+            break;
+        }
+    }
+    m_activeTurn = false;
+}
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/game/Player.hpp b/src/game/Player.hpp
index dafdcb7..27f6921 100644
--- a/src/game/Player.hpp
+++ b/src/game/Player.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
+#include "Building.hpp"
 #include "Unit.hpp"
+#include <unordered_map>
 
 namespace advanced_wars
 {
@@ -17,17 +19,32 @@ enum class PlayerFaction
 class Player
 {
     private:
-        int           money;
-        bool          alive;
-        bool          activeTurn;
-        PlayerFaction faction;
+        int           m_money;
+        bool          m_alive;
+        bool          m_activeTurn;
+        PlayerFaction m_faction;
 
     public:
         Player(/* args */);
         ~Player();
 
-        void startTurn();
-        void endTurn();
+        /**
+         * Sets all units of the players faction to idle, adds money for each building under the
+         * players control and sets them as the active player.
+         *
+         * @param lvUnits All current units of a level
+         * @param lvBuildings All buildings of a level
+         */
+        void startTurn(
+            std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings);
+
+        /**
+         * Sets all units of the players faction to unavailable and sets them as no longer being the
+         * active player.
+         *
+         * @param lvUnits All current units of a level
+         */
+        void endTurn(std::unordered_map<int, Unit> lvUnits);
 };
 
 } // namespace advanced_wars
-- 
GitLab


From 5207e5adc295eb98c1c9dd923c370a589a03de96 Mon Sep 17 00:00:00 2001
From: Frederik Keens <frederik@prasch.de>
Date: Mon, 3 Feb 2025 14:34:34 +0100
Subject: [PATCH 04/12] Implement player turn queue and a change turn function

---
 src/game/Level.cpp | 12 ++++++++++++
 src/game/Level.hpp |  5 +++++
 2 files changed, 17 insertions(+)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index 67e35e5..01f1e31 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -380,4 +380,16 @@ Effect Level::removeEffect(int id)
     return value;
 }
 
+void Level::changeTurn()
+{
+    Player temp = m_turnQ.front();
+
+    temp.endTurn(m_units);
+
+    // Cycle Player at end of queue
+    m_turnQ.pop();
+    m_turnQ.push(temp);
+
+    m_turnQ.front().startTurn(m_units, m_buildings);
+}
 } // namespace advanced_wars
diff --git a/src/game/Level.hpp b/src/game/Level.hpp
index 49c076f..de691c5 100644
--- a/src/game/Level.hpp
+++ b/src/game/Level.hpp
@@ -3,11 +3,13 @@
 #include "Building.hpp"
 #include "Effect.hpp"
 #include "Engine.hpp"
+#include "Player.hpp"
 #include "Scene.hpp"
 #include "Tile.hpp"
 #include "Unit.hpp"
 #include "ui/Contextmenu.hpp"
 #include <SDL.h>
+#include <queue>
 #include <string>
 #include <unordered_map>
 #include <vector>
@@ -52,6 +54,7 @@ class Level : public Scene
         std::unordered_map<int, Building> m_buildings;
         std::unordered_map<int, Unit>     m_units;
         std::unordered_map<int, Effect>   m_effects;
+        std::queue<Player>                m_turnQ;
 
         int m_selectedUnit;
         int m_targetedUnit;
@@ -68,6 +71,8 @@ class Level : public Scene
 
         bool clickCheckLeft(int mouseX, int mouseY);
         bool clickCheckRight(int mouseX, int mouseY);
+
+        void changeTurn();
 };
 
 } // namespace advanced_wars
-- 
GitLab


From 121307a45c54d527d1373fadb7748e2478ccb98d Mon Sep 17 00:00:00 2001
From: TheUltimateOptimist <digitalConfidence@web.de>
Date: Mon, 3 Feb 2025 23:50:45 +0100
Subject: [PATCH 05/12] switched green and yellow around to match order of
 building faction enum

---
 src/game/Player.cpp | 26 +++++++++++++-------------
 src/game/Player.hpp |  2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 92584f7..069f00d 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -26,14 +26,14 @@ void Player::startTurn(
                 unit.setState(UnitState::IDLE);
             }
             break;
-        case PlayerFaction::GREEN:
-            if (unit.getFaction() == UnitFaction::UGREEN)
+        case PlayerFaction::YELLOW:
+            if (unit.getFaction() == UnitFaction::UYELLOW)
             {
                 unit.setState(UnitState::IDLE);
             }
             break;
-        case PlayerFaction::YELLOW:
-            if (unit.getFaction() == UnitFaction::UYELLOW)
+        case PlayerFaction::GREEN:
+            if (unit.getFaction() == UnitFaction::UGREEN)
             {
                 unit.setState(UnitState::IDLE);
             }
@@ -68,14 +68,14 @@ void Player::startTurn(
                 underControl++;
             }
             break;
-        case PlayerFaction::GREEN:
-            if (building.getFaction() == BuildingFaction::GREEN)
+        case PlayerFaction::YELLOW:
+            if (building.getFaction() == BuildingFaction::YELLOW)
             {
                 underControl++;
             }
-            break;
-        case PlayerFaction::YELLOW:
-            if (building.getFaction() == BuildingFaction::YELLOW)
+            break; 
+        case PlayerFaction::GREEN:
+            if (building.getFaction() == BuildingFaction::GREEN)
             {
                 underControl++;
             }
@@ -115,14 +115,14 @@ void Player::endTurn(std::unordered_map<int, Unit> lvUnits)
                 unit.setState(UnitState::UNAVAILABLE);
             }
             break;
-        case PlayerFaction::GREEN:
-            if (unit.getFaction() == UnitFaction::UGREEN)
+        case PlayerFaction::YELLOW:
+            if (unit.getFaction() == UnitFaction::UYELLOW)
             {
                 unit.setState(UnitState::UNAVAILABLE);
             }
             break;
-        case PlayerFaction::YELLOW:
-            if (unit.getFaction() == UnitFaction::UYELLOW)
+        case PlayerFaction::GREEN:
+            if (unit.getFaction() == UnitFaction::UGREEN)
             {
                 unit.setState(UnitState::UNAVAILABLE);
             }
diff --git a/src/game/Player.hpp b/src/game/Player.hpp
index 27f6921..0dd5223 100644
--- a/src/game/Player.hpp
+++ b/src/game/Player.hpp
@@ -11,8 +11,8 @@ enum class PlayerFaction
 {
     RED,
     BLUE,
-    GREEN,
     YELLOW,
+    GREEN,
     PURPLE
 };
 
-- 
GitLab


From bb099e4ade147abe287f6404144f73ee2dd6a996 Mon Sep 17 00:00:00 2001
From: TheUltimateOptimist <digitalConfidence@web.de>
Date: Tue, 4 Feb 2025 00:46:28 +0100
Subject: [PATCH 06/12] enabled creation of turnQ in loadLevel function

---
 src/game/Level.cpp   | 28 ++++++++++++++++++++++------
 src/game/Level.hpp   |  5 +++--
 src/game/Player.cpp  |  5 +++--
 src/game/Player.hpp  |  2 +-
 src/game/ui/Menu.cpp | 13 +++++++------
 5 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index 01f1e31..70eb70c 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -21,9 +21,10 @@ const int RENDERING_SCALE = 3;
 
 Level::Level(
     std::string name, int width, int height, std::vector<Tile> tiles,
-    std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects)
-    : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_contextMenu(ContextMenu()),
-      m_contextMenuActive(false), m_id(0)
+    std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects,
+    std::queue<Player> turnQ)
+    : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_turnQ(turnQ),
+      m_contextMenu(ContextMenu()), m_contextMenuActive(false), m_id(0)
 {
 
     m_contextMenu.setOptions({"Move", "Info", "Wait"});
@@ -49,7 +50,7 @@ Level::Level(
     }
 };
 
-Level Level::loadLevel(std::string path)
+std::shared_ptr<Level> Level::loadLevel(std::string path)
 {
     HighFive::File file(path, HighFive::File::ReadOnly);
 
@@ -73,6 +74,7 @@ Level Level::loadLevel(std::string path)
     std::vector<Tile>     tiles;
     std::vector<Building> buildings;
     tiles.reserve(width * height);
+    bool has_factions[] = {false, false, false, false, false};
     for (int i = 0; i < level_tilesarray.size(); i++)
     {
         int x = i % width;
@@ -83,6 +85,10 @@ Level Level::loadLevel(std::string path)
             BuildingId      building_id = static_cast<BuildingId>((level_tilesarray[i] - 50) % 5);
             BuildingFaction faction_id =
                 static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5);
+            if (building_id == BuildingId::HEADQUARTER)
+            {
+                has_factions[static_cast<int>(faction_id)] = true;
+            }
             buildings.push_back(Building(x, y, building_id, faction_id));
         }
         else
@@ -92,7 +98,18 @@ Level Level::loadLevel(std::string path)
         }
     }
 
-    return Level(name, width, height, tiles, buildings, {}, {});
+    // create turnQ from has_factions array
+    std::queue<Player> turnQ;
+    for (int i = 0; i < 5; i++)
+    {
+        if (has_factions[i])
+        {
+            turnQ.push(Player(2000, static_cast<PlayerFaction>(i)));
+        }
+    }
+
+    return std::make_shared<Level>(
+        name, width, height, tiles, buildings, std::vector<Unit>{}, std::vector<Effect>{}, turnQ);
 };
 
 bool Level::clickCheckLeft(int tileX, int tileY)
@@ -279,7 +296,6 @@ void Level::handleEvent(Engine& engine, SDL_Event& event)
 
 void Level::render(Engine& engine)
 {
-
     // Iterate over all events
     while (!engine.events().empty())
     {
diff --git a/src/game/Level.hpp b/src/game/Level.hpp
index de691c5..979233d 100644
--- a/src/game/Level.hpp
+++ b/src/game/Level.hpp
@@ -25,9 +25,10 @@ class Level : public Scene
     public:
         Level(
             std::string name, int width, int height, std::vector<Tile> tiles,
-            std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect>);
+            std::vector<Building> buildings, std::vector<Unit> units, 
+            std::vector<Effect> effects, std::queue<Player> turnQ);
 
-        static Level loadLevel(std::string path);
+        static std::shared_ptr<Level> loadLevel(std::string path);
 
         void render(Engine& engine);
 
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 069f00d..d521a78 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -1,9 +1,10 @@
 #include "Player.hpp"
+#include <iostream>
 
 namespace advanced_wars
 {
 
-Player::Player() {}
+Player::Player(int money, PlayerFaction faction) : m_money(money), m_faction(faction) {}
 
 Player::~Player() {}
 
@@ -73,7 +74,7 @@ void Player::startTurn(
             {
                 underControl++;
             }
-            break; 
+            break;
         case PlayerFaction::GREEN:
             if (building.getFaction() == BuildingFaction::GREEN)
             {
diff --git a/src/game/Player.hpp b/src/game/Player.hpp
index 0dd5223..06f50d7 100644
--- a/src/game/Player.hpp
+++ b/src/game/Player.hpp
@@ -25,7 +25,7 @@ class Player
         PlayerFaction m_faction;
 
     public:
-        Player(/* args */);
+        Player(int money, PlayerFaction faction);
         ~Player();
 
         /**
diff --git a/src/game/ui/Menu.cpp b/src/game/ui/Menu.cpp
index 392209b..62e6c02 100644
--- a/src/game/ui/Menu.cpp
+++ b/src/game/ui/Menu.cpp
@@ -71,7 +71,7 @@ void Menu::render(Engine& engine)
     {
         SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface);
         SDL_Rect     titleRect = {
-            static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h};
+                static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h};
         SDL_RenderCopy(engine.renderer(), titleTexture, nullptr, &titleRect);
         SDL_DestroyTexture(titleTexture);
         SDL_FreeSurface(titleSurface);
@@ -88,8 +88,8 @@ void Menu::render(Engine& engine)
 
         SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface);
         SDL_Rect     textRect = {
-            static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50),
-            textSurface->w, textSurface->h};
+                static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50),
+                textSurface->w, textSurface->h};
         SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect);
 
         SDL_DestroyTexture(textTexture);
@@ -197,10 +197,11 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event)
                      Effect(5, 15, EffectId::AIR_EXPLOSION, true),
                      Effect(5, 18, EffectId::NAVAL_EXPLOSION, true)});
 
-                std::shared_ptr<Level> level =
-                    std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units, effects);
+                // std::shared_ptr<Level> level =
+                //     std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units,
+                //     effects, std::queue<Player>{});
 
-                engine.pushScene(level);
+                engine.pushScene(Level::loadLevel("../res/level.h5"));
             }
             else if (m_options[m_selectedOption] == "Options")
             {
-- 
GitLab


From f0d7034418dcf1f64058cf35c59043d07a91221f Mon Sep 17 00:00:00 2001
From: TheUltimateOptimist <digitalConfidence@web.de>
Date: Tue, 4 Feb 2025 18:53:29 +0100
Subject: [PATCH 07/12] every headquarter receives infantery at start

---
 src/game/Level.cpp | 12 ++++++++++--
 src/game/Unit.hpp  |  2 +-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index 70eb70c..e9293b8 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -70,9 +70,10 @@ std::shared_ptr<Level> Level::loadLevel(std::string path)
     int         height = pt.get<int>("level.height");
     std::string name = pt.get<std::string>("level.name");
 
-    // create tiles and buildings vector from tiles array
+    // create tiles, buildings and units vector from tiles array
     std::vector<Tile>     tiles;
     std::vector<Building> buildings;
+    std::vector<Unit>     units;
     tiles.reserve(width * height);
     bool has_factions[] = {false, false, false, false, false};
     for (int i = 0; i < level_tilesarray.size(); i++)
@@ -87,6 +88,13 @@ std::shared_ptr<Level> Level::loadLevel(std::string path)
                 static_cast<BuildingFaction>((level_tilesarray[i] - 50) / 5);
             if (building_id == BuildingId::HEADQUARTER)
             {
+                int index = static_cast<int>(faction_id);
+                if (!has_factions[index])
+                {
+                    units.push_back(Unit(
+                        x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY,
+                        UnitState::IDLE));
+                }
                 has_factions[static_cast<int>(faction_id)] = true;
             }
             buildings.push_back(Building(x, y, building_id, faction_id));
@@ -109,7 +117,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path)
     }
 
     return std::make_shared<Level>(
-        name, width, height, tiles, buildings, std::vector<Unit>{}, std::vector<Effect>{}, turnQ);
+        name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ);
 };
 
 bool Level::clickCheckLeft(int tileX, int tileY)
diff --git a/src/game/Unit.hpp b/src/game/Unit.hpp
index 285ac13..707e157 100644
--- a/src/game/Unit.hpp
+++ b/src/game/Unit.hpp
@@ -12,8 +12,8 @@ enum class UnitFaction
 {
     URED = 0,
     UBLUE = 1,
-    UGREEN = 2,
     UYELLOW = 3,
+    UGREEN = 2,
     UPURPLE = 4,
 };
 
-- 
GitLab


From fccb56ed521aff32ed1bd5c7cb71e79eb582c8da Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Thu, 6 Feb 2025 02:42:11 +0100
Subject: [PATCH 08/12] Add the proper test Level to test more gameplay

---
 res/level.h5 | Bin 0 -> 6310 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 res/level.h5

diff --git a/res/level.h5 b/res/level.h5
new file mode 100644
index 0000000000000000000000000000000000000000..aa5ba5b60aae9dc4927a4e818e5bb480796ee5a0
GIT binary patch
literal 6310
zcmeD5aB<`1lHy_j0S*oZ76t(j3y%Lo!7>Sm5S05L!ed}afHD}NbO)4P!31G2GJqfh
z15`VMAk=(xbs<5nt_%!}3^4OyG{h7J1_Krd3uX?4H%g9_5b$ty3;_8x0z@z{Fla#O
z6VP-9<uc@^mL#SmmL$UXC7C&?#fe2liIor$SUNR;a0!x(3~UTwJzxTqLOH;Cpj-xK
z1_`jdBqJj@WrK1LL=K{km4O2+&%^|#7&xFgftis3q5!N5Y$TWvf(nDoXtth_&cFc6
zDPZXVCxZR_T^Jddpsr+KP+-RIBv^i}V8yR)q{(8YD@aH&GJ;~BfngdnKwva8g8(=I
z;Z9#nV2z0MB>*uHZW6>m%=Fa&kr*XMWC-LiFfa%}OCnGLa(DLk0nxBx3Cw0-U;wED
z1(1z>MQ)BlS!z*nW`3TnlA)e~l0s@;a(+r?Ub?MPX-S%{g_6A;mrYJ;S!#}*O?hTY
zNrs)Fsf|8_Ws{MbnVwN%XJ}xf4`tfqCFZ8uIp!2(B--eM**5wR-5~p5xPTwV8l^`=
zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1SkywCT3=4CMFQc4DR|ffyVck
znVFdxpabwA3z(Tf1ECDyp;sRtV~`R?29O{~l7X3l!IF`gfx(D@fx*WY#08C9nS<pR
iz{)_fP%Z;AGc!mp6I?sUBC!1o%uGzoOw5eTOiTdvhGZfD

literal 0
HcmV?d00001

-- 
GitLab


From fe879173d854c3cd572a4536d8a9eca048693e9d Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Thu, 6 Feb 2025 02:42:38 +0100
Subject: [PATCH 09/12] Fix tilemarker not reaching leftmost tile

---
 src/game/ui/TileMarker.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/game/ui/TileMarker.cpp b/src/game/ui/TileMarker.cpp
index cfffcc6..1ad9d6a 100644
--- a/src/game/ui/TileMarker.cpp
+++ b/src/game/ui/TileMarker.cpp
@@ -62,7 +62,7 @@ void TileMarker::handleEvent(Engine& engine, SDL_Event& event)
             newX = m_x - 16 * m_renderingScale;
             std::cout << "New X: " << newX << std::endl;
 
-            if (newX <= 0)
+            if (newX < 0)
             {
                 break;
             }
@@ -82,7 +82,8 @@ std::pair<int, int> TileMarker::getPosition()
     return {tileX, tileY};
 }
 
-void TileMarker::setPosition(int tileX, int tileY){
+void TileMarker::setPosition(int tileX, int tileY)
+{
     m_x = tileX * 16 * m_renderingScale;
     m_y = tileY * 16 * m_renderingScale + (16 * m_renderingScale - m_height);
 }
-- 
GitLab


From 03e2d6bd2e1bcc59f9493a9141c410045016f69d Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Thu, 6 Feb 2025 02:43:10 +0100
Subject: [PATCH 10/12] Fix stuff broken by merge

---
 src/game/Level.cpp   |  8 ++++----
 src/game/Level.hpp   | 20 ++++++++++----------
 src/game/Player.cpp  | 10 +++++-----
 src/game/Unit.cpp    | 16 +++-------------
 src/game/ui/Menu.cpp | 11 +++++------
 5 files changed, 27 insertions(+), 38 deletions(-)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index a41458d..eebaf33 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -23,12 +23,12 @@ const int RENDERING_SCALE = 3;
 
 Level::Level(
     std::string name, int width, int height, std::vector<Tile> tiles,
-    std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects
+    std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects,
     std::queue<Player> turnQ)
     : m_name(name), m_width(width), m_height(height), m_tiles(tiles), m_selectedUnit(-1),
       m_selectedBuilding(-1), m_contextMenu(ContextMenu()), m_id(0),
       m_state(LevelState::SELECTING_STATE),
-      m_currentPos(TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height), m_turnQ(turnQ))
+      m_currentPos(TileMarker(RENDERING_SCALE, 1, 1, m_width, m_height)), m_turnQ(turnQ)
 {
 
     m_contextMenu.setOptions({"Move", "Info", "Wait"});
@@ -57,7 +57,7 @@ Level::Level(
     m_selectedUnit = -1;
 };
 
-std::shared_ptr<Level> Level::loadLevel(std::string path)
+std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine)
 {
     HighFive::File file(path, HighFive::File::ReadOnly);
 
@@ -100,7 +100,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path)
                 {
                     units.push_back(Unit(
                         x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY,
-                        UnitState::IDLE));
+                        UnitState::IDLE, engine.getUnitConfig()));
                 }
                 has_factions[static_cast<int>(faction_id)] = true;
             }
diff --git a/src/game/Level.hpp b/src/game/Level.hpp
index 909223c..6e2aeea 100644
--- a/src/game/Level.hpp
+++ b/src/game/Level.hpp
@@ -11,8 +11,8 @@
 #include "ui/Recruitingmenu.hpp"
 #include "ui/TileMarker.hpp"
 #include <SDL.h>
-#include <queue>
 #include <array>
+#include <queue>
 #include <string>
 #include <unordered_map>
 #include <unordered_set>
@@ -77,10 +77,10 @@ class Level : public Scene
     public:
         Level(
             std::string name, int width, int height, std::vector<Tile> tiles,
-            std::vector<Building> buildings, std::vector<Unit> units, 
-            std::vector<Effect> effects, std::queue<Player> turnQ);
+            std::vector<Building> buildings, std::vector<Unit> units, std::vector<Effect> effects,
+            std::queue<Player> turnQ);
 
-        static std::shared_ptr<Level> loadLevel(std::string path);
+        static std::shared_ptr<Level> loadLevel(std::string path, Engine& engine);
 
         void render(Engine& engine);
 
@@ -131,12 +131,12 @@ class Level : public Scene
         std::unordered_map<int, Effect>   m_effects;
         std::queue<Player>                m_turnQ;
 
-        int                               m_selectedUnit;
-        int                               m_selectedBuilding;
-        ContextMenu                       m_contextMenu;
-        RecruitingMenu                    m_recruitingMenu;
-        int                               m_id;
-        LevelState                        m_state;
+        int            m_selectedUnit;
+        int            m_selectedBuilding;
+        ContextMenu    m_contextMenu;
+        RecruitingMenu m_recruitingMenu;
+        int            m_id;
+        LevelState     m_state;
 
         std::pair<int, int> calcTilePos(int mouseX, int mouseY);
         void                selectEntity(int x, int y);
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index d521a78..ee8a248 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -58,31 +58,31 @@ void Player::startTurn(
         switch (m_faction)
         {
         case PlayerFaction::RED:
-            if (building.getFaction() == BuildingFaction::RED)
+            if (building.getFaction() == BuildingFaction::URED)
             {
                 underControl++;
             }
             break;
         case PlayerFaction::BLUE:
-            if (building.getFaction() == BuildingFaction::BLUE)
+            if (building.getFaction() == BuildingFaction::UBLUE)
             {
                 underControl++;
             }
             break;
         case PlayerFaction::YELLOW:
-            if (building.getFaction() == BuildingFaction::YELLOW)
+            if (building.getFaction() == BuildingFaction::UYELLOW)
             {
                 underControl++;
             }
             break;
         case PlayerFaction::GREEN:
-            if (building.getFaction() == BuildingFaction::GREEN)
+            if (building.getFaction() == BuildingFaction::UGREEN)
             {
                 underControl++;
             }
             break;
         case PlayerFaction::PURPLE:
-            if (building.getFaction() == BuildingFaction::PURPLE)
+            if (building.getFaction() == BuildingFaction::UPURPLE)
             {
                 underControl++;
             }
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 9797603..f5d85a3 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -42,8 +42,6 @@ Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state, Config
     m_secondaryWeapon = Weapon(config.getUnitSecondaryWeapon(id), secondaryDamage);
 }
 
- 
-
 void Unit::render(Engine& engine, int scale)
 {
     Spritesheet* spritesheet = engine.getSpritesheet();
@@ -149,9 +147,9 @@ void Unit::attack(Unit& enemy)
 int Unit::calculateDamage(Unit& target)
 {
     // Pointers to Weapon objects
-    Weapon* primaryWeapon =  &m_primaryWeapon;
+    Weapon* primaryWeapon = &m_primaryWeapon;
     Weapon* secondaryWeapon = &m_secondaryWeapon;
-    
+
     // Find the corresponding damage values
     auto primary_damage_it = primaryWeapon->m_damage.find(target.m_id);
     auto secondary_damage_it = secondaryWeapon->m_damage.find(target.m_id);
@@ -181,8 +179,6 @@ int Unit::calculateDamage(Unit& target)
     return damage_value;
 }
 
-
-
 void Unit::performAttack(Unit& target, int damage)
 {
     int effective_damage = damage * (static_cast<float>(m_health) / m_maxHealth);
@@ -244,7 +240,7 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un
     std::vector<Unit*> unitsInRangeWithDamage;
 
     for (Unit* unit : allUnits)
-    { //Iterate over all units
+    { // Iterate over all units
         // except itself
         if (unit == this)
         {
@@ -254,7 +250,6 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un
         int distanceX = std::abs(unit->m_x - m_x);
         int distanceY = std::abs(unit->m_y - m_y);
 
-        
         int distance = distanceX + distanceY;
         if (distance >= m_minRange && distance <= m_maxRange)
         {
@@ -285,11 +280,6 @@ std::vector<Unit*> Unit::getUnitsInRangeWithDamagePotential(const std::vector<Un
     return unitsInRangeWithDamage;
 }
 
-UnitFaction Unit::getFaction()
-{
-    return this->m_faction;
-}
-
 void Unit::renderHP(Engine& engine, int scale)
 {
     Spritesheet* spritesheet = engine.getSpritesheet();
diff --git a/src/game/ui/Menu.cpp b/src/game/ui/Menu.cpp
index d2e5891..770a153 100644
--- a/src/game/ui/Menu.cpp
+++ b/src/game/ui/Menu.cpp
@@ -1,7 +1,7 @@
 #include "Menu.hpp"
 #include "../Building.hpp"
-#include "../Level.hpp"
 #include "../Config.hpp"
+#include "../Level.hpp"
 #include "../Spritesheet.hpp"
 #include "../Tile.hpp"
 #include "../Unit.hpp"
@@ -72,7 +72,7 @@ void Menu::render(Engine& engine)
     {
         SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine.renderer(), titleSurface);
         SDL_Rect     titleRect = {
-                static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h};
+            static_cast<int>((800 - titleSurface->w) / 2), 50, titleSurface->w, titleSurface->h};
         SDL_RenderCopy(engine.renderer(), titleTexture, nullptr, &titleRect);
         SDL_DestroyTexture(titleTexture);
         SDL_FreeSurface(titleSurface);
@@ -89,8 +89,8 @@ void Menu::render(Engine& engine)
 
         SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine.renderer(), textSurface);
         SDL_Rect     textRect = {
-                static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50),
-                textSurface->w, textSurface->h};
+            static_cast<int>((800 - textSurface->w) / 2), static_cast<int>(150 + i * 50),
+            textSurface->w, textSurface->h};
         SDL_RenderCopy(engine.renderer(), textTexture, nullptr, &textRect);
 
         SDL_DestroyTexture(textTexture);
@@ -126,7 +126,6 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event)
             {
                 std::cout << "Starting game..." << std::endl;
 
-
                 // Construct a level
                 std::vector<Tile> tiles;
                 for (int y = 0; y < 20; y++)
@@ -203,7 +202,7 @@ void Menu::handleEvent(Engine& engine, SDL_Event& event)
                 //     std::make_shared<Level>("Osnabrück", 20, 20, tiles, buildings, units,
                 //     effects, std::queue<Player>{});
 
-                engine.pushScene(Level::loadLevel("../res/level.h5"));
+                engine.pushScene(Level::loadLevel("../res/level.h5", engine));
             }
             else if (m_options[m_selectedOption] == "Options")
             {
-- 
GitLab


From a048952d54803cb2c20ef16c447be87b617395ee Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Thu, 6 Feb 2025 03:40:29 +0100
Subject: [PATCH 11/12] Fix Bug with start and end turn and start the first
 turn immeadiatly after loading

---
 src/game/Level.cpp  | 8 +++++---
 src/game/Player.cpp | 9 ++++++---
 src/game/Player.hpp | 4 ++--
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index eebaf33..15318c5 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -123,9 +123,11 @@ std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine)
         }
     }
 
-    return std::make_shared<Level>(
-        name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ);
-};
+    Level level(name, width, height, tiles, buildings, units, std::vector<Effect>{}, turnQ);
+
+    level.m_turnQ.front().startTurn(level.m_units, level.m_buildings);
+    return std::make_shared<Level>(level);
+}
 
 std::pair<int, int> Level::calcTilePos(int mouseX, int mouseY)
 {
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index ee8a248..9bd7bad 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -4,12 +4,15 @@
 namespace advanced_wars
 {
 
-Player::Player(int money, PlayerFaction faction) : m_money(money), m_faction(faction) {}
+Player::Player(int money, PlayerFaction faction)
+    : m_money(money), m_alive(true), m_activeTurn(false), m_faction(faction)
+{
+}
 
 Player::~Player() {}
 
 void Player::startTurn(
-    std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings)
+    std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings)
 {
     for (auto& [id, unit] : lvUnits)
     {
@@ -98,7 +101,7 @@ void Player::startTurn(
     m_activeTurn = true;
 }
 
-void Player::endTurn(std::unordered_map<int, Unit> lvUnits)
+void Player::endTurn(std::unordered_map<int, Unit>& lvUnits)
 {
     for (auto& [id, unit] : lvUnits)
     {
diff --git a/src/game/Player.hpp b/src/game/Player.hpp
index 06f50d7..f77bb6c 100644
--- a/src/game/Player.hpp
+++ b/src/game/Player.hpp
@@ -36,7 +36,7 @@ class Player
          * @param lvBuildings All buildings of a level
          */
         void startTurn(
-            std::unordered_map<int, Unit> lvUnits, std::unordered_map<int, Building> lvBuildings);
+            std::unordered_map<int, Unit>& lvUnits, std::unordered_map<int, Building>& lvBuildings);
 
         /**
          * Sets all units of the players faction to unavailable and sets them as no longer being the
@@ -44,7 +44,7 @@ class Player
          *
          * @param lvUnits All current units of a level
          */
-        void endTurn(std::unordered_map<int, Unit> lvUnits);
+        void endTurn(std::unordered_map<int, Unit>& lvUnits);
 };
 
 } // namespace advanced_wars
-- 
GitLab


From e9f846cd2bfbfa6845ab2df21a1399267e5a8629 Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Thu, 6 Feb 2025 03:41:36 +0100
Subject: [PATCH 12/12] Fix missing config needed for unit construction and set
 starting units to spawn in unavailable state

---
 src/game/Level.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/game/Level.cpp b/src/game/Level.cpp
index 15318c5..53e8448 100644
--- a/src/game/Level.cpp
+++ b/src/game/Level.cpp
@@ -100,7 +100,7 @@ std::shared_ptr<Level> Level::loadLevel(std::string path, Engine& engine)
                 {
                     units.push_back(Unit(
                         x, y, static_cast<UnitFaction>(faction_id), UnitId::INFANTERY,
-                        UnitState::IDLE, engine.getUnitConfig()));
+                        UnitState::UNAVAILABLE, engine.getUnitConfig()));
                 }
                 has_factions[static_cast<int>(faction_id)] = true;
             }
-- 
GitLab