From b8b5e5d90cbb4a617d2a244757c077654a69a73e Mon Sep 17 00:00:00 2001
From: fdai7375 <david.maul@informatik.hs-fulda.de>
Date: Mon, 27 Jan 2025 01:16:02 +0100
Subject: [PATCH 01/30] experimental changes for units and weapons

---
 src/unit.hpp   | 17 +++++++++++++++++
 src/weapon.cpp |  3 +++
 src/weapon.hpp | 21 +++++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 src/weapon.cpp
 create mode 100644 src/weapon.hpp

diff --git a/src/unit.hpp b/src/unit.hpp
index 20877ba..878f925 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
 #include "engine.hpp"
+#include "weapon.hpp"
+#include <optional>
 
 namespace advanced_wars {
 
@@ -61,9 +63,24 @@ public:
 private:
   int x;
   int y;
+
   UnitFaction faction;
   UnitId id;
   UnitState state;
+
+  int health;
+  int range;
+  int fuel;
+  int max_fuel;
+
+  bool has_moved;
+  bool has_attacked;
+
+  // Primary weapon ammo
+  int ammo;
+
+  std::optional<Weapon> primary;
+  std::optional<Weapon> secondary;
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/weapon.cpp b/src/weapon.cpp
new file mode 100644
index 0000000..650e950
--- /dev/null
+++ b/src/weapon.cpp
@@ -0,0 +1,3 @@
+#include "weapon.hpp"
+
+namespace advanced_wars {}
\ No newline at end of file
diff --git a/src/weapon.hpp b/src/weapon.hpp
new file mode 100644
index 0000000..753e674
--- /dev/null
+++ b/src/weapon.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "unit.hpp"
+#include <unordered_map>
+
+namespace advanced_wars {
+
+// Forward Declaration
+enum class UnitId;
+
+class Weapon {
+public:
+  // Ranges
+  int min_range;
+  int max_range;
+
+  // Damage
+  std::unordered_map<UnitId, int> damage;
+};
+
+} // namespace advanced_wars
\ No newline at end of file
-- 
GitLab


From 21ca6c12f1191ae9ae3a6f09df0a660238e39ec2 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 13:23:50 +0100
Subject: [PATCH 02/30] Update unit.hpp with required methods

---
 src/unit.hpp | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/src/unit.hpp b/src/unit.hpp
index 878f925..31d690e 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -60,6 +60,29 @@ public:
 
   void render(Engine &engine, int scale);
 
+
+  /*
+  The attacker will move towards the defender and thus initiate combat
+  @params Takes a reference to the defender
+
+  Will Update the health for both units
+  Attacker deals damage to the defender first
+  */
+  void init_combat(Unit &defender);
+
+
+  /*
+  @params Takes the desired position of the unit and updates its values
+  */
+  void update_position(int posX, int posY);
+
+  /*
+  This function needs to be able to determine the possible movement-paths the unit can take
+  MUST take into consideration that different units behave differently on certain terrain
+  MUST show all movements possible
+  */
+  void calculate_movement();
+
 private:
   int x;
   int y;
-- 
GitLab


From de1bea635ea9f952f838650574aa63e0c8beb104 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 15:44:16 +0100
Subject: [PATCH 03/30] Add nested unordered_map for damageMatrix

---
 src/unit.hpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/unit.hpp b/src/unit.hpp
index 31d690e..bdfb037 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -54,6 +54,9 @@ enum class MovementType {
   LANDER = 5,
 };
 
+//Fill the MatchupTabel
+using MatchupTabel = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, int>>;
+
 class Unit {
 public:
   Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
@@ -68,7 +71,7 @@ public:
   Will Update the health for both units
   Attacker deals damage to the defender first
   */
-  void init_combat(Unit &defender);
+  void attack(Unit &enemy);
 
 
   /*
@@ -83,6 +86,8 @@ public:
   */
   void calculate_movement();
 
+
+
 private:
   int x;
   int y;
-- 
GitLab


From 393dc7334a73b7da969c127722e10e9fc3c4e674 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 15:49:55 +0100
Subject: [PATCH 04/30] add first rendition of combat system

---
 src/unit.cpp | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/unit.cpp b/src/unit.cpp
index cb0b87b..b5df46e 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -62,4 +62,22 @@ void Unit::render(Engine &engine, int scale) {
   }
 }
 
+//Placeholder
+MatchupTabel damageMatrix = {
+    { UnitId::INFANTRY, {{ UnitId::INFANTRY, 50 }, { UnitId::TANK, 5 }} },
+    { UnitId::TANK, {{ UnitId::INFANTRY, 90 }, { UnitId::TANK, 50 }} }
+};
+void Unit::attack(Unit &enemy) {
+
+
+    //Start Attack: choose the appropriate weapon:
+    int offDamage = damageMatrix[this->id][enemy->id] * ((this->health)/(this->max_health));
+    int defDamage = damageMatrix[this->id][enemy->id] * ((enemy->health)/(enemy->max_health));
+
+    enemy->health = enemy->health - offDamage;
+    if(enemy->health > 0) {
+        this->health = this->health - defDamage;
+    }
+}
+
 } // namespace advanced_wars
\ No newline at end of file
-- 
GitLab


From 2d37a5c81a23d49bb28c5274591cac17821ecbee Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 16:06:34 +0100
Subject: [PATCH 05/30] Add comments to signal future progress

---
 src/unit.cpp | 15 ++++++++++++---
 src/unit.hpp |  9 +++++----
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index b5df46e..983df79 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -4,7 +4,7 @@ namespace advanced_wars {
 
 Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
     : x(x), y(y), faction(faction), id(id), state(state) {
-
+        health = max_health;
       };
 
 void Unit::render(Engine &engine, int scale) {
@@ -64,11 +64,15 @@ void Unit::render(Engine &engine, int scale) {
 
 //Placeholder
 MatchupTabel damageMatrix = {
-    { UnitId::INFANTRY, {{ UnitId::INFANTRY, 50 }, { UnitId::TANK, 5 }} },
-    { UnitId::TANK, {{ UnitId::INFANTRY, 90 }, { UnitId::TANK, 50 }} }
+    { UnitId::INFANTRY, {{ UnitId::INFANTRY, 50 }, { UnitId::MEDIUM_TANK, 5 }} },
+    { UnitId::MEDIUM_TANK, {{ UnitId::INFANTRY, 90 }, { UnitId::MEDIUM_TANK, 50 }} }
 };
+
 void Unit::attack(Unit &enemy) {
 
+    //checks to be run:
+    //is unit in range?
+    //has unit not attacked this turn?
 
     //Start Attack: choose the appropriate weapon:
     int offDamage = damageMatrix[this->id][enemy->id] * ((this->health)/(this->max_health));
@@ -77,6 +81,11 @@ void Unit::attack(Unit &enemy) {
     enemy->health = enemy->health - offDamage;
     if(enemy->health > 0) {
         this->health = this->health - defDamage;
+        if(this->health <= 0) {
+            this->~Unit();
+        }
+    } else {
+        enemy->~Unit();
     }
 }
 
diff --git a/src/unit.hpp b/src/unit.hpp
index bdfb037..a980b2a 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -60,10 +60,12 @@ using MatchupTabel = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, i
 class Unit {
 public:
   Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
+  ~Unit() {
+        //Assuming that the destruktion of a unit triggers events
+    }
 
   void render(Engine &engine, int scale);
 
-
   /*
   The attacker will move towards the defender and thus initiate combat
   @params Takes a reference to the defender
@@ -86,8 +88,6 @@ public:
   */
   void calculate_movement();
 
-
-
 private:
   int x;
   int y;
@@ -96,7 +96,8 @@ private:
   UnitId id;
   UnitState state;
 
-  int health;
+  int health; //health equals max_health at construction
+  int max_health; // max_health required for damage_scaling
   int range;
   int fuel;
   int max_fuel;
-- 
GitLab


From 952853aa32f61ec193f134dfd9d567606d43aaeb Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 18:24:21 +0100
Subject: [PATCH 06/30] Add function to check for Range from allied  to enemy
 unit(s)

---
 src/unit.cpp | 18 ++++++++++++++++--
 src/unit.hpp |  8 ++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 983df79..17ea40b 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -70,9 +70,14 @@ MatchupTabel damageMatrix = {
 
 void Unit::attack(Unit &enemy) {
 
-    //checks to be run:
-    //is unit in range?
     //has unit not attacked this turn?
+    if(!inRange(Unit &enemy)) {
+        //Render enemies as not in Range
+    }
+
+    if (this->has_attacked) {
+        //display the unit as not able to attack (maybe greyscale?)
+    }
 
     //Start Attack: choose the appropriate weapon:
     int offDamage = damageMatrix[this->id][enemy->id] * ((this->health)/(this->max_health));
@@ -89,4 +94,13 @@ void Unit::attack(Unit &enemy) {
     }
 }
 
+void Unit::inRange(Unit &enemy) {
+    if (this->x == enemy.x) {
+        return abs(this->y - enemy.y) <= this->range;
+    } else if (this->y == enemy.y) {
+        return abs(this->x - enemy.x) <= this->range;
+    }
+    return false; 
+}
+
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index a980b2a..adc11e8 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -66,6 +66,14 @@ public:
 
   void render(Engine &engine, int scale);
 
+  /*
+  Check if attacker is in Range to initiate combat
+  TODO: This should probably tie back into rendering the units differently
+  If a unit is selected, it should call inRange on all other enemy units on the field
+  */
+ 
+ bool inRange(Unit &enemy);
+
   /*
   The attacker will move towards the defender and thus initiate combat
   @params Takes a reference to the defender
-- 
GitLab


From 38a8e6eaa87e3e8cbd43749b8979f86648a7b373 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 19:52:55 +0100
Subject: [PATCH 07/30] Start work on reading the XML-File for the units

---
 src/unit.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++--------
 src/unit.hpp |  7 ++++++-
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 17ea40b..6f9932c 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,4 +1,5 @@
 #include "unit.hpp"
+#include <tinyxml2.h>
 
 namespace advanced_wars {
 
@@ -62,17 +63,11 @@ void Unit::render(Engine &engine, int scale) {
   }
 }
 
-//Placeholder
-MatchupTabel damageMatrix = {
-    { UnitId::INFANTRY, {{ UnitId::INFANTRY, 50 }, { UnitId::MEDIUM_TANK, 5 }} },
-    { UnitId::MEDIUM_TANK, {{ UnitId::INFANTRY, 90 }, { UnitId::MEDIUM_TANK, 50 }} }
-};
-
 void Unit::attack(Unit &enemy) {
 
     //has unit not attacked this turn?
-    if(!inRange(Unit &enemy)) {
-        //Render enemies as not in Range
+    if(!inRange(enemy)) {
+        //Render enemies as not in Range => use the UNAVAILABLE Texture for that
     }
 
     if (this->has_attacked) {
@@ -103,4 +98,44 @@ void Unit::inRange(Unit &enemy) {
     return false; 
 }
 
+void loadXML(const char* filename) {
+
+    tinyxml2::XMLDocument doc;
+    if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS) {
+        std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
+        return;
+    }
+
+    MatchupTabel damageMatrix;
+    tinyxml2::XMLElement* unitElement = doc.FirstChildElement("Units")->FirstChildElement("Unit");
+
+    //get all Units
+    while(unitElement) {
+
+        const u_int8_t UnitId = unitElement->Attribute("id");
+
+        std::unordered_map<u_int8_t, int> attackValues;
+        tinyxml2::XMLElement* attackElement = unitElement->FirstChildElement("Attack");
+
+        //get all attack-values
+        while(attackElement) {
+            
+            tinyxml2::XMLElement* attackTypeElement = attackElement->FirstChildElement();
+
+            while(attackTypeElement) {
+                 UnitId Unit_Id = static_cast<UnitId> attackTypeElement->Name(); //wenn das geht kauf ich maggus sein kochbuch
+
+                 int attackValue = attackTypeElement->IntText();
+
+                 attackValues[Unit_Id] = attackValue;
+
+                 attackTypeElement = attackTypeElement->NextSiblingElement();
+            }
+        }
+
+        damageMatrix[unitElement][attackValues];
+        unitElement = unitElement->NextSiblingElement("Unit");
+    }
+    
+}
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index adc11e8..e5ee504 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -71,7 +71,7 @@ public:
   TODO: This should probably tie back into rendering the units differently
   If a unit is selected, it should call inRange on all other enemy units on the field
   */
- 
+
  bool inRange(Unit &enemy);
 
   /*
@@ -96,6 +96,11 @@ public:
   */
   void calculate_movement();
 
+ /*
+ Load the XML and iterate over the entire datastructure
+ */
+void loadXML(const char* filename);
+
 private:
   int x;
   int y;
-- 
GitLab


From 7c9372937a05beb7d9186216dc2efb30395a40d3 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Mon, 27 Jan 2025 19:57:46 +0100
Subject: [PATCH 08/30] Add description in unit.hpp

---
 src/unit.hpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/unit.hpp b/src/unit.hpp
index e5ee504..b67a740 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -98,6 +98,7 @@ public:
 
  /*
  Load the XML and iterate over the entire datastructure
+ For every Unit, get Unit_Id and create a map for Unit_Id -> {Unit_Id -> damageType}
  */
 void loadXML(const char* filename);
 
-- 
GitLab


From ab45c86e69d4a76af95ad5cee0f8ec2a492e3b3c Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 11:24:43 +0100
Subject: [PATCH 09/30] Add onClick for units and basic attack initialization

---
 src/unit.cpp | 68 +++++++++++++++++++++++++++++++++++++++++-----------
 src/unit.hpp |  4 ++++
 2 files changed, 58 insertions(+), 14 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 6f9932c..8673d40 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -63,33 +63,73 @@ void Unit::render(Engine &engine, int scale) {
   }
 }
 
-void Unit::attack(Unit &enemy) {
+void Unit::attack(Unit &ally, Unit &enemy) {
 
-    //has unit not attacked this turn?
-    if(!inRange(enemy)) {
-        //Render enemies as not in Range => use the UNAVAILABLE Texture for that
-    }
-
-    if (this->has_attacked) {
+    if (ally->has_attacked) {
         //display the unit as not able to attack (maybe greyscale?)
     }
 
     //Start Attack: choose the appropriate weapon:
-    int offDamage = damageMatrix[this->id][enemy->id] * ((this->health)/(this->max_health));
-    int defDamage = damageMatrix[this->id][enemy->id] * ((enemy->health)/(enemy->max_health));
+    int offDamage = damageMatrix[ally->id][enemy->id] * ((ally->health)/(ally->max_health));
+    int defDamage = damageMatrix[ally->id][enemy->id] * ((enemy->health)/(enemy->max_health));
 
     enemy->health = enemy->health - offDamage;
     if(enemy->health > 0) {
-        this->health = this->health - defDamage;
-        if(this->health <= 0) {
-            this->~Unit();
+        ally->health = ally->health - defDamage;
+        if(ally->health <= 0) {
+            ally->~Unit();
         }
     } else {
         enemy->~Unit();
     }
 }
 
-void Unit::inRange(Unit &enemy) {
+void Unit::onClick(SDL_Event event) {
+
+    Unit &defender;
+    Unit &attacker;
+
+    switch (event.button.button) {
+        case SDL_BUTTON_LEFT:
+            
+            this->is_selected = true;
+
+            for (Unit &unit : units) {
+                if(inRange(unit)) {
+                    unit.state = UNAVAILABLE;
+                };
+            }
+        break;
+        case SDL_BUTTON_RIGHT:
+
+            this->is_targeted = true;
+
+            for (Unit &unit : units) {
+                if(unit.state = UNAVAILABLE) {
+                    continue;
+                }
+
+                if(unit.is_selected) {
+                    attacker = &unit;
+                }
+
+                if(unit.is_targeted) {
+                    defender = &unit;
+                }
+            }
+
+            if(attacker && defender) {
+                attack(attacker, defender);
+                break;
+            } else {
+                stderr("Could not init the attack!");
+                break;
+            }
+
+    }
+}
+
+bool Unit::inRange(Unit &enemy) {
     if (this->x == enemy.x) {
         return abs(this->y - enemy.y) <= this->range;
     } else if (this->y == enemy.y) {
@@ -98,7 +138,7 @@ void Unit::inRange(Unit &enemy) {
     return false; 
 }
 
-void loadXML(const char* filename) {
+void Unit::loadXML(const char* filename) {
 
     tinyxml2::XMLDocument doc;
     if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS) {
diff --git a/src/unit.hpp b/src/unit.hpp
index b67a740..9ead0b0 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -102,6 +102,8 @@ public:
  */
 void loadXML(const char* filename);
 
+void onClick(SDL_EVENT event);
+
 private:
   int x;
   int y;
@@ -118,6 +120,8 @@ private:
 
   bool has_moved;
   bool has_attacked;
+  bool is_selected;
+  bool is_targeted;
 
   // Primary weapon ammo
   int ammo;
-- 
GitLab


From 85ba722558e8f1188881906e3d759bf358fe0835 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 13:00:38 +0100
Subject: [PATCH 10/30] Update der Unit.cpp

---
 src/unit.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/unit.cpp b/src/unit.cpp
index 8673d40..fa9374b 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -11,6 +11,12 @@ Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
 void Unit::render(Engine &engine, int scale) {
   Spritesheet *spritesheet = engine.get_spritesheet();
 
+    while (engine.events not empty)
+    {
+        handle_event(events.pop_front());
+
+    }
+
   int step = engine.get_stage() % spritesheet->get_unit_textures()
                                       .at(static_cast<int>(faction))
                                       .at(static_cast<int>(id))
@@ -92,6 +98,7 @@ void Unit::onClick(SDL_Event event) {
     switch (event.button.button) {
         case SDL_BUTTON_LEFT:
             
+            //we have to re-initialize the unit.state (probably to idle)
             this->is_selected = true;
 
             for (Unit &unit : units) {
-- 
GitLab


From 159e0b5f1457fe1ec7c530477d1dc5095f206638 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 16:28:14 +0100
Subject: [PATCH 11/30] Update with move position and format unit.cpp

---
 src/unit.cpp | 291 +++++++++++++++++++++++++++++----------------------
 src/unit.hpp |   8 +-
 2 files changed, 170 insertions(+), 129 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index fa9374b..83875bc 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,188 +1,223 @@
 #include "unit.hpp"
 #include <tinyxml2.h>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
-    : x(x), y(y), faction(faction), id(id), state(state) {
+    Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
+        : x(x), y(y), faction(faction), id(id), state(state)
+    {
         health = max_health;
-      };
-
-void Unit::render(Engine &engine, int scale) {
-  Spritesheet *spritesheet = engine.get_spritesheet();
+    };
 
-    while (engine.events not empty)
+    void Unit::render(Engine &engine, int scale)
     {
-        handle_event(events.pop_front());
+        Spritesheet *spritesheet = engine.get_spritesheet();
 
-    }
+        while (engine.events not empty)
+        {
+            handle_event(events.pop_front());
+        }
 
-  int step = engine.get_stage() % spritesheet->get_unit_textures()
-                                      .at(static_cast<int>(faction))
-                                      .at(static_cast<int>(id))
-                                      .at(static_cast<int>(state))
-                                      .second;
-
-  if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE) {
-
-    SDL_Rect src;
-    src.x = step * spritesheet->get_unit_width();
-    src.y = 0;
-    src.w = spritesheet->get_unit_width();
-    src.h = spritesheet->get_unit_height();
-
-    SDL_Rect dst;
-    dst.x = x * spritesheet->get_unit_width() * scale;
-    dst.y = y * spritesheet->get_unit_height() * scale;
-    dst.w = spritesheet->get_unit_width() * scale;
-    dst.h = spritesheet->get_unit_height() * scale;
-
-    SDL_RenderCopyEx(engine.renderer(),
-                     spritesheet->get_unit_textures()
-                         .at(static_cast<int>(faction))
-                         .at(static_cast<int>(id))
-                         .at(static_cast<int>(state))
-                         .first,
-                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
-  } else {
-    // The moving states have a resolution of 24x24 instead of 16x16 and need to
-    // be handled separately
-    SDL_Rect src;
-    src.x = step * spritesheet->get_unit_moving_width();
-    src.y = 0;
-    src.w = spritesheet->get_unit_moving_width();
-    src.h = spritesheet->get_unit_moving_height();
-
-    SDL_Rect dst;
-    dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
-    dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
-    dst.w = spritesheet->get_unit_moving_width() * scale;
-    dst.h = spritesheet->get_unit_moving_height() * scale;
-
-    SDL_RenderCopyEx(engine.renderer(),
-                     spritesheet->get_unit_textures()
-                         .at(static_cast<int>(faction))
-                         .at(static_cast<int>(id))
-                         .at(static_cast<int>(state))
-                         .first,
-                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
-  }
-}
-
-void Unit::attack(Unit &ally, Unit &enemy) {
-
-    if (ally->has_attacked) {
-        //display the unit as not able to attack (maybe greyscale?)
+        int step = engine.get_stage() % spritesheet->get_unit_textures()
+                                            .at(static_cast<int>(faction))
+                                            .at(static_cast<int>(id))
+                                            .at(static_cast<int>(state))
+                                            .second;
+
+        if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE)
+        {
+
+            SDL_Rect src;
+            src.x = step * spritesheet->get_unit_width();
+            src.y = 0;
+            src.w = spritesheet->get_unit_width();
+            src.h = spritesheet->get_unit_height();
+
+            SDL_Rect dst;
+            dst.x = x * spritesheet->get_unit_width() * scale;
+            dst.y = y * spritesheet->get_unit_height() * scale;
+            dst.w = spritesheet->get_unit_width() * scale;
+            dst.h = spritesheet->get_unit_height() * scale;
+
+            SDL_RenderCopyEx(engine.renderer(),
+                             spritesheet->get_unit_textures()
+                                 .at(static_cast<int>(faction))
+                                 .at(static_cast<int>(id))
+                                 .at(static_cast<int>(state))
+                                 .first,
+                             &src, &dst, 0, NULL, SDL_FLIP_NONE);
+        }
+        else
+        {
+            // The moving states have a resolution of 24x24 instead of 16x16 and need to
+            // be handled separately
+            SDL_Rect src;
+            src.x = step * spritesheet->get_unit_moving_width();
+            src.y = 0;
+            src.w = spritesheet->get_unit_moving_width();
+            src.h = spritesheet->get_unit_moving_height();
+
+            SDL_Rect dst;
+            dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
+            dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
+            dst.w = spritesheet->get_unit_moving_width() * scale;
+            dst.h = spritesheet->get_unit_moving_height() * scale;
+
+            SDL_RenderCopyEx(engine.renderer(),
+                             spritesheet->get_unit_textures()
+                                 .at(static_cast<int>(faction))
+                                 .at(static_cast<int>(id))
+                                 .at(static_cast<int>(state))
+                                 .first,
+                             &src, &dst, 0, NULL, SDL_FLIP_NONE);
+        }
     }
 
-    //Start Attack: choose the appropriate weapon:
-    int offDamage = damageMatrix[ally->id][enemy->id] * ((ally->health)/(ally->max_health));
-    int defDamage = damageMatrix[ally->id][enemy->id] * ((enemy->health)/(enemy->max_health));
+    void Unit::attack(Unit &ally, Unit &enemy)
+    {
 
-    enemy->health = enemy->health - offDamage;
-    if(enemy->health > 0) {
-        ally->health = ally->health - defDamage;
-        if(ally->health <= 0) {
-            ally->~Unit();
+        if (ally->has_attacked)
+        {
+            // display the unit as not able to attack (maybe greyscale?)
+        }
+
+        // Start Attack: choose the appropriate weapon:
+        int offDamage = damageMatrix[ally->id][enemy->id] * ((ally->health) / (ally->max_health));
+        int defDamage = damageMatrix[ally->id][enemy->id] * ((enemy->health) / (enemy->max_health));
+
+        enemy->health = enemy->health - offDamage;
+        if (enemy->health > 0)
+        {
+            ally->health = ally->health - defDamage;
+            if (ally->health <= 0)
+            {
+                ally->~Unit();
+            }
+        }
+        else
+        {
+            enemy->~Unit();
         }
-    } else {
-        enemy->~Unit();
     }
-}
 
-void Unit::onClick(SDL_Event event) {
+    void Unit::update_position(int posX, int posY)
+    {
+        this->x = posX;
+        this->y = posY;
+    }
+
+    void Unit::onClick(SDL_EVENT event)
+    {
 
-    Unit &defender;
-    Unit &attacker;
+        Unit & defender;
+        Unit & attacker;
 
-    switch (event.button.button) {
+        switch (event.button.button)
+        {
         case SDL_BUTTON_LEFT:
-            
-            //we have to re-initialize the unit.state (probably to idle)
+
+            // we have to re-initialize the unit.state (probably to idle)
             this->is_selected = true;
 
-            for (Unit &unit : units) {
-                if(inRange(unit)) {
+            for (Unit &unit : units)
+            {
+                if (inRange(unit))
+                {
                     unit.state = UNAVAILABLE;
                 };
             }
-        break;
+            break;
         case SDL_BUTTON_RIGHT:
 
             this->is_targeted = true;
 
-            for (Unit &unit : units) {
-                if(unit.state = UNAVAILABLE) {
+            for (Unit &unit : units)
+            {
+                if (unit.state = UNAVAILABLE)
+                {
                     continue;
                 }
 
-                if(unit.is_selected) {
+                if (unit.is_selected)
+                {
                     attacker = &unit;
                 }
 
-                if(unit.is_targeted) {
+                if (unit.is_targeted)
+                {
                     defender = &unit;
                 }
             }
 
-            if(attacker && defender) {
+            if (attacker && defender)
+            {
                 attack(attacker, defender);
                 break;
-            } else {
+            }
+            else
+            {
                 stderr("Could not init the attack!");
                 break;
             }
-
+        }
     }
-}
 
-bool Unit::inRange(Unit &enemy) {
-    if (this->x == enemy.x) {
-        return abs(this->y - enemy.y) <= this->range;
-    } else if (this->y == enemy.y) {
-        return abs(this->x - enemy.x) <= this->range;
+    bool Unit::inRange(Unit &enemy)
+    {
+        if (this->x == enemy.x)
+        {
+            return abs(this->y - enemy.y) <= this->range;
+        }
+        else if (this->y == enemy.y)
+        {
+            return abs(this->x - enemy.x) <= this->range;
+        }
+        return false;
     }
-    return false; 
-}
 
-void Unit::loadXML(const char* filename) {
+    void Unit::loadXML(const char *filename)
+    {
 
-    tinyxml2::XMLDocument doc;
-    if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS) {
-        std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
-        return;
-    }
+        tinyxml2::XMLDocument doc;
+        if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS)
+        {
+            std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
+            return;
+        }
+
+        MatchupTabel damageMatrix;
+        tinyxml2::XMLElement *unitElement = doc.FirstChildElement("Units")->FirstChildElement("Unit");
 
-    MatchupTabel damageMatrix;
-    tinyxml2::XMLElement* unitElement = doc.FirstChildElement("Units")->FirstChildElement("Unit");
+        // get all Units
+        while (unitElement)
+        {
 
-    //get all Units
-    while(unitElement) {
+            const u_int8_t UnitId = unitElement->Attribute("id");
 
-        const u_int8_t UnitId = unitElement->Attribute("id");
+            std::unordered_map<u_int8_t, int> attackValues;
+            tinyxml2::XMLElement *attackElement = unitElement->FirstChildElement("Attack");
 
-        std::unordered_map<u_int8_t, int> attackValues;
-        tinyxml2::XMLElement* attackElement = unitElement->FirstChildElement("Attack");
+            // get all attack-values
+            while (attackElement)
+            {
 
-        //get all attack-values
-        while(attackElement) {
-            
-            tinyxml2::XMLElement* attackTypeElement = attackElement->FirstChildElement();
+                tinyxml2::XMLElement *attackTypeElement = attackElement->FirstChildElement();
 
-            while(attackTypeElement) {
-                 UnitId Unit_Id = static_cast<UnitId> attackTypeElement->Name(); //wenn das geht kauf ich maggus sein kochbuch
+                while (attackTypeElement)
+                {
+                    UnitId Unit_Id = static_cast<UnitId> attackTypeElement->Name(); // wenn das geht kauf ich maggus sein kochbuch
 
-                 int attackValue = attackTypeElement->IntText();
+                    int attackValue = attackTypeElement->IntText();
 
-                 attackValues[Unit_Id] = attackValue;
+                    attackValues[Unit_Id] = attackValue;
 
-                 attackTypeElement = attackTypeElement->NextSiblingElement();
+                    attackTypeElement = attackTypeElement->NextSiblingElement();
+                }
             }
-        }
 
-        damageMatrix[unitElement][attackValues];
-        unitElement = unitElement->NextSiblingElement("Unit");
+            damageMatrix[unitElement][attackValues];
+            unitElement = unitElement->NextSiblingElement("Unit");
+        }
     }
-    
-}
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index 9ead0b0..8710940 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -81,11 +81,12 @@ public:
   Will Update the health for both units
   Attacker deals damage to the defender first
   */
-  void attack(Unit &enemy);
+  void attack(Unit &ally ,Unit &enemy);
 
 
   /*
   @params Takes the desired position of the unit and updates its values
+  This will teleport the unit, there is no smooth transition between tiles
   */
   void update_position(int posX, int posY);
 
@@ -102,6 +103,11 @@ public:
  */
 void loadXML(const char* filename);
 
+
+/*
+This function will be called by an external event-handler, eventually.
+Currently, it should be called if a Unit is interacted with and the resulting SDL_EVENT is passed through, and then decided upon
+*/
 void onClick(SDL_EVENT event);
 
 private:
-- 
GitLab


From c3aeb3d7c8b931caf8af5161fb414bbdeeaf2bdf Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 18:18:17 +0100
Subject: [PATCH 12/30] Fix all possible bugs

Had to switch from references to pointers for now; should be refactored in the future
---
 src/unit.cpp | 52 ++++++++++++++++++++++++++--------------------------
 src/unit.hpp | 10 ++++++----
 2 files changed, 32 insertions(+), 30 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 83875bc..3a678b8 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,5 +1,6 @@
 #include "unit.hpp"
 #include <tinyxml2.h>
+#include <iostream>
 
 namespace advanced_wars
 {
@@ -14,11 +15,6 @@ namespace advanced_wars
     {
         Spritesheet *spritesheet = engine.get_spritesheet();
 
-        while (engine.events not empty)
-        {
-            handle_event(events.pop_front());
-        }
-
         int step = engine.get_stage() % spritesheet->get_unit_textures()
                                             .at(static_cast<int>(faction))
                                             .at(static_cast<int>(id))
@@ -74,7 +70,10 @@ namespace advanced_wars
         }
     }
 
-    void Unit::attack(Unit &ally, Unit &enemy)
+    MatchupTabel damageMatrix;
+    std::vector<Unit*> units;
+
+    void Unit::attack(Unit *ally, Unit *enemy)
     {
 
         if (ally->has_attacked)
@@ -83,8 +82,8 @@ namespace advanced_wars
         }
 
         // Start Attack: choose the appropriate weapon:
-        int offDamage = damageMatrix[ally->id][enemy->id] * ((ally->health) / (ally->max_health));
-        int defDamage = damageMatrix[ally->id][enemy->id] * ((enemy->health) / (enemy->max_health));
+        int offDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((ally->health) / (ally->max_health));
+        int defDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((enemy->health) / (enemy->max_health));
 
         enemy->health = enemy->health - offDamage;
         if (enemy->health > 0)
@@ -107,11 +106,11 @@ namespace advanced_wars
         this->y = posY;
     }
 
-    void Unit::onClick(SDL_EVENT event)
+    void Unit::onClick(SDL_Event event)
     {
 
-        Unit & defender;
-        Unit & attacker;
+        Unit *defender = nullptr;
+        Unit *attacker = nullptr;
 
         switch (event.button.button)
         {
@@ -120,11 +119,11 @@ namespace advanced_wars
             // we have to re-initialize the unit.state (probably to idle)
             this->is_selected = true;
 
-            for (Unit &unit : units)
+            for (Unit *unit : units)
             {
                 if (inRange(unit))
                 {
-                    unit.state = UNAVAILABLE;
+                    unit->state = advanced_wars::UnitState::UNAVAILABLE;
                 };
             }
             break;
@@ -132,21 +131,21 @@ namespace advanced_wars
 
             this->is_targeted = true;
 
-            for (Unit &unit : units)
+            for (Unit *unit : units)
             {
-                if (unit.state = UNAVAILABLE)
+                if (unit->state == advanced_wars::UnitState::UNAVAILABLE)
                 {
                     continue;
                 }
 
-                if (unit.is_selected)
+                if (unit->is_selected)
                 {
-                    attacker = &unit;
+                    attacker = unit;
                 }
 
-                if (unit.is_targeted)
+                if (unit->is_targeted)
                 {
-                    defender = &unit;
+                    defender = unit;
                 }
             }
 
@@ -157,25 +156,25 @@ namespace advanced_wars
             }
             else
             {
-                stderr("Could not init the attack!");
+                std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
                 break;
             }
         }
     }
 
-    bool Unit::inRange(Unit &enemy)
+    bool Unit::inRange(Unit *enemy)
     {
-        if (this->x == enemy.x)
+        if (this->x == enemy->x)
         {
-            return abs(this->y - enemy.y) <= this->range;
+            return abs(this->y - enemy->y) <= this->range;
         }
-        else if (this->y == enemy.y)
+        else if (this->y == enemy->y)
         {
-            return abs(this->x - enemy.x) <= this->range;
+            return abs(this->x - enemy->x) <= this->range;
         }
         return false;
     }
-
+    /*
     void Unit::loadXML(const char *filename)
     {
 
@@ -220,4 +219,5 @@ namespace advanced_wars
             unitElement = unitElement->NextSiblingElement("Unit");
         }
     }
+    */
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index 8710940..dfb5fc0 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <unordered_map>
 #include "engine.hpp"
 #include "weapon.hpp"
 #include <optional>
@@ -72,7 +73,7 @@ public:
   If a unit is selected, it should call inRange on all other enemy units on the field
   */
 
- bool inRange(Unit &enemy);
+ bool inRange(Unit *enemy);
 
   /*
   The attacker will move towards the defender and thus initiate combat
@@ -81,7 +82,7 @@ public:
   Will Update the health for both units
   Attacker deals damage to the defender first
   */
-  void attack(Unit &ally ,Unit &enemy);
+  void attack(Unit *ally ,Unit *enemy);
 
 
   /*
@@ -108,7 +109,7 @@ void loadXML(const char* filename);
 This function will be called by an external event-handler, eventually.
 Currently, it should be called if a Unit is interacted with and the resulting SDL_EVENT is passed through, and then decided upon
 */
-void onClick(SDL_EVENT event);
+void onClick(SDL_Event event);
 
 private:
   int x;
@@ -131,9 +132,10 @@ private:
 
   // Primary weapon ammo
   int ammo;
-
+  /*
   std::optional<Weapon> primary;
   std::optional<Weapon> secondary;
+  */
 };
 
 } // namespace advanced_wars
\ No newline at end of file
-- 
GitLab


From 4b69d0a826cc96fad66c9df8576ca4206e00b275 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 20:55:29 +0100
Subject: [PATCH 13/30] Add actual fighting mechanics

Modifie Level.hpp with eventhandling (bare-bones)
Fix potential bugs in unit.cpp
---
 src/level.cpp | 43 +++++++++++++++++++++++++++++++++++++++++--
 src/level.hpp |  5 +++++
 src/main.cpp  |  2 +-
 src/unit.cpp  | 27 ++++++++++++++++-----------
 src/unit.hpp  |  9 +++++----
 5 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 74c1598..7469a8f 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -22,11 +22,50 @@ Level::Level(std::string name, int width, int height, std::vector<Tile> tiles,
   }
 };
 
-void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
-  const int RENDERING_SCALE = 3;
+const int RENDERING_SCALE = 3;
+
+bool Level::clickCheck(int mouseX, int mouseY) {
+  
+  int tileX = mouseX/(16*RENDERING_SCALE);
+  int tileY = mouseY/(16*RENDERING_SCALE);
+
+  for (auto& unit : units) {
+
+    if(unit.x == tileX && unit.y == tileY) {
+      //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+      selectedUnit = &unit;
+      return true;
+    }
+  }
+}
+
 
+void Level::handleEvent(Engine &engine, SDL_Event &event) {
+
+  //handle following events:
+  //clicks/mouseDown
+  //escape (esc)
+
+  switch (event.type)
+  {
+  case SDL_MOUSEBUTTONDOWN:
+      if(clickCheck(event.button.x, event.button.y)) {
+        selectedUnit->onClick(event, units);
+      }
+    break;
+  
+  default:
+    break;
+  }
+}
+
+void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
+  
   // Iterate over all events
   while (!events.empty()) {
+    //events.erase(events.begin());
+
+    handleEvent(engine, events.at(0));
     events.erase(events.begin());
   }
 
diff --git a/src/level.hpp b/src/level.hpp
index 9aff83c..3bf0dfb 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -23,6 +23,8 @@ public:
 
   void render(Engine &engine, std::vector<SDL_Event> &events);
 
+  void handleEvent(Engine &engine, SDL_Event &event);
+
 private:
   std::string name;
   int width;
@@ -31,6 +33,9 @@ private:
   std::vector<Building> buildings;
   std::vector<Unit> units;
   std::vector<Effect> effects;
+  Unit* selectedUnit;
+
+  bool clickCheck(int mouseX, int mouseY);
 };
 
 } // namespace advanced_wars
diff --git a/src/main.cpp b/src/main.cpp
index 6bb056f..a6d4dd4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -82,7 +82,7 @@ int main() {
 
   engine.set_scene(level);
 
-  Spritesheet spritesheet("/media/data/rust/sprite-extractor/spritesheet.h5",
+  Spritesheet spritesheet("./spritesheet.h5",
                           engine);
 
   engine.set_spritesheet(spritesheet);
diff --git a/src/unit.cpp b/src/unit.cpp
index 3a678b8..8661298 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -6,7 +6,7 @@ namespace advanced_wars
 {
 
     Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
-        : x(x), y(y), faction(faction), id(id), state(state)
+        : x(x), y(y), faction(faction), id(id), state(state), max_health(100)
     {
         health = max_health;
     };
@@ -106,7 +106,7 @@ namespace advanced_wars
         this->y = posY;
     }
 
-    void Unit::onClick(SDL_Event event)
+    void Unit::onClick(SDL_Event event, std::vector<Unit> &unitVector)
     {
 
         Unit *defender = nullptr;
@@ -118,45 +118,50 @@ namespace advanced_wars
 
             // we have to re-initialize the unit.state (probably to idle)
             this->is_selected = true;
+            std::cout << "I am selected!!" << std::endl;
 
+            /*
             for (Unit *unit : units)
             {
-                if (inRange(unit))
+                if (!inRange(unit))
                 {
                     unit->state = advanced_wars::UnitState::UNAVAILABLE;
                 };
             }
+            */
             break;
         case SDL_BUTTON_RIGHT:
 
             this->is_targeted = true;
+            std::cout << "I am targeted!!" << std::endl;
 
-            for (Unit *unit : units)
+            for (Unit unit : unitVector)
             {
-                if (unit->state == advanced_wars::UnitState::UNAVAILABLE)
+                if (unit.state == advanced_wars::UnitState::UNAVAILABLE)
                 {
                     continue;
                 }
 
-                if (unit->is_selected)
+                if (unit.is_selected)
                 {
-                    attacker = unit;
+                    attacker = &unit;
                 }
 
-                if (unit->is_targeted)
+                if (unit.is_targeted)
                 {
-                    defender = unit;
+                    defender = &unit;
                 }
             }
 
-            if (attacker && defender)
+            if (attacker != nullptr && defender != nullptr)
             {
                 attack(attacker, defender);
+                std::cout << "We are fighting!!" << std::endl;
                 break;
             }
             else
             {
-                std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
+                std::cerr << "Angriff konnte nicht gestartet werden!" << std::endl;
                 break;
             }
         }
diff --git a/src/unit.hpp b/src/unit.hpp
index dfb5fc0..ef1c9ef 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -60,6 +60,10 @@ using MatchupTabel = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, i
 
 class Unit {
 public:
+  int x;
+  int y;
+
+
   Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
   ~Unit() {
         //Assuming that the destruktion of a unit triggers events
@@ -109,12 +113,9 @@ void loadXML(const char* filename);
 This function will be called by an external event-handler, eventually.
 Currently, it should be called if a Unit is interacted with and the resulting SDL_EVENT is passed through, and then decided upon
 */
-void onClick(SDL_Event event);
+void onClick(SDL_Event event, std::vector<Unit> &unitVector);
 
 private:
-  int x;
-  int y;
-
   UnitFaction faction;
   UnitId id;
   UnitState state;
-- 
GitLab


From 70b3c32312f61c551c4526291675f16e4fb6ceea Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 21:30:33 +0100
Subject: [PATCH 14/30] Add building selection

---
 src/level.cpp | 35 ++++++++++++++++++++++++++++++++++-
 src/level.hpp |  3 +++
 src/unit.cpp  | 15 +++++++++++++++
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/level.cpp b/src/level.cpp
index 7469a8f..6808505 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -29,6 +29,16 @@ bool Level::clickCheck(int mouseX, int mouseY) {
   int tileX = mouseX/(16*RENDERING_SCALE);
   int tileY = mouseY/(16*RENDERING_SCALE);
 
+  if(selectUnit(tileX, tileY)) return true;
+  if(selectBuilding(tileX, tileY)) return true;
+
+  std::cout << "Neither building nor unit clicked" << std::endl;
+  
+  return false;
+}
+
+bool Level::selectUnit (int tileX, int tileY) {
+
   for (auto& unit : units) {
 
     if(unit.x == tileX && unit.y == tileY) {
@@ -37,8 +47,23 @@ bool Level::clickCheck(int mouseX, int mouseY) {
       return true;
     }
   }
+  selectedUnit = nullptr;
+  return false;
 }
 
+bool Level::selectBuilding (int tileX, int tileY) {
+
+  for (auto& building : buildings) {
+
+    if(building.x == tileX && building.y == tileY) {
+      //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+      selectedBuilding = &building;
+      return true;
+    }
+  }
+  selectedBuilding = nullptr;
+  return false;
+}
 
 void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
@@ -50,7 +75,15 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
   {
   case SDL_MOUSEBUTTONDOWN:
       if(clickCheck(event.button.x, event.button.y)) {
-        selectedUnit->onClick(event, units);
+        
+        if(selectedUnit) {
+          selectedUnit->onClick(event, units);
+        }
+
+        if(selectedBuilding) {
+          //building stuff
+        }
+        
       }
     break;
   
diff --git a/src/level.hpp b/src/level.hpp
index 3bf0dfb..0d3b6dd 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -34,6 +34,9 @@ private:
   std::vector<Unit> units;
   std::vector<Effect> effects;
   Unit* selectedUnit;
+  Building* selectedBuilding;
+  bool selectUnit (int tileX, int tileY);
+  bool selectBuilding(int tileX, int tileY);
 
   bool clickCheck(int mouseX, int mouseY);
 };
diff --git a/src/unit.cpp b/src/unit.cpp
index 8661298..4b3f2e3 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -106,6 +106,19 @@ namespace advanced_wars
         this->y = posY;
     }
 
+/*
+Features:
+//select unit 
+    - show context menu
+    - show move range
+    - MAYBE show valid targets
+
+//deselect unit
+
+//attack unit
+    - show context menu
+
+*/
     void Unit::onClick(SDL_Event event, std::vector<Unit> &unitVector)
     {
 
@@ -129,6 +142,8 @@ namespace advanced_wars
                 };
             }
             */
+
+           //make move range calc
             break;
         case SDL_BUTTON_RIGHT:
 
-- 
GitLab


From abb13726f94d132e6f315470818ffbeceacc9819 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 21:40:28 +0100
Subject: [PATCH 15/30] Add actual fighting

---
 src/unit.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 4b3f2e3..42fbab1 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -82,13 +82,18 @@ namespace advanced_wars
         }
 
         // Start Attack: choose the appropriate weapon:
+        /*
         int offDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((ally->health) / (ally->max_health));
-        int defDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((enemy->health) / (enemy->max_health));
+        int defDamage = damageMatrix[static_cast<u_int8_t>(enemy->id)][static_cast<u_int8_t>(ally->id)] * ((enemy->health) / (enemy->max_health));
+        */
+        int offDamage = 10;
+        int defDamage = 1000;
 
         enemy->health = enemy->health - offDamage;
         if (enemy->health > 0)
         {
             ally->health = ally->health - defDamage;
+            std::cout << "Health ally:" << ally->health << std::endl;
             if (ally->health <= 0)
             {
                 ally->~Unit();
-- 
GitLab


From 1c234b83fbf81f16f116a4b736acab50e9176de5 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Tue, 28 Jan 2025 22:25:31 +0100
Subject: [PATCH 16/30] Implement removal of units on stage if defeated

---
 src/level.cpp | 26 ++++++++++++++++++++++++--
 src/unit.cpp  | 37 +++++++++----------------------------
 src/unit.hpp  |  7 +++++--
 3 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 6808505..7d0f61e 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -8,6 +8,7 @@
 #include <SDL.h>
 #include <iostream>
 #include <string>
+#include <algorithm> 
 
 namespace advanced_wars {
 
@@ -74,7 +75,8 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
   switch (event.type)
   {
   case SDL_MOUSEBUTTONDOWN:
-      if(clickCheck(event.button.x, event.button.y)) {
+      if (event.button.button == SDL_BUTTON_LEFT) {
+        if(clickCheck(event.button.x, event.button.y)) {
         
         if(selectedUnit) {
           selectedUnit->onClick(event, units);
@@ -83,8 +85,28 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
         if(selectedBuilding) {
           //building stuff
         }
-        
       }
+      } else if (event.button.button == SDL_BUTTON_RIGHT) {
+
+        if(selectedUnit) {
+          int tileX = event.button.x/(16*RENDERING_SCALE);
+          int tileY = event.button.y/(16*RENDERING_SCALE);
+          for (auto& unit : units) {
+
+            if(unit.x == tileX && unit.y == tileY) {
+            //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+            
+            selectedUnit->attack(unit);
+
+            units.erase(
+            std::remove_if(units.begin(), units.end(),
+                       [](const Unit& unit) { return unit.health < 0; }),
+            units.end());
+          }
+  }
+        }
+      }
+      
     break;
   
   default:
diff --git a/src/unit.cpp b/src/unit.cpp
index 42fbab1..4911a0d 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -72,36 +72,17 @@ namespace advanced_wars
 
     MatchupTabel damageMatrix;
     std::vector<Unit*> units;
+    
+    void Unit::attack(Unit& enemy) {
 
-    void Unit::attack(Unit *ally, Unit *enemy)
-    {
-
-        if (ally->has_attacked)
-        {
-            // display the unit as not able to attack (maybe greyscale?)
-        }
-
-        // Start Attack: choose the appropriate weapon:
-        /*
-        int offDamage = damageMatrix[static_cast<u_int8_t>(ally->id)][static_cast<u_int8_t>(enemy->id)] * ((ally->health) / (ally->max_health));
-        int defDamage = damageMatrix[static_cast<u_int8_t>(enemy->id)][static_cast<u_int8_t>(ally->id)] * ((enemy->health) / (enemy->max_health));
-        */
-        int offDamage = 10;
+        int offDamage = 50;
         int defDamage = 1000;
 
-        enemy->health = enemy->health - offDamage;
-        if (enemy->health > 0)
-        {
-            ally->health = ally->health - defDamage;
-            std::cout << "Health ally:" << ally->health << std::endl;
-            if (ally->health <= 0)
-            {
-                ally->~Unit();
-            }
-        }
-        else
-        {
-            enemy->~Unit();
+        enemy.health = enemy.health - offDamage;
+        std::cout << "Enemy health:" << enemy.health << std::endl;
+        if (enemy.health > 0) {
+            this->health = this->health - defDamage;
+            std::cout << "Health ally:" << this->health << std::endl;
         }
     }
 
@@ -175,7 +156,7 @@ Features:
 
             if (attacker != nullptr && defender != nullptr)
             {
-                attack(attacker, defender);
+                //attack(attacker, defender);
                 std::cout << "We are fighting!!" << std::endl;
                 break;
             }
diff --git a/src/unit.hpp b/src/unit.hpp
index ef1c9ef..9c7460f 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -62,6 +62,7 @@ class Unit {
 public:
   int x;
   int y;
+  int health; //health equals max_health at construction
 
 
   Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
@@ -86,7 +87,8 @@ public:
   Will Update the health for both units
   Attacker deals damage to the defender first
   */
-  void attack(Unit *ally ,Unit *enemy);
+
+  void attack(Unit& enemy);
 
 
   /*
@@ -109,6 +111,7 @@ public:
 void loadXML(const char* filename);
 
 
+
 /*
 This function will be called by an external event-handler, eventually.
 Currently, it should be called if a Unit is interacted with and the resulting SDL_EVENT is passed through, and then decided upon
@@ -120,7 +123,7 @@ private:
   UnitId id;
   UnitState state;
 
-  int health; //health equals max_health at construction
+ 
   int max_health; // max_health required for damage_scaling
   int range;
   int fuel;
-- 
GitLab


From 5feb27d1fa3fe427cf5ec9e3c38ac25db0a9805f Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Wed, 29 Jan 2025 18:49:09 +0100
Subject: [PATCH 17/30] Refactor simple issues

Such as typos, unused includes and unnecessary comments
---
 src/unit.cpp | 60 +---------------------------------------------------
 src/unit.hpp | 14 ++++++------
 2 files changed, 7 insertions(+), 67 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 4911a0d..d48d323 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,5 +1,4 @@
 #include "unit.hpp"
-#include <tinyxml2.h>
 #include <iostream>
 
 namespace advanced_wars
@@ -69,9 +68,6 @@ namespace advanced_wars
                              &src, &dst, 0, NULL, SDL_FLIP_NONE);
         }
     }
-
-    MatchupTabel damageMatrix;
-    std::vector<Unit*> units;
     
     void Unit::attack(Unit& enemy) {
 
@@ -119,17 +115,8 @@ Features:
             this->is_selected = true;
             std::cout << "I am selected!!" << std::endl;
 
-            /*
-            for (Unit *unit : units)
-            {
-                if (!inRange(unit))
-                {
-                    unit->state = advanced_wars::UnitState::UNAVAILABLE;
-                };
-            }
-            */
-
            //make move range calc
+
             break;
         case SDL_BUTTON_RIGHT:
 
@@ -180,50 +167,5 @@ Features:
         }
         return false;
     }
-    /*
-    void Unit::loadXML(const char *filename)
-    {
-
-        tinyxml2::XMLDocument doc;
-        if (doc.LoadFile(filename) != tinyxml2::XML_SUCCESS)
-        {
-            std::cerr << "Fehler beim Laden der XML-Datei!" << std::endl;
-            return;
-        }
-
-        MatchupTabel damageMatrix;
-        tinyxml2::XMLElement *unitElement = doc.FirstChildElement("Units")->FirstChildElement("Unit");
-
-        // get all Units
-        while (unitElement)
-        {
-
-            const u_int8_t UnitId = unitElement->Attribute("id");
 
-            std::unordered_map<u_int8_t, int> attackValues;
-            tinyxml2::XMLElement *attackElement = unitElement->FirstChildElement("Attack");
-
-            // get all attack-values
-            while (attackElement)
-            {
-
-                tinyxml2::XMLElement *attackTypeElement = attackElement->FirstChildElement();
-
-                while (attackTypeElement)
-                {
-                    UnitId Unit_Id = static_cast<UnitId> attackTypeElement->Name(); // wenn das geht kauf ich maggus sein kochbuch
-
-                    int attackValue = attackTypeElement->IntText();
-
-                    attackValues[Unit_Id] = attackValue;
-
-                    attackTypeElement = attackTypeElement->NextSiblingElement();
-                }
-            }
-
-            damageMatrix[unitElement][attackValues];
-            unitElement = unitElement->NextSiblingElement("Unit");
-        }
-    }
-    */
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index 9c7460f..f547e59 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -55,8 +55,7 @@ enum class MovementType {
   LANDER = 5,
 };
 
-//Fill the MatchupTabel
-using MatchupTabel = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, int>>;
+using MatchupTable = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, int>>;
 
 class Unit {
 public:
@@ -104,13 +103,12 @@ public:
   */
   void calculate_movement();
 
- /*
- Load the XML and iterate over the entire datastructure
- For every Unit, get Unit_Id and create a map for Unit_Id -> {Unit_Id -> damageType}
- */
-void loadXML(const char* filename);
-
 
+  /*
+  This function fills the MatchupTable
+  It would be better if this table would be placed in the level
+  */
+ void fill_matchupTable();
 
 /*
 This function will be called by an external event-handler, eventually.
-- 
GitLab


From 91cd1cb4cd97aa9b62f1f1dbb234f83359e13d23 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Wed, 29 Jan 2025 19:13:14 +0100
Subject: [PATCH 18/30] Make progress towards porting new attack function

Currently the matchupTable needs to be loaded for both primary and secondary weapontypes
How do we do that?
---
 src/unit.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/unit.hpp | 12 +++----
 2 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index d48d323..9ef601d 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -69,16 +69,90 @@ namespace advanced_wars
         }
     }
     
-    void Unit::attack(Unit& enemy) {
+    void Unit::attack(Unit &enemy)
+    {   
+        secondary_weapon = fill_matchupTable(0);
+        primary_weapon = fill_matchupTable(1);
 
-        int offDamage = 50;
-        int defDamage = 1000;
+        // Zuerst die Tabel für die Waffen der angreifenden Einheit holen
+        auto &attackerSecondaryWeaponTable = secondary_weapon[this->id];
+        auto &attackerPrimaryWeaponTable = primary_weapon[this->id];
 
-        enemy.health = enemy.health - offDamage;
-        std::cout << "Enemy health:" << enemy.health << std::endl;
-        if (enemy.health > 0) {
-            this->health = this->health - defDamage;
-            std::cout << "Health ally:" << this->health << std::endl;
+        // Schadenswert für die angreifende Einheit gegen die verteidigende Einheit berechnen
+        // Es wird die Waffe genommen die mehr Schaden macht
+
+        int attackerDamageValue = 0;
+
+        if (attackerSecondaryWeaponTable.find(enemy.id) != attackerSecondaryWeaponTable.end())
+        {
+            attackerDamageValue = attackerSecondaryWeaponTable[enemy.id];
+        }
+        if (attackerPrimaryWeaponTable.find(enemy.id) != attackerPrimaryWeaponTable.end())
+        {
+            if (attackerDamageValue < attackerPrimaryWeaponTable[enemy.id])
+            {
+                // Here ammo deduction should happen if applicable
+                attackerDamageValue = attackerPrimaryWeaponTable[enemy.id];
+            }
+        }
+
+        if (attackerDamageValue == 0)
+        {
+            std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
+                      << " against unit " << static_cast<int>(enemy.id) << std::endl;
+        }
+        else
+        {
+
+            int offDamage = attackerDamageValue * (static_cast<float>(health) / max_health);
+            enemy.health -= offDamage;
+            enemy.health = std::max(0, enemy.health); // Ensuring health is not negative
+            std::cout << "Enemy health after attack: " << enemy.health << std::endl;
+
+            // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
+            if (enemy.health > 0)
+            {
+                // Weapon tables for the defender
+                auto &defenderSecondaryWeaponTable = secondary_weapon[enemy.id];
+                auto &defenderPrimaryWeaponTable = primary_weapon[enemy.id];
+
+                int defenderDamageValue = 0; // Declare outside for later use
+
+                // Determine the damage value for the defender
+                if (defenderSecondaryWeaponTable.find(id) != defenderSecondaryWeaponTable.end())
+                {
+                    defenderDamageValue = defenderSecondaryWeaponTable[id];
+                }
+                if (defenderPrimaryWeaponTable.find(id) != defenderPrimaryWeaponTable.end())
+                {
+                    if (defenderDamageValue < defenderPrimaryWeaponTable[id])
+                    {
+                        // Deduct ammo for primary weapon, if applicable
+                        defenderDamageValue = defenderPrimaryWeaponTable[id];
+                    }
+                }
+
+                // If a valid damage value was determined for retaliation
+                if (defenderDamageValue > 0)
+                {
+                    int defDamage = static_cast<int>(defenderDamageValue * static_cast<float>(enemy.health) / enemy.max_health);
+                    this->health -= defDamage;
+                    this->health = std::max(0, this->health); // Safeguard against negative health
+                    std::cout << "Ally health after retaliation: " << this->health << std::endl;
+                }
+            }
+        }
+    }
+
+    MatchupTable Unit::fill_matchupTable(int type) {
+        switch (type)
+        {
+        case 0:
+            
+            break;
+        
+        default:
+            break;
         }
     }
 
diff --git a/src/unit.hpp b/src/unit.hpp
index f547e59..4027d81 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -55,7 +55,7 @@ enum class MovementType {
   LANDER = 5,
 };
 
-using MatchupTable = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, int>>;
+using MatchupTable = std::unordered_map<UnitId, std::unordered_map<UnitId, int>>;
 
 class Unit {
 public:
@@ -108,7 +108,7 @@ public:
   This function fills the MatchupTable
   It would be better if this table would be placed in the level
   */
- void fill_matchupTable();
+ MatchupTable fill_matchupTable(int);
 
 /*
 This function will be called by an external event-handler, eventually.
@@ -131,13 +131,11 @@ private:
   bool has_attacked;
   bool is_selected;
   bool is_targeted;
+  MatchupTable secondary_weapon;
+  MatchupTable primary_weapon;
 
-  // Primary weapon ammo
   int ammo;
-  /*
-  std::optional<Weapon> primary;
-  std::optional<Weapon> secondary;
-  */
+ 
 };
 
 } // namespace advanced_wars
\ No newline at end of file
-- 
GitLab


From af6c8e0607520342be2f1822eb49c10fc144f384 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 10:13:15 +0100
Subject: [PATCH 19/30] Fix bug in selecting units

New problems:
- illegal instruction error
- units disappear after moving them
---
 src/level.cpp | 102 ++++++++++++++++++++++++++++++++++++--------------
 src/level.hpp |   5 ++-
 src/unit.cpp  |  30 ++++++++-------
 src/unit.hpp  |   2 +-
 4 files changed, 95 insertions(+), 44 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 7d0f61e..11d3b15 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -25,30 +25,63 @@ Level::Level(std::string name, int width, int height, std::vector<Tile> tiles,
 
 const int RENDERING_SCALE = 3;
 
-bool Level::clickCheck(int mouseX, int mouseY) {
+bool Level::click_check_left(int mouseX, int mouseY) {
   
   int tileX = mouseX/(16*RENDERING_SCALE);
   int tileY = mouseY/(16*RENDERING_SCALE);
 
-  if(selectUnit(tileX, tileY)) return true;
-  if(selectBuilding(tileX, tileY)) return true;
+  if(selectUnit(tileX, tileY)) {
+    return true;
+  }
+
+  if(selectBuilding(tileX, tileY)) {
+    return true; 
+  } 
+    
+  return false;
+}
 
-  std::cout << "Neither building nor unit clicked" << std::endl;
+bool Level::click_check_right(int mouseX, int mouseY) {
   
+  int tileX = mouseX/(16*RENDERING_SCALE);
+  int tileY = mouseY/(16*RENDERING_SCALE);
+
+  if(target_unit(tileX, tileY)) {
+    return true;
+  }
+   
   return false;
 }
 
 bool Level::selectUnit (int tileX, int tileY) {
 
+  //std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
   for (auto& unit : units) {
 
     if(unit.x == tileX && unit.y == tileY) {
-      //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+      //std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
+      
       selectedUnit = &unit;
       return true;
     }
   }
-  selectedUnit = nullptr;
+  
+  return false;
+}
+
+bool Level::target_unit (int tileX, int tileY) {
+
+  //std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
+  for (auto& unit : units) {
+
+    if(unit.x == tileX && unit.y == tileY) {
+      //std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
+      
+      targetedUnit = &unit;
+      return true;
+    }
+  }
+  
   return false;
 }
 
@@ -62,7 +95,6 @@ bool Level::selectBuilding (int tileX, int tileY) {
       return true;
     }
   }
-  selectedBuilding = nullptr;
   return false;
 }
 
@@ -75,44 +107,58 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
   switch (event.type)
   {
   case SDL_MOUSEBUTTONDOWN:
+
       if (event.button.button == SDL_BUTTON_LEFT) {
-        if(clickCheck(event.button.x, event.button.y)) {
+
+        if(click_check_left(event.button.x, event.button.y)) {
         
-        if(selectedUnit) {
-          selectedUnit->onClick(event, units);
-        }
+          if(selectedUnit) {
+            selectedUnit->onClick(event, units);
+          }
+
+          if(selectedBuilding) {
+            //building stuff
+          }
+
+      } else {
+
+        std::cout << "Neither building nor unit clicked!" << std::endl;
+        selectedUnit = nullptr;
+        selectedBuilding = nullptr;
 
-        if(selectedBuilding) {
-          //building stuff
-        }
       }
+
       } else if (event.button.button == SDL_BUTTON_RIGHT) {
 
         if(selectedUnit) {
-          int tileX = event.button.x/(16*RENDERING_SCALE);
-          int tileY = event.button.y/(16*RENDERING_SCALE);
-          for (auto& unit : units) {
 
-            if(unit.x == tileX && unit.y == tileY) {
-            //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
-            
-            selectedUnit->attack(unit);
+          int tileX = event.button.x;
+          int tileY = event.button.y;
+
+          if(click_check_right(tileX, tileY)) {
+
+            selectedUnit->attack(targetedUnit);
 
             units.erase(
             std::remove_if(units.begin(), units.end(),
                        [](const Unit& unit) { return unit.health < 0; }),
             units.end());
+
+          } else {
+            
+            
+
+            selectedUnit->update_position(tileX, tileY);
+
           }
-  }
+        } else {
+
+          std::cout << "No unit selected! " << std::endl;
+
+        }
         }
       }
-      
-    break;
-  
-  default:
-    break;
   }
-}
 
 void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
   
diff --git a/src/level.hpp b/src/level.hpp
index 0d3b6dd..7c5e99b 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -34,11 +34,14 @@ private:
   std::vector<Unit> units;
   std::vector<Effect> effects;
   Unit* selectedUnit;
+  Unit* targetedUnit;
   Building* selectedBuilding;
   bool selectUnit (int tileX, int tileY);
+  bool target_unit (int tileX, int tileY);
   bool selectBuilding(int tileX, int tileY);
 
-  bool clickCheck(int mouseX, int mouseY);
+  bool click_check_left(int mouseX, int mouseY);
+  bool click_check_right(int mouseX, int mouseY);
 };
 
 } // namespace advanced_wars
diff --git a/src/unit.cpp b/src/unit.cpp
index 9ef601d..1d9b293 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -69,7 +69,7 @@ namespace advanced_wars
         }
     }
     
-    void Unit::attack(Unit &enemy)
+    void Unit::attack(Unit *enemy)
     {   
         secondary_weapon = fill_matchupTable(0);
         primary_weapon = fill_matchupTable(1);
@@ -83,38 +83,38 @@ namespace advanced_wars
 
         int attackerDamageValue = 0;
 
-        if (attackerSecondaryWeaponTable.find(enemy.id) != attackerSecondaryWeaponTable.end())
+        if (attackerSecondaryWeaponTable.find(enemy->id) != attackerSecondaryWeaponTable.end())
         {
-            attackerDamageValue = attackerSecondaryWeaponTable[enemy.id];
+            attackerDamageValue = attackerSecondaryWeaponTable[enemy->id];
         }
-        if (attackerPrimaryWeaponTable.find(enemy.id) != attackerPrimaryWeaponTable.end())
+        if (attackerPrimaryWeaponTable.find(enemy->id) != attackerPrimaryWeaponTable.end())
         {
-            if (attackerDamageValue < attackerPrimaryWeaponTable[enemy.id])
+            if (attackerDamageValue < attackerPrimaryWeaponTable[enemy->id])
             {
                 // Here ammo deduction should happen if applicable
-                attackerDamageValue = attackerPrimaryWeaponTable[enemy.id];
+                attackerDamageValue = attackerPrimaryWeaponTable[enemy->id];
             }
         }
 
         if (attackerDamageValue == 0)
         {
             std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
-                      << " against unit " << static_cast<int>(enemy.id) << std::endl;
+                      << " against unit " << static_cast<int>(enemy->id) << std::endl;
         }
         else
         {
 
             int offDamage = attackerDamageValue * (static_cast<float>(health) / max_health);
-            enemy.health -= offDamage;
-            enemy.health = std::max(0, enemy.health); // Ensuring health is not negative
-            std::cout << "Enemy health after attack: " << enemy.health << std::endl;
+            enemy->health -= offDamage;
+            enemy->health = std::max(0, enemy->health); // Ensuring health is not negative
+            std::cout << "Enemy health after attack: " << enemy->health << std::endl;
 
             // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
-            if (enemy.health > 0)
+            if (enemy->health > 0)
             {
                 // Weapon tables for the defender
-                auto &defenderSecondaryWeaponTable = secondary_weapon[enemy.id];
-                auto &defenderPrimaryWeaponTable = primary_weapon[enemy.id];
+                auto &defenderSecondaryWeaponTable = secondary_weapon[enemy->id];
+                auto &defenderPrimaryWeaponTable = primary_weapon[enemy->id];
 
                 int defenderDamageValue = 0; // Declare outside for later use
 
@@ -135,7 +135,7 @@ namespace advanced_wars
                 // If a valid damage value was determined for retaliation
                 if (defenderDamageValue > 0)
                 {
-                    int defDamage = static_cast<int>(defenderDamageValue * static_cast<float>(enemy.health) / enemy.max_health);
+                    int defDamage = static_cast<int>(defenderDamageValue * static_cast<float>(enemy->health) / enemy->max_health);
                     this->health -= defDamage;
                     this->health = std::max(0, this->health); // Safeguard against negative health
                     std::cout << "Ally health after retaliation: " << this->health << std::endl;
@@ -188,6 +188,7 @@ Features:
             // we have to re-initialize the unit.state (probably to idle)
             this->is_selected = true;
             std::cout << "I am selected!!" << std::endl;
+            std::cout << "And my position is:" << this->x << " " << this->y << std::endl;
 
            //make move range calc
 
@@ -196,6 +197,7 @@ Features:
 
             this->is_targeted = true;
             std::cout << "I am targeted!!" << std::endl;
+            std::cout << "And my position is:" << this->x << " " << this->y << std::endl;
 
             for (Unit unit : unitVector)
             {
diff --git a/src/unit.hpp b/src/unit.hpp
index 4027d81..d836862 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -87,7 +87,7 @@ public:
   Attacker deals damage to the defender first
   */
 
-  void attack(Unit& enemy);
+  void attack(Unit *enemy);
 
 
   /*
-- 
GitLab


From 3528a3d647cfce740ce7736aa9e4f1e72de5d75f Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 10:23:17 +0100
Subject: [PATCH 20/30] Refactor left_click

Why does the clicked unit dissappear after moving it?
---
 src/level.cpp |  6 ++----
 src/unit.cpp  | 55 +++------------------------------------------------
 src/unit.hpp  |  4 ++--
 3 files changed, 7 insertions(+), 58 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 11d3b15..0b241d1 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -113,7 +113,7 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
         if(click_check_left(event.button.x, event.button.y)) {
         
           if(selectedUnit) {
-            selectedUnit->onClick(event, units);
+            selectedUnit->on_left_click(event, units);
           }
 
           if(selectedBuilding) {
@@ -146,8 +146,6 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
           } else {
             
-            
-
             selectedUnit->update_position(tileX, tileY);
 
           }
@@ -156,8 +154,8 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
           std::cout << "No unit selected! " << std::endl;
 
         }
-        }
       }
+    }
   }
 
 void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
diff --git a/src/unit.cpp b/src/unit.cpp
index 1d9b293..c0a4634 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -175,60 +175,11 @@ Features:
     - show context menu
 
 */
-    void Unit::onClick(SDL_Event event, std::vector<Unit> &unitVector)
+    void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector)
     {
 
-        Unit *defender = nullptr;
-        Unit *attacker = nullptr;
-
-        switch (event.button.button)
-        {
-        case SDL_BUTTON_LEFT:
-
-            // we have to re-initialize the unit.state (probably to idle)
-            this->is_selected = true;
-            std::cout << "I am selected!!" << std::endl;
-            std::cout << "And my position is:" << this->x << " " << this->y << std::endl;
-
-           //make move range calc
-
-            break;
-        case SDL_BUTTON_RIGHT:
-
-            this->is_targeted = true;
-            std::cout << "I am targeted!!" << std::endl;
-            std::cout << "And my position is:" << this->x << " " << this->y << std::endl;
-
-            for (Unit unit : unitVector)
-            {
-                if (unit.state == advanced_wars::UnitState::UNAVAILABLE)
-                {
-                    continue;
-                }
-
-                if (unit.is_selected)
-                {
-                    attacker = &unit;
-                }
-
-                if (unit.is_targeted)
-                {
-                    defender = &unit;
-                }
-            }
-
-            if (attacker != nullptr && defender != nullptr)
-            {
-                //attack(attacker, defender);
-                std::cout << "We are fighting!!" << std::endl;
-                break;
-            }
-            else
-            {
-                std::cerr << "Angriff konnte nicht gestartet werden!" << std::endl;
-                break;
-            }
-        }
+        std::cout << "Left-button pressed on unit: " << this->health << std::endl;
+        
     }
 
     bool Unit::inRange(Unit *enemy)
diff --git a/src/unit.hpp b/src/unit.hpp
index d836862..9550219 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -112,9 +112,9 @@ public:
 
 /*
 This function will be called by an external event-handler, eventually.
-Currently, it should be called if a Unit is interacted with and the resulting SDL_EVENT is passed through, and then decided upon
+It should start displaying standard unit information, such as UI and move_range
 */
-void onClick(SDL_Event event, std::vector<Unit> &unitVector);
+void on_left_click(SDL_Event event, std::vector<Unit> &unitVector);
 
 private:
   UnitFaction faction;
-- 
GitLab


From 19e1fdeca94821f7050c328546d8b6243602401f Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 12:26:08 +0100
Subject: [PATCH 21/30] Save work for soon

---
 src/level.cpp | 12 ++++--------
 src/unit.cpp  | 13 -------------
 2 files changed, 4 insertions(+), 21 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 0b241d1..a1e0b98 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -100,10 +100,6 @@ bool Level::selectBuilding (int tileX, int tileY) {
 
 void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
-  //handle following events:
-  //clicks/mouseDown
-  //escape (esc)
-
   switch (event.type)
   {
   case SDL_MOUSEBUTTONDOWN:
@@ -120,11 +116,11 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
             //building stuff
           }
 
-      } else {
+        } else {
 
-        std::cout << "Neither building nor unit clicked!" << std::endl;
-        selectedUnit = nullptr;
-        selectedBuilding = nullptr;
+          std::cout << "Neither building nor unit clicked!" << std::endl;
+          selectedUnit = nullptr;
+          selectedBuilding = nullptr;
 
       }
 
diff --git a/src/unit.cpp b/src/unit.cpp
index c0a4634..311e026 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -162,19 +162,6 @@ namespace advanced_wars
         this->y = posY;
     }
 
-/*
-Features:
-//select unit 
-    - show context menu
-    - show move range
-    - MAYBE show valid targets
-
-//deselect unit
-
-//attack unit
-    - show context menu
-
-*/
     void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector)
     {
 
-- 
GitLab


From 5b0d77b729f276b27c0daa966d40d3b89e80c897 Mon Sep 17 00:00:00 2001
From: Lorenz <lorenz-martin.diel@informatik.hs-fulda.de>
Date: Thu, 30 Jan 2025 13:05:02 +0100
Subject: [PATCH 22/30] Fixed Bug: units no longer dissappear when they are
 being placed

---
 src/level.cpp | 289 ++++++++++++++++++++++++++++----------------------
 src/unit.cpp  |  12 ++-
 2 files changed, 170 insertions(+), 131 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index 11d3b15..2ac150a 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -8,193 +8,224 @@
 #include <SDL.h>
 #include <iostream>
 #include <string>
-#include <algorithm> 
+#include <algorithm>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-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)
-    : name(name), width(width), height(height), tiles(tiles),
-      buildings(buildings), units(units), effects(effects) {
+  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)
+      : name(name), width(width), height(height), tiles(tiles),
+        buildings(buildings), units(units), effects(effects)
+  {
 
-  if ((size_t)(width * height) != tiles.size()) {
-    throw std::runtime_error("level tile mismatch");
-  }
-};
+    if ((size_t)(width * height) != tiles.size())
+    {
+      throw std::runtime_error("level tile mismatch");
+    }
+  };
 
-const int RENDERING_SCALE = 3;
+  const int RENDERING_SCALE = 3;
 
-bool Level::click_check_left(int mouseX, int mouseY) {
-  
-  int tileX = mouseX/(16*RENDERING_SCALE);
-  int tileY = mouseY/(16*RENDERING_SCALE);
+  bool Level::click_check_left(int mouseX, int mouseY)
+  {
 
-  if(selectUnit(tileX, tileY)) {
-    return true;
-  }
+    int tileX = mouseX / (16 * RENDERING_SCALE);
+    int tileY = mouseY / (16 * RENDERING_SCALE);
 
-  if(selectBuilding(tileX, tileY)) {
-    return true; 
-  } 
-    
-  return false;
-}
+    if (selectUnit(tileX, tileY))
+    {
+      return true;
+    }
 
-bool Level::click_check_right(int mouseX, int mouseY) {
-  
-  int tileX = mouseX/(16*RENDERING_SCALE);
-  int tileY = mouseY/(16*RENDERING_SCALE);
+    if (selectBuilding(tileX, tileY))
+    {
+      return true;
+    }
 
-  if(target_unit(tileX, tileY)) {
-    return true;
+    return false;
   }
-   
-  return false;
-}
 
-bool Level::selectUnit (int tileX, int tileY) {
+  bool Level::click_check_right(int mouseX, int mouseY)
+  {
 
-  //std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
-  for (auto& unit : units) {
+    int tileX = mouseX / (16 * RENDERING_SCALE);
+    int tileY = mouseY / (16 * RENDERING_SCALE);
 
-    if(unit.x == tileX && unit.y == tileY) {
-      //std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
-      
-      selectedUnit = &unit;
+    if (target_unit(tileX, tileY))
+    {
       return true;
     }
+
+    return false;
   }
-  
-  return false;
-}
 
-bool Level::target_unit (int tileX, int tileY) {
+  bool Level::selectUnit(int tileX, int tileY)
+  {
 
-  //std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
-  for (auto& unit : units) {
+    // std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
+    for (auto &unit : units)
+    {
 
-    if(unit.x == tileX && unit.y == tileY) {
-      //std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
-      
-      targetedUnit = &unit;
-      return true;
+      if (unit.x == tileX && unit.y == tileY)
+      {
+        // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
+
+        selectedUnit = &unit;
+        return true;
+      }
     }
+
+    return false;
   }
-  
-  return false;
-}
 
-bool Level::selectBuilding (int tileX, int tileY) {
+  bool Level::target_unit(int tileX, int tileY)
+  {
+
+    // std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
+    for (auto &unit : units)
+    {
 
-  for (auto& building : buildings) {
+      if (unit.x == tileX && unit.y == tileY)
+      {
+        // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
 
-    if(building.x == tileX && building.y == tileY) {
-      //std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
-      selectedBuilding = &building;
-      return true;
+        targetedUnit = &unit;
+        return true;
+      }
     }
+
+    return false;
   }
-  return false;
-}
 
-void Level::handleEvent(Engine &engine, SDL_Event &event) {
+  bool Level::selectBuilding(int tileX, int tileY)
+  {
 
-  //handle following events:
-  //clicks/mouseDown
-  //escape (esc)
+    for (auto &building : buildings)
+    {
 
-  switch (event.type)
+      if (building.x == tileX && building.y == tileY)
+      {
+        // std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+        selectedBuilding = &building;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void Level::handleEvent(Engine &engine, SDL_Event &event)
   {
-  case SDL_MOUSEBUTTONDOWN:
 
-      if (event.button.button == SDL_BUTTON_LEFT) {
+    // handle following events:
+    // clicks/mouseDown
+    // escape (esc)
+
+    switch (event.type)
+    {
+    case SDL_MOUSEBUTTONDOWN:
 
-        if(click_check_left(event.button.x, event.button.y)) {
-        
-          if(selectedUnit) {
+      if (event.button.button == SDL_BUTTON_LEFT)
+      {
+
+        if (click_check_left(event.button.x, event.button.y))
+        {
+
+          if (selectedUnit)
+          {
             selectedUnit->onClick(event, units);
           }
 
-          if(selectedBuilding) {
-            //building stuff
+          if (selectedBuilding)
+          {
+            // building stuff
           }
+        }
+        else
+        {
 
-      } else {
-
-        std::cout << "Neither building nor unit clicked!" << std::endl;
-        selectedUnit = nullptr;
-        selectedBuilding = nullptr;
-
+          std::cout << "Neither building nor unit clicked!" << std::endl;
+          selectedUnit = nullptr;
+          selectedBuilding = nullptr;
+        }
       }
+      else if (event.button.button == SDL_BUTTON_RIGHT)
+      {
 
-      } else if (event.button.button == SDL_BUTTON_RIGHT) {
-
-        if(selectedUnit) {
-
-          int tileX = event.button.x;
-          int tileY = event.button.y;
-
-          if(click_check_right(tileX, tileY)) {
+        if (selectedUnit)
+        {
 
+          if (click_check_right(event.button.x, event.button.y))
+          {
+            
             selectedUnit->attack(targetedUnit);
 
             units.erase(
-            std::remove_if(units.begin(), units.end(),
-                       [](const Unit& unit) { return unit.health < 0; }),
-            units.end());
-
-          } else {
-            
-            
+                std::remove_if(units.begin(), units.end(),
+                               [](const Unit &unit)
+                               { return unit.health < 0; }),
+                units.end());
+          }
+          else
+          {
+            int tileX = event.button.x / (16 * RENDERING_SCALE);
+            int tileY = event.button.y / (16 * RENDERING_SCALE);
 
             selectedUnit->update_position(tileX, tileY);
-
           }
-        } else {
+        }
+        else
+        {
 
           std::cout << "No unit selected! " << std::endl;
-
-        }
         }
       }
+    }
   }
 
-void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
-  
-  // Iterate over all events
-  while (!events.empty()) {
-    //events.erase(events.begin());
+  void Level::render(Engine &engine, std::vector<SDL_Event> &events)
+  {
 
-    handleEvent(engine, events.at(0));
-    events.erase(events.begin());
-  }
+    // Iterate over all events
+    while (!events.empty())
+    {
+      // events.erase(events.begin());
 
-  // Tiles
-  for (Tile &tile : tiles) {
-    tile.render(engine, RENDERING_SCALE);
-  }
+      handleEvent(engine, events.at(0));
+      events.erase(events.begin());
+    }
 
-  // Buildings
-  for (Building &building : buildings) {
-    building.render(engine, RENDERING_SCALE);
-  }
+    // Tiles
+    for (Tile &tile : tiles)
+    {
+      tile.render(engine, RENDERING_SCALE);
+    }
 
-  // Units
-  for (Unit &unit : units) {
-    unit.render(engine, RENDERING_SCALE);
-  }
+    // Buildings
+    for (Building &building : buildings)
+    {
+      building.render(engine, RENDERING_SCALE);
+    }
 
-  // Effects
-  for (Effect &effect : effects) {
-    effect.render(engine, RENDERING_SCALE);
-  }
+    // Units
+    for (Unit &unit : units)
+    {
+      unit.render(engine, RENDERING_SCALE);
+    }
 
-  // Set background color for renderer
-  if (SDL_SetRenderDrawColor(engine.renderer(), 255, 0, 0, 0)) {
-    std::cout << "Could not set render draw color: " << SDL_GetError()
-              << std::endl;
+    // Effects
+    for (Effect &effect : effects)
+    {
+      effect.render(engine, RENDERING_SCALE);
+    }
+
+    // Set background color for renderer
+    if (SDL_SetRenderDrawColor(engine.renderer(), 255, 0, 0, 0))
+    {
+      std::cout << "Could not set render draw color: " << SDL_GetError()
+                << std::endl;
+    }
   }
-}
 
 } // namespace advanced_wars
diff --git a/src/unit.cpp b/src/unit.cpp
index 1d9b293..21b0735 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -74,10 +74,14 @@ namespace advanced_wars
         secondary_weapon = fill_matchupTable(0);
         primary_weapon = fill_matchupTable(1);
 
+        
+
         // Zuerst die Tabel für die Waffen der angreifenden Einheit holen
         auto &attackerSecondaryWeaponTable = secondary_weapon[this->id];
         auto &attackerPrimaryWeaponTable = primary_weapon[this->id];
 
+        
+
         // Schadenswert für die angreifende Einheit gegen die verteidigende Einheit berechnen
         // Es wird die Waffe genommen die mehr Schaden macht
 
@@ -87,6 +91,7 @@ namespace advanced_wars
         {
             attackerDamageValue = attackerSecondaryWeaponTable[enemy->id];
         }
+        
         if (attackerPrimaryWeaponTable.find(enemy->id) != attackerPrimaryWeaponTable.end())
         {
             if (attackerDamageValue < attackerPrimaryWeaponTable[enemy->id])
@@ -96,6 +101,8 @@ namespace advanced_wars
             }
         }
 
+        
+
         if (attackerDamageValue == 0)
         {
             std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
@@ -159,8 +166,9 @@ namespace advanced_wars
     void Unit::update_position(int posX, int posY)
     {
         this->x = posX;
-        this->y = posY;
-    }
+        this->y = posY;       
+    }      
+    
 
 /*
 Features:
-- 
GitLab


From 97a2125b26289a1038a08b60e0fa40dcbd56dcb4 Mon Sep 17 00:00:00 2001
From: Lorenz <lorenz-martin.diel@informatik.hs-fulda.de>
Date: Thu, 30 Jan 2025 15:28:24 +0100
Subject: [PATCH 23/30] adjusted attack function on DamageTable in weapon

---
 src/unit.cpp   | 114 +++++++++++++++++++++++--------------------------
 src/unit.hpp   |   4 +-
 src/weapon.cpp |  26 ++++++++++-
 src/weapon.hpp |  22 +++++++---
 4 files changed, 96 insertions(+), 70 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index 21b0735..81f4312 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -7,6 +7,11 @@ namespace advanced_wars
     Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
         : x(x), y(y), faction(faction), id(id), state(state), max_health(100)
     {
+        //das ist nur für Testzwecke
+        if (id == UnitId::INFANTERY)
+        {
+            secondary_weapon = Weapon("Machine-Gun", {{UnitId::INFANTERY, 55}});
+        }
         health = max_health;
     };
 
@@ -68,82 +73,71 @@ namespace advanced_wars
                              &src, &dst, 0, NULL, SDL_FLIP_NONE);
         }
     }
-    
-    void Unit::attack(Unit *enemy)
-    {   
-        secondary_weapon = fill_matchupTable(0);
-        primary_weapon = fill_matchupTable(1);
-
-        
 
-        // Zuerst die Tabel für die Waffen der angreifenden Einheit holen
-        auto &attackerSecondaryWeaponTable = secondary_weapon[this->id];
-        auto &attackerPrimaryWeaponTable = primary_weapon[this->id];
-
-        
-
-        // Schadenswert für die angreifende Einheit gegen die verteidigende Einheit berechnen
-        // Es wird die Waffe genommen die mehr Schaden macht
+    void Unit::attack(Unit *enemy)
+    {
+        // Angenommen, primary_weapon und secondary_weapon wurden bereits korrekt initialisiert
+        auto primary_weapon_damage_it = primary_weapon.damage.find(enemy->id);
+        auto secondary_weapon_damage_it = secondary_weapon.damage.find(enemy->id);
 
-        int attackerDamageValue = 0;
+        int attacker_damage_value = 0;
 
-        if (attackerSecondaryWeaponTable.find(enemy->id) != attackerSecondaryWeaponTable.end())
+        // Die Waffe mit dem höchsten Schaden wählen
+        if (secondary_weapon_damage_it != secondary_weapon.damage.end())
         {
-            attackerDamageValue = attackerSecondaryWeaponTable[enemy->id];
+            attacker_damage_value = secondary_weapon_damage_it->second;
         }
-        
-        if (attackerPrimaryWeaponTable.find(enemy->id) != attackerPrimaryWeaponTable.end())
+
+        if (primary_weapon_damage_it != primary_weapon.damage.end())
         {
-            if (attackerDamageValue < attackerPrimaryWeaponTable[enemy->id])
+            if (primary_weapon_damage_it->second > attacker_damage_value)
             {
-                // Here ammo deduction should happen if applicable
-                attackerDamageValue = attackerPrimaryWeaponTable[enemy->id];
+                // Munitionsabzug sollte hier erfolgen, falls zutreffend
+                attacker_damage_value = primary_weapon_damage_it->second;
             }
         }
 
-        
-
-        if (attackerDamageValue == 0)
+        if (attacker_damage_value == 0)
         {
             std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
                       << " against unit " << static_cast<int>(enemy->id) << std::endl;
         }
         else
         {
-
-            int offDamage = attackerDamageValue * (static_cast<float>(health) / max_health);
-            enemy->health -= offDamage;
-            enemy->health = std::max(0, enemy->health); // Ensuring health is not negative
+            int off_damage = attacker_damage_value * (static_cast<float>(health) / max_health);
+            enemy->health -= off_damage;
+            enemy->health = std::max(0, enemy->health); // Sicherstellen, dass die Gesundheit nicht negativ wird
             std::cout << "Enemy health after attack: " << enemy->health << std::endl;
 
             // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
             if (enemy->health > 0)
             {
                 // Weapon tables for the defender
-                auto &defenderSecondaryWeaponTable = secondary_weapon[enemy->id];
-                auto &defenderPrimaryWeaponTable = primary_weapon[enemy->id];
+                auto defender_primary_weapon_damage_it = enemy->primary_weapon.damage.find(id);
+                auto defender_secondary_weapon_damage_it = enemy->secondary_weapon.damage.find(id);
 
-                int defenderDamageValue = 0; // Declare outside for later use
+                int defender_damage_value = 0; // Declare outside for later use
 
                 // Determine the damage value for the defender
-                if (defenderSecondaryWeaponTable.find(id) != defenderSecondaryWeaponTable.end())
+                if (defender_secondary_weapon_damage_it != enemy->secondary_weapon.damage.end())
                 {
-                    defenderDamageValue = defenderSecondaryWeaponTable[id];
+                    defender_damage_value = defender_secondary_weapon_damage_it->second;
                 }
-                if (defenderPrimaryWeaponTable.find(id) != defenderPrimaryWeaponTable.end())
+
+                if (defender_primary_weapon_damage_it != enemy->primary_weapon.damage.end())
                 {
-                    if (defenderDamageValue < defenderPrimaryWeaponTable[id])
+                    if (defender_primary_weapon_damage_it->second > defender_damage_value)
                     {
-                        // Deduct ammo for primary weapon, if applicable
-                        defenderDamageValue = defenderPrimaryWeaponTable[id];
+                        // Munitionsabzug für primäre Waffe, falls zutreffend
+                        defender_damage_value = defender_primary_weapon_damage_it->second;
                     }
                 }
 
                 // If a valid damage value was determined for retaliation
-                if (defenderDamageValue > 0)
+                if (defender_damage_value > 0)
                 {
-                    int defDamage = static_cast<int>(defenderDamageValue * static_cast<float>(enemy->health) / enemy->max_health);
-                    this->health -= defDamage;
+                    int def_damage = static_cast<int>(defender_damage_value * static_cast<float>(enemy->health) / enemy->max_health);
+                    this->health -= def_damage;
                     this->health = std::max(0, this->health); // Safeguard against negative health
                     std::cout << "Ally health after retaliation: " << this->health << std::endl;
                 }
@@ -151,13 +145,14 @@ namespace advanced_wars
         }
     }
 
-    MatchupTable Unit::fill_matchupTable(int type) {
+    MatchupTable Unit::fill_matchupTable(int type)
+    {
         switch (type)
         {
         case 0:
-            
+
             break;
-        
+
         default:
             break;
         }
@@ -166,23 +161,22 @@ namespace advanced_wars
     void Unit::update_position(int posX, int posY)
     {
         this->x = posX;
-        this->y = posY;       
-    }      
-    
+        this->y = posY;
+    }
 
-/*
-Features:
-//select unit 
-    - show context menu
-    - show move range
-    - MAYBE show valid targets
+    /*
+    Features:
+    //select unit
+        - show context menu
+        - show move range
+        - MAYBE show valid targets
 
-//deselect unit
+    //deselect unit
 
-//attack unit
-    - show context menu
+    //attack unit
+        - show context menu
 
-*/
+    */
     void Unit::onClick(SDL_Event event, std::vector<Unit> &unitVector)
     {
 
@@ -198,7 +192,7 @@ Features:
             std::cout << "I am selected!!" << std::endl;
             std::cout << "And my position is:" << this->x << " " << this->y << std::endl;
 
-           //make move range calc
+            // make move range calc
 
             break;
         case SDL_BUTTON_RIGHT:
@@ -227,7 +221,7 @@ Features:
 
             if (attacker != nullptr && defender != nullptr)
             {
-                //attack(attacker, defender);
+                // attack(attacker, defender);
                 std::cout << "We are fighting!!" << std::endl;
                 break;
             }
diff --git a/src/unit.hpp b/src/unit.hpp
index d836862..ca588ea 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -131,8 +131,8 @@ private:
   bool has_attacked;
   bool is_selected;
   bool is_targeted;
-  MatchupTable secondary_weapon;
-  MatchupTable primary_weapon;
+  Weapon secondary_weapon;
+  Weapon primary_weapon;
 
   int ammo;
  
diff --git a/src/weapon.cpp b/src/weapon.cpp
index 650e950..b93d09c 100644
--- a/src/weapon.cpp
+++ b/src/weapon.cpp
@@ -1,3 +1,27 @@
 #include "weapon.hpp"
 
-namespace advanced_wars {}
\ No newline at end of file
+namespace advanced_wars
+{
+    Weapon::Weapon() : name(""), damage() {}
+
+    Weapon::Weapon(const std::string &weaponName, const std::unordered_map<UnitId, int> &damageValues)
+        : name(weaponName), damage(damageValues) {}
+
+    // Funktion zum Hinzufügen von Schadenswerten
+    void Weapon::addDamageValue(UnitId unitId, int value)
+    {
+        damage[unitId] = value;
+    }
+
+    // Funktion zum Abrufen eines Schadenswertes
+    int Weapon::getDamageValue(UnitId unitId) const
+    {
+        auto it = damage.find(unitId);
+        if (it != damage.end())
+        {
+            return it->second;
+        }
+        return 0; // oder ein Fehlerwert
+    }
+
+}
\ No newline at end of file
diff --git a/src/weapon.hpp b/src/weapon.hpp
index 753e674..2192e61 100644
--- a/src/weapon.hpp
+++ b/src/weapon.hpp
@@ -1,21 +1,29 @@
 #pragma once
 
-#include "unit.hpp"
+#include <string>
 #include <unordered_map>
 
 namespace advanced_wars {
 
-// Forward Declaration
 enum class UnitId;
 
 class Weapon {
 public:
-  // Ranges
-  int min_range;
-  int max_range;
+  // Konstruktoren
+  Weapon();
+  Weapon(const std::string &weaponName, const std::unordered_map<UnitId, int> &damageValues);
 
-  // Damage
+  // Methode, um einen Schadenswert hinzuzufügen
+  void addDamageValue(UnitId unitId, int value);
+
+  // Methode, um einen Schadenswert abzurufen
+  int getDamageValue(UnitId unitId) const;
+
+  // Name der Waffe
+  std::string name;
+
+  // Schadenstabelle
   std::unordered_map<UnitId, int> damage;
 };
 
-} // namespace advanced_wars
\ No newline at end of file
+} // namespace advanced_wars
-- 
GitLab


From 645c9bc0298e161b94cbf646e2997d56ba0eb2c6 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 16:27:25 +0100
Subject: [PATCH 24/30] Add responsive Unitstates for movement

---
 src/level.cpp |   4 +-
 src/unit.cpp  | 125 +++++++++++++++++++-------------------------------
 src/unit.hpp  |   3 +-
 3 files changed, 51 insertions(+), 81 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index a1e0b98..f1eec01 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -128,8 +128,8 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
         if(selectedUnit) {
 
-          int tileX = event.button.x;
-          int tileY = event.button.y;
+          int tileX = event.button.x / (16*RENDERING_SCALE);
+          int tileY = event.button.y / (16*RENDERING_SCALE);
 
           if(click_check_right(tileX, tileY)) {
 
diff --git a/src/unit.cpp b/src/unit.cpp
index 311e026..a2e2d80 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -69,97 +69,66 @@ namespace advanced_wars
         }
     }
     
-    void Unit::attack(Unit *enemy)
-    {   
-        secondary_weapon = fill_matchupTable(0);
-        primary_weapon = fill_matchupTable(1);
+    void Unit::attack(Unit* enemy) {
 
-        // Zuerst die Tabel für die Waffen der angreifenden Einheit holen
-        auto &attackerSecondaryWeaponTable = secondary_weapon[this->id];
-        auto &attackerPrimaryWeaponTable = primary_weapon[this->id];
+        int offDamage = 50;
+        int defDamage = 50;
 
-        // Schadenswert für die angreifende Einheit gegen die verteidigende Einheit berechnen
-        // Es wird die Waffe genommen die mehr Schaden macht
+        enemy->health = enemy->health - offDamage;
+        std::cout << "Enemy health:" << enemy->health << std::endl;
+        if (enemy->health > 0) {
+            this->health = this->health - defDamage;
+            std::cout << "Health ally:" << this->health << std::endl;
+        }
+    }
 
-        int attackerDamageValue = 0;
 
-        if (attackerSecondaryWeaponTable.find(enemy->id) != attackerSecondaryWeaponTable.end())
-        {
-            attackerDamageValue = attackerSecondaryWeaponTable[enemy->id];
-        }
-        if (attackerPrimaryWeaponTable.find(enemy->id) != attackerPrimaryWeaponTable.end())
-        {
-            if (attackerDamageValue < attackerPrimaryWeaponTable[enemy->id])
-            {
-                // Here ammo deduction should happen if applicable
-                attackerDamageValue = attackerPrimaryWeaponTable[enemy->id];
+    void Unit::update_position(int posX, int posY)
+    {
+        calc_state(posX, posY);
+
+        this->x = posX;
+        this->y = posY;
+    }
+
+    void Unit::calc_state(int posX, int posY) {
+
+        int currentX = this->x;
+        int currentY = this->y;
+
+        int deltaX = currentX - posX;
+        int deltaY = currentY - posY;
+
+        if (deltaY == 0) {
+            if (deltaX > 0) {
+                this->state = advanced_wars::UnitState::MOVEMENTLEFT;
+                return;
+            } else {
+                this->state = advanced_wars::UnitState::MOVEMENTRIGHT;
+                return;
             }
         }
 
-        if (attackerDamageValue == 0)
-        {
-            std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
-                      << " against unit " << static_cast<int>(enemy->id) << std::endl;
-        }
-        else
-        {
+        double bresen = deltaX/deltaY;
 
-            int offDamage = attackerDamageValue * (static_cast<float>(health) / max_health);
-            enemy->health -= offDamage;
-            enemy->health = std::max(0, enemy->health); // Ensuring health is not negative
-            std::cout << "Enemy health after attack: " << enemy->health << std::endl;
-
-            // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
-            if (enemy->health > 0)
-            {
-                // Weapon tables for the defender
-                auto &defenderSecondaryWeaponTable = secondary_weapon[enemy->id];
-                auto &defenderPrimaryWeaponTable = primary_weapon[enemy->id];
-
-                int defenderDamageValue = 0; // Declare outside for later use
-
-                // Determine the damage value for the defender
-                if (defenderSecondaryWeaponTable.find(id) != defenderSecondaryWeaponTable.end())
-                {
-                    defenderDamageValue = defenderSecondaryWeaponTable[id];
-                }
-                if (defenderPrimaryWeaponTable.find(id) != defenderPrimaryWeaponTable.end())
-                {
-                    if (defenderDamageValue < defenderPrimaryWeaponTable[id])
-                    {
-                        // Deduct ammo for primary weapon, if applicable
-                        defenderDamageValue = defenderPrimaryWeaponTable[id];
-                    }
-                }
-
-                // If a valid damage value was determined for retaliation
-                if (defenderDamageValue > 0)
-                {
-                    int defDamage = static_cast<int>(defenderDamageValue * static_cast<float>(enemy->health) / enemy->max_health);
-                    this->health -= defDamage;
-                    this->health = std::max(0, this->health); // Safeguard against negative health
-                    std::cout << "Ally health after retaliation: " << this->health << std::endl;
-                }
+        if(bresen == 0) {
+            if(deltaY < 0) {
+                this->state = advanced_wars::UnitState::MOVEMENTDOWN;
+                return;
+            } else {
+                this->state = advanced_wars::UnitState::MOVEMENTUP;
+                return;
             }
         }
-    }
 
-    MatchupTable Unit::fill_matchupTable(int type) {
-        switch (type)
-        {
-        case 0:
-            
-            break;
-        
-        default:
-            break;
+        if(0 < bresen && bresen < 1) {
+            this->state = advanced_wars::UnitState::MOVEMENTDOWN;
+            return;
+        } else if (-1 < bresen && bresen < 0) {
+            this->state = advanced_wars::UnitState::MOVEMENTUP;
+            return;
         }
-    }
 
-    void Unit::update_position(int posX, int posY)
-    {
-        this->x = posX;
-        this->y = posY;
     }
 
     void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector)
diff --git a/src/unit.hpp b/src/unit.hpp
index 9550219..ad189e8 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -87,7 +87,7 @@ public:
   Attacker deals damage to the defender first
   */
 
-  void attack(Unit *enemy);
+  void attack(Unit* enemy) ;
 
 
   /*
@@ -103,6 +103,7 @@ public:
   */
   void calculate_movement();
 
+  void calc_state(int posX, int posY);
 
   /*
   This function fills the MatchupTable
-- 
GitLab


From cce05dedc0871144d0c69df4e8e1cb7921a59955 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 16:36:40 +0100
Subject: [PATCH 25/30] fix bug concerning moving and attacking

---
 src/level.cpp | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/level.cpp b/src/level.cpp
index f1eec01..456bb40 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -25,11 +25,8 @@ Level::Level(std::string name, int width, int height, std::vector<Tile> tiles,
 
 const int RENDERING_SCALE = 3;
 
-bool Level::click_check_left(int mouseX, int mouseY) {
+bool Level::click_check_left(int tileX, int tileY) {
   
-  int tileX = mouseX/(16*RENDERING_SCALE);
-  int tileY = mouseY/(16*RENDERING_SCALE);
-
   if(selectUnit(tileX, tileY)) {
     return true;
   }
@@ -41,10 +38,7 @@ bool Level::click_check_left(int mouseX, int mouseY) {
   return false;
 }
 
-bool Level::click_check_right(int mouseX, int mouseY) {
-  
-  int tileX = mouseX/(16*RENDERING_SCALE);
-  int tileY = mouseY/(16*RENDERING_SCALE);
+bool Level::click_check_right(int tileX, int tileY) {
 
   if(target_unit(tileX, tileY)) {
     return true;
@@ -106,7 +100,10 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
       if (event.button.button == SDL_BUTTON_LEFT) {
 
-        if(click_check_left(event.button.x, event.button.y)) {
+        int tileX = event.button.x/(16*RENDERING_SCALE);
+        int tileY = event.button.y/(16*RENDERING_SCALE);
+
+        if(click_check_left(tileX,tileY)) {
         
           if(selectedUnit) {
             selectedUnit->on_left_click(event, units);
@@ -137,7 +134,7 @@ void Level::handleEvent(Engine &engine, SDL_Event &event) {
 
             units.erase(
             std::remove_if(units.begin(), units.end(),
-                       [](const Unit& unit) { return unit.health < 0; }),
+                       [](const Unit& unit) { return unit.health <= 0; }),
             units.end());
 
           } else {
-- 
GitLab


From 7fb409a0023a016759ef047ee766910a64e2cda5 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 19:02:04 +0100
Subject: [PATCH 26/30] Removed unnecessary function

---
 src/unit.cpp | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index c71a0c0..af4a42d 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -145,19 +145,6 @@ namespace advanced_wars
         }
     }
 
-    MatchupTable Unit::fill_matchupTable(int type)
-    {
-        switch (type)
-        {
-        case 0:
-
-            break;
-
-        default:
-            break;
-        }
-    }
-
     void Unit::update_position(int posX, int posY)
     {
         calc_state(posX, posY);
-- 
GitLab


From e1c9cb119335a7eb806d1ac662fea8905bc1cb55 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 19:21:30 +0100
Subject: [PATCH 27/30] Cut some function parts from calc_state

---
 src/unit.cpp | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index af4a42d..d73e6b2 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -163,10 +163,10 @@ namespace advanced_wars
 
         if (deltaY == 0) {
             if (deltaX > 0) {
-                this->state = advanced_wars::UnitState::MOVEMENTLEFT;
+                this->state = UnitState::MOVEMENTLEFT;
                 return;
             } else {
-                this->state = advanced_wars::UnitState::MOVEMENTRIGHT;
+                this->state = UnitState::MOVEMENTRIGHT;
                 return;
             }
         }
@@ -175,22 +175,13 @@ namespace advanced_wars
 
         if(bresen == 0) {
             if(deltaY < 0) {
-                this->state = advanced_wars::UnitState::MOVEMENTDOWN;
+                this->state = UnitState::MOVEMENTDOWN;
                 return;
             } else {
-                this->state = advanced_wars::UnitState::MOVEMENTUP;
+                this->state = UnitState::MOVEMENTUP;
                 return;
             }
         }
-
-        if(0 < bresen && bresen < 1) {
-            this->state = advanced_wars::UnitState::MOVEMENTDOWN;
-            return;
-        } else if (-1 < bresen && bresen < 0) {
-            this->state = advanced_wars::UnitState::MOVEMENTUP;
-            return;
-        }
-
     }
 
     void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector)
-- 
GitLab


From 6692c6ddae5a32f1500f24108380e7e3523619d5 Mon Sep 17 00:00:00 2001
From: Max Cherris <MCherris@protonmail.com>
Date: Thu, 30 Jan 2025 19:24:07 +0100
Subject: [PATCH 28/30] Fix unit hpp

---
 src/unit.hpp | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/unit.hpp b/src/unit.hpp
index bac964c..722e52f 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -103,14 +103,9 @@ public:
   */
   void calculate_movement();
 
+  
   void calc_state(int posX, int posY);
 
-  /*
-  This function fills the MatchupTable
-  It would be better if this table would be placed in the level
-  */
- MatchupTable fill_matchupTable(int);
-
 /*
 This function will be called by an external event-handler, eventually.
 It should start displaying standard unit information, such as UI and move_range
-- 
GitLab


From 07726a73e3c2729e799874c5aa63b83e0165d13d Mon Sep 17 00:00:00 2001
From: Lorenz <lorenz-martin.diel@informatik.hs-fulda.de>
Date: Thu, 30 Jan 2025 20:56:15 +0100
Subject: [PATCH 29/30] Adjusted and refactored the function calc_state

---
 src/unit.cpp | 374 ++++++++++++++++++++++++---------------------------
 1 file changed, 177 insertions(+), 197 deletions(-)

diff --git a/src/unit.cpp b/src/unit.cpp
index d73e6b2..c938f48 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,207 +1,187 @@
 #include "unit.hpp"
 #include <iostream>
 
-namespace advanced_wars
-{
-
-    Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
-        : x(x), y(y), faction(faction), id(id), state(state), max_health(100)
-    {
-        //das ist nur für Testzwecke
-        if (id == UnitId::INFANTERY)
-        {
-            secondary_weapon = Weapon("Machine-Gun", {{UnitId::INFANTERY, 55}});
-        }
-        health = max_health;
-    };
-
-    void Unit::render(Engine &engine, int scale)
-    {
-        Spritesheet *spritesheet = engine.get_spritesheet();
-
-        int step = engine.get_stage() % spritesheet->get_unit_textures()
-                                            .at(static_cast<int>(faction))
-                                            .at(static_cast<int>(id))
-                                            .at(static_cast<int>(state))
-                                            .second;
-
-        if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE)
-        {
-
-            SDL_Rect src;
-            src.x = step * spritesheet->get_unit_width();
-            src.y = 0;
-            src.w = spritesheet->get_unit_width();
-            src.h = spritesheet->get_unit_height();
-
-            SDL_Rect dst;
-            dst.x = x * spritesheet->get_unit_width() * scale;
-            dst.y = y * spritesheet->get_unit_height() * scale;
-            dst.w = spritesheet->get_unit_width() * scale;
-            dst.h = spritesheet->get_unit_height() * scale;
-
-            SDL_RenderCopyEx(engine.renderer(),
-                             spritesheet->get_unit_textures()
-                                 .at(static_cast<int>(faction))
-                                 .at(static_cast<int>(id))
-                                 .at(static_cast<int>(state))
-                                 .first,
-                             &src, &dst, 0, NULL, SDL_FLIP_NONE);
-        }
-        else
-        {
-            // The moving states have a resolution of 24x24 instead of 16x16 and need to
-            // be handled separately
-            SDL_Rect src;
-            src.x = step * spritesheet->get_unit_moving_width();
-            src.y = 0;
-            src.w = spritesheet->get_unit_moving_width();
-            src.h = spritesheet->get_unit_moving_height();
-
-            SDL_Rect dst;
-            dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
-            dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
-            dst.w = spritesheet->get_unit_moving_width() * scale;
-            dst.h = spritesheet->get_unit_moving_height() * scale;
-
-            SDL_RenderCopyEx(engine.renderer(),
-                             spritesheet->get_unit_textures()
-                                 .at(static_cast<int>(faction))
-                                 .at(static_cast<int>(id))
-                                 .at(static_cast<int>(state))
-                                 .first,
-                             &src, &dst, 0, NULL, SDL_FLIP_NONE);
-        }
-    }
-
-    void Unit::attack(Unit *enemy)
-    {
-        // Angenommen, primary_weapon und secondary_weapon wurden bereits korrekt initialisiert
-        auto primary_weapon_damage_it = primary_weapon.damage.find(enemy->id);
-        auto secondary_weapon_damage_it = secondary_weapon.damage.find(enemy->id);
-
-        int attacker_damage_value = 0;
-
-        // Die Waffe mit dem höchsten Schaden wählen
-        if (secondary_weapon_damage_it != secondary_weapon.damage.end())
-        {
-            attacker_damage_value = secondary_weapon_damage_it->second;
-        }
-
-        if (primary_weapon_damage_it != primary_weapon.damage.end())
-        {
-            if (primary_weapon_damage_it->second > attacker_damage_value)
-            {
-                // Munitionsabzug sollte hier erfolgen, falls zutreffend
-                attacker_damage_value = primary_weapon_damage_it->second;
-            }
-        }
-
-        if (attacker_damage_value == 0)
-        {
-            std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
-                      << " against unit " << static_cast<int>(enemy->id) << std::endl;
-        }
-        else
-        {
-            int off_damage = attacker_damage_value * (static_cast<float>(health) / max_health);
-            enemy->health -= off_damage;
-            enemy->health = std::max(0, enemy->health); // Sicherstellen, dass die Gesundheit nicht negativ wird
-            std::cout << "Enemy health after attack: " << enemy->health << std::endl;
-
-            // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
-            if (enemy->health > 0)
-            {
-                // Weapon tables for the defender
-                auto defender_primary_weapon_damage_it = enemy->primary_weapon.damage.find(id);
-                auto defender_secondary_weapon_damage_it = enemy->secondary_weapon.damage.find(id);
-
-                int defender_damage_value = 0; // Declare outside for later use
-
-                // Determine the damage value for the defender
-                if (defender_secondary_weapon_damage_it != enemy->secondary_weapon.damage.end())
-                {
-                    defender_damage_value = defender_secondary_weapon_damage_it->second;
-                }
-
-                if (defender_primary_weapon_damage_it != enemy->primary_weapon.damage.end())
-                {
-                    if (defender_primary_weapon_damage_it->second > defender_damage_value)
-                    {
-                        // Munitionsabzug für primäre Waffe, falls zutreffend
-                        defender_damage_value = defender_primary_weapon_damage_it->second;
-                    }
-                }
-
-                // If a valid damage value was determined for retaliation
-                if (defender_damage_value > 0)
-                {
-                    int def_damage = static_cast<int>(defender_damage_value * static_cast<float>(enemy->health) / enemy->max_health);
-                    this->health -= def_damage;
-                    this->health = std::max(0, this->health); // Safeguard against negative health
-                    std::cout << "Ally health after retaliation: " << this->health << std::endl;
-                }
-            }
-        }
-    }
-
-    void Unit::update_position(int posX, int posY)
-    {
-        calc_state(posX, posY);
-
-        this->x = posX;
-        this->y = posY;
+namespace advanced_wars {
+
+Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
+    : x(x), y(y), faction(faction), id(id), state(state), max_health(100) {
+  // das ist nur für Testzwecke
+  if (id == UnitId::INFANTERY) {
+    secondary_weapon = Weapon("Machine-Gun", {{UnitId::INFANTERY, 55}});
+  }
+  health = max_health;
+};
+
+void Unit::render(Engine &engine, int scale) {
+  Spritesheet *spritesheet = engine.get_spritesheet();
+
+  int step = engine.get_stage() % spritesheet->get_unit_textures()
+                                      .at(static_cast<int>(faction))
+                                      .at(static_cast<int>(id))
+                                      .at(static_cast<int>(state))
+                                      .second;
+
+  if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE) {
+
+    SDL_Rect src;
+    src.x = step * spritesheet->get_unit_width();
+    src.y = 0;
+    src.w = spritesheet->get_unit_width();
+    src.h = spritesheet->get_unit_height();
+
+    SDL_Rect dst;
+    dst.x = x * spritesheet->get_unit_width() * scale;
+    dst.y = y * spritesheet->get_unit_height() * scale;
+    dst.w = spritesheet->get_unit_width() * scale;
+    dst.h = spritesheet->get_unit_height() * scale;
+
+    SDL_RenderCopyEx(engine.renderer(),
+                     spritesheet->get_unit_textures()
+                         .at(static_cast<int>(faction))
+                         .at(static_cast<int>(id))
+                         .at(static_cast<int>(state))
+                         .first,
+                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
+  } else {
+    // The moving states have a resolution of 24x24 instead of 16x16 and need to
+    // be handled separately
+    SDL_Rect src;
+    src.x = step * spritesheet->get_unit_moving_width();
+    src.y = 0;
+    src.w = spritesheet->get_unit_moving_width();
+    src.h = spritesheet->get_unit_moving_height();
+
+    SDL_Rect dst;
+    dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
+    dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
+    dst.w = spritesheet->get_unit_moving_width() * scale;
+    dst.h = spritesheet->get_unit_moving_height() * scale;
+
+    SDL_RenderCopyEx(engine.renderer(),
+                     spritesheet->get_unit_textures()
+                         .at(static_cast<int>(faction))
+                         .at(static_cast<int>(id))
+                         .at(static_cast<int>(state))
+                         .first,
+                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
+  }
+}
+
+void Unit::attack(Unit *enemy) {
+  // Angenommen, primary_weapon und secondary_weapon wurden bereits korrekt
+  // initialisiert
+  auto primary_weapon_damage_it = primary_weapon.damage.find(enemy->id);
+  auto secondary_weapon_damage_it = secondary_weapon.damage.find(enemy->id);
+
+  int attacker_damage_value = 0;
+
+  // Die Waffe mit dem höchsten Schaden wählen
+  if (secondary_weapon_damage_it != secondary_weapon.damage.end()) {
+    attacker_damage_value = secondary_weapon_damage_it->second;
+  }
+
+  if (primary_weapon_damage_it != primary_weapon.damage.end()) {
+    if (primary_weapon_damage_it->second > attacker_damage_value) {
+      // Munitionsabzug sollte hier erfolgen, falls zutreffend
+      attacker_damage_value = primary_weapon_damage_it->second;
     }
-
-    void Unit::calc_state(int posX, int posY) {
-
-        int currentX = this->x;
-        int currentY = this->y;
-
-        int deltaX = currentX - posX;
-        int deltaY = currentY - posY;
-
-        if (deltaY == 0) {
-            if (deltaX > 0) {
-                this->state = UnitState::MOVEMENTLEFT;
-                return;
-            } else {
-                this->state = UnitState::MOVEMENTRIGHT;
-                return;
-            }
-        }
-
-        double bresen = deltaX/deltaY;
-
-        if(bresen == 0) {
-            if(deltaY < 0) {
-                this->state = UnitState::MOVEMENTDOWN;
-                return;
-            } else {
-                this->state = UnitState::MOVEMENTUP;
-                return;
-            }
+  }
+
+  if (attacker_damage_value == 0) {
+    std::cout << "No damage value found for attack from unit "
+              << static_cast<int>(id) << " against unit "
+              << static_cast<int>(enemy->id) << std::endl;
+  } else {
+    int off_damage =
+        attacker_damage_value * (static_cast<float>(health) / max_health);
+    enemy->health -= off_damage;
+    enemy->health = std::max(
+        0,
+        enemy->health); // Sicherstellen, dass die Gesundheit nicht negativ wird
+    std::cout << "Enemy health after attack: " << enemy->health << std::endl;
+
+    // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
+    if (enemy->health > 0) {
+      // Weapon tables for the defender
+      auto defender_primary_weapon_damage_it =
+          enemy->primary_weapon.damage.find(id);
+      auto defender_secondary_weapon_damage_it =
+          enemy->secondary_weapon.damage.find(id);
+
+      int defender_damage_value = 0; // Declare outside for later use
+
+      // Determine the damage value for the defender
+      if (defender_secondary_weapon_damage_it !=
+          enemy->secondary_weapon.damage.end()) {
+        defender_damage_value = defender_secondary_weapon_damage_it->second;
+      }
+
+      if (defender_primary_weapon_damage_it !=
+          enemy->primary_weapon.damage.end()) {
+        if (defender_primary_weapon_damage_it->second > defender_damage_value) {
+          // Munitionsabzug für primäre Waffe, falls zutreffend
+          defender_damage_value = defender_primary_weapon_damage_it->second;
         }
+      }
+
+      // If a valid damage value was determined for retaliation
+      if (defender_damage_value > 0) {
+        int def_damage = static_cast<int>(defender_damage_value *
+                                          static_cast<float>(enemy->health) /
+                                          enemy->max_health);
+        this->health -= def_damage;
+        this->health =
+            std::max(0, this->health); // Safeguard against negative health
+        std::cout << "Ally health after retaliation: " << this->health
+                  << std::endl;
+      }
     }
-
-    void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector)
-    {
-
-        std::cout << "Left-button pressed on unit: " << this->health << std::endl;
-        
+  }
+}
+
+void Unit::update_position(int posX, int posY) {
+  calc_state(posX, posY);
+
+  this->x = posX;
+  this->y = posY;
+}
+
+void Unit::calc_state(int posX, int posY) {
+  int deltaX = this->x - posX;
+  int deltaY = this->y - posY;
+
+  if (deltaX == 0 && deltaY == 0) {
+    // Unit is already at the target position
+    return;
+  }
+
+  if (abs(deltaX) >= abs(deltaY)) {
+    if (deltaX > 0) {
+      this->state = advanced_wars::UnitState::MOVEMENTLEFT;
+    } else {
+      this->state = advanced_wars::UnitState::MOVEMENTRIGHT;
     }
-
-    bool Unit::inRange(Unit *enemy)
-    {
-        if (this->x == enemy->x)
-        {
-            return abs(this->y - enemy->y) <= this->range;
-        }
-        else if (this->y == enemy->y)
-        {
-            return abs(this->x - enemy->x) <= this->range;
-        }
-        return false;
+  } else {
+    if (deltaY > 0) {
+      this->state = advanced_wars::UnitState::MOVEMENTUP;
+    } else {
+      this->state = advanced_wars::UnitState::MOVEMENTDOWN;
     }
+  }
+}
+
+void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector) {
+
+  std::cout << "Left-button pressed on unit: " << this->health << std::endl;
+}
+
+bool Unit::inRange(Unit *enemy) {
+  if (this->x == enemy->x) {
+    return abs(this->y - enemy->y) <= this->range;
+  } else if (this->y == enemy->y) {
+    return abs(this->x - enemy->x) <= this->range;
+  }
+  return false;
+}
 
 } // namespace advanced_wars
\ No newline at end of file
-- 
GitLab


From 5400f6888a1235aaff78e623c23e4744431488be Mon Sep 17 00:00:00 2001
From: Frederik <frederik@prasch.de>
Date: Fri, 31 Jan 2025 00:10:44 +0100
Subject: [PATCH 30/30] Fix problems from units branch merge conflicts

---
 .clang-format                  | 187 +++++++++
 CMakeLists.txt                 |  43 ++-
 README.md                      |  25 ++
 level-spezifikation.md         |  36 ++
 src/assets/ARCADECLASSIC.TTF   | Bin 0 -> 17296 bytes
 src/assets/main_background.png | Bin 0 -> 2633 bytes
 src/building.cpp               |  37 +-
 src/building.hpp               |  50 +--
 src/effect.cpp                 |  41 +-
 src/effect.hpp                 |  39 +-
 src/engine.cpp                 | 144 ++++---
 src/engine.hpp                 |  63 +--
 src/level.cpp                  | 359 +++++++++++------
 src/level.hpp                  |  80 ++--
 src/main.cpp                   | 109 ++----
 src/scene.hpp                  |  13 +-
 src/spritesheet.cpp            | 686 ++++++++++++++++++---------------
 src/spritesheet.hpp            | 235 +++++++----
 src/tile.cpp                   |  44 +--
 src/tile.hpp                   |  81 ++--
 src/ui/contextmenu.cpp         |  83 ++++
 src/ui/contextmenu.hpp         |  34 ++
 src/ui/menu.cpp                | 249 ++++++++++++
 src/ui/menu.hpp                |  86 +++++
 src/ui/pausemenu.cpp           | 118 ++++++
 src/ui/pausemenu.hpp           |  92 +++++
 src/unit.cpp                   | 346 +++++++++--------
 src/unit.hpp                   | 236 ++++++------
 src/weapon.cpp                 |  36 +-
 src/weapon.hpp                 |  30 +-
 src/window.cpp                 |  62 +--
 src/window.hpp                 |  82 ++--
 32 files changed, 2538 insertions(+), 1188 deletions(-)
 create mode 100644 .clang-format
 create mode 100644 level-spezifikation.md
 create mode 100644 src/assets/ARCADECLASSIC.TTF
 create mode 100644 src/assets/main_background.png
 create mode 100644 src/ui/contextmenu.cpp
 create mode 100644 src/ui/contextmenu.hpp
 create mode 100644 src/ui/menu.cpp
 create mode 100644 src/ui/menu.hpp
 create mode 100644 src/ui/pausemenu.cpp
 create mode 100644 src/ui/pausemenu.hpp

diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000..2910389
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,187 @@
+---
+BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: AlwaysBreak
+AlignArrayOfStructures: Right
+AlignConsecutiveAssignments: None
+AlignConsecutiveBitFields: None
+AlignConsecutiveDeclarations: Consecutive
+AlignConsecutiveMacros: None
+AlignEscapedNewlines: Right
+AlignOperands: Align
+AlignTrailingComments: true
+AllowAllArgumentsOnNextLine: true
+AllowAllConstructorInitializersOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros:
+  - __capability
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: Both
+BraceWrapping:
+  AfterCaseLabel: false
+  AfterClass: false
+  AfterControlStatement: Never
+  AfterEnum: false
+  AfterFunction: false
+  AfterNamespace: false
+  AfterObjCDeclaration: false
+  AfterStruct: false
+  AfterUnion: false
+  AfterExternBlock: false
+  BeforeCatch: false
+  BeforeElse: false
+  BeforeLambdaBody: false
+  BeforeWhile: false
+  IndentBraces: false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakAfterJavaFieldAnnotations: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Allman
+BreakBeforeConceptDeclarations: true
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit: 100
+CommentPragmas: "^ IWYU pragma:"
+CompactNamespaces: false
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DeriveLineEnding: true
+DerivePointerAlignment: false
+DisableFormat: false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks: Preserve
+IncludeCategories:
+  - Regex: ^"(llvm|llvm-c|clang|clang-c)/
+    Priority: 2
+    SortPriority: 0
+    CaseSensitive: false
+  - Regex: ^(<|"(gtest|gmock|isl|json)/)
+    Priority: 3
+    SortPriority: 0
+    CaseSensitive: false
+  - Regex: .*
+    Priority: 1
+    SortPriority: 0
+    CaseSensitive: false
+IncludeIsMainRegex: (Test)?$
+IncludeIsMainSourceRegex: ""
+IndentAccessModifiers: true
+IndentCaseBlocks: true
+IndentCaseLabels: false
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequires: false
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+InsertTrailingCommas: None
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+LambdaBodyIndentation: Signature
+Language: Cpp
+MacroBlockBegin: ""
+MacroBlockEnd: ""
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PPIndentWidth: -1
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Left
+QualifierAlignment: Leave
+ReferenceAlignment: Pointer
+ReflowComments: true
+RemoveBracesLLVM: false
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes: CaseSensitive
+SortJavaStaticImport: Before
+SortUsingDeclarations: true
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterForeachMacros: true
+  AfterFunctionDeclarationName: false
+  AfterFunctionDefinitionName: false
+  AfterIfMacros: true
+  AfterOverloadedOperator: false
+  BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: Never
+SpacesInCStyleCastParentheses: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: true
+SpacesInLineCommentPrefix:
+  Minimum: 1
+  Maximum: -1
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Latest
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth: 4
+UseCRLF: false
+UseTab: Never
+WhitespaceSensitiveMacros:
+  - STRINGIZE
+  - PP_STRINGIZE
+  - BOOST_PP_STRINGIZE
+  - NS_SWIFT_NAME
+  - CF_SWIFT_NAME
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c2881f5..593dc28 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,7 +19,23 @@ set(HIGHFIVE_UNIT_TESTS OFF)
 
 FetchContent_MakeAvailable(highfive)
 
+FetchContent_Declare(
+    box2d
+    GIT_REPOSITORY https://github.com/erincatto/box2d.git
+    GIT_TAG v3.0.0
+)
+
+# Box2D Build-Optionen konfigurieren
+set(BOX2D_BUILD_TESTBED OFF CACHE BOOL "" FORCE)
+set(BOX2D_BUILD_UNIT_TESTS OFF CACHE BOOL "" FORCE)
+set(BOX2D_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
+
+FetchContent_MakeAvailable(box2d)
 
+set(Boost_USE_STATIC_LIBS OFF)
+set(Boost_USE_MULTITHREADED ON)
+set(Boost_USE_STATIC_RUNTIME OFF)
+find_package(Boost 1.71.0 REQUIRED COMPONENTS graph)
 
 # Quellen sammeln
 file(GLOB_RECURSE ADVANCED_WARS_SOURCES
@@ -31,6 +47,12 @@ file(GLOB_RECURSE ADVANCED_WARS_SOURCES
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_BUILD_TYPE Debug)
+
+set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Wpedantic")
+
+add_definitions(-DDEBUG)
 
 # Compiler-Warnungen aktivieren
 if(MSVC)
@@ -43,7 +65,8 @@ endif()
 set(ASSETS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/assets)
 set(OUTPUT_ASSETS_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets)
 file(MAKE_DIRECTORY ${OUTPUT_ASSETS_DIR})
-file(GLOB FONT_FILES ${ASSETS_DIR}/*.ttf)
+file(GLOB FONT_FILES ${ASSETS_DIR}/*.TTF)
+file(GLOB IMAGE_FILES ${ASSETS_DIR}/*.png)
 
 # Executable erstellen
 add_executable(advanced_wars ${ADVANCED_WARS_SOURCES})
@@ -51,6 +74,7 @@ add_executable(advanced_wars ${ADVANCED_WARS_SOURCES})
 target_include_directories(advanced_wars
     PRIVATE 
         ${highfive_SOURCE_DIR}/include
+        ${Boost_INCLUDE_DIRS}
 )
 
 foreach(FONT ${FONT_FILES})
@@ -61,6 +85,14 @@ foreach(FONT ${FONT_FILES})
     )
 endforeach()
 
+foreach(IMAGE ${IMAGE_FILES})
+    add_custom_command(
+            TARGET advanced_wars PRE_BUILD
+            COMMAND ${CMAKE_COMMAND} -E copy ${IMAGE} ${OUTPUT_ASSETS_DIR}
+            COMMENT "Kopiere Image: ${IMAGE} nach ${OUTPUT_ASSETS_DIR}"
+    )
+endforeach()
+
 set(CMAKE_MODULE_PATH ${ADVANCED_WARS_SOURCE_DIR}/cmake/ ${CMAKE_MODULE_PATH})
 
 # Plattform-spezifische Konfiguration
@@ -80,12 +112,14 @@ if(APPLE)
             ${SDL2_PATH}/SDL2.framework/SDL2
             ${SDL2_PATH}/SDL2_image.framework/SDL2_image
             ${SDL2_PATH}/SDL2_ttf.framework/SDL2_ttf
+            Boost::graph  
+            box2d
     )
 
-    # Debug-Ausgaben
     message(STATUS "Include Dir (SDL2): ${SDL2_PATH}/SDL2.framework/Headers")
     message(STATUS "Include Dir (SDL2_image): ${SDL2_PATH}/SDL2_image.framework/Headers")
     message(STATUS "Include Dir (SDL2_ttf): ${SDL2_PATH}/SDL2_ttf.framework/Headers")
+    message(STATUS "Boost Include Dirs: ${Boost_INCLUDE_DIRS}")
 else()
     find_package(SDL2 REQUIRED)
     find_package(SDL2_IMAGE REQUIRED)
@@ -104,9 +138,8 @@ else()
         -lSDL2
         -lSDL2_image
         -lSDL2_ttf
+        Boost::graph
+        box2d
         m
     )
-
-
 endif()
-
diff --git a/README.md b/README.md
index 8e5bcd0..e464b3a 100644
--- a/README.md
+++ b/README.md
@@ -49,6 +49,31 @@
 4. Visual Studio erkennt automatisch das CMake-Projekt
 5. Build über "Build All" ausführen
 
+#### Falls Syntax errors
+
+1. Erstelle .vscode/c_cpp_properties.json Datei
+2. Füge die folgende JSON so oder so ähnlich ein:
+
+```json
+{
+    "configurations": [
+        {
+            "name": "Fedora",
+            "includePath": [
+                "/usr/include",
+                "/usr/include/SDL2"
+            ],
+            "defines": [],
+            "intelliSenseMode": "linux-gcc-x64",
+            "compilerPath": "/usr/bin/gcc",
+            "cStandard": "c17",
+            "cppStandard": "c++17"
+        }
+    ],
+    "version": 4
+}
+```
+
 ## Build-Optionen
 
 CMake kann mit verschiedenen Optionen konfiguriert werden:
diff --git a/level-spezifikation.md b/level-spezifikation.md
new file mode 100644
index 0000000..1f087e5
--- /dev/null
+++ b/level-spezifikation.md
@@ -0,0 +1,36 @@
+# Levelspezifikation
+
+Das Level wird ueber 2 Datasets in der HDF5-Datei repraesentiert.  
+Ein Dataset in XML Format, das die Level Metadaten (Breite, Hoehe, Dataset ID Tiles Array) angibt.  
+Ein weiters Dataset, das letztlich ein array<uint8_t> ist, welches die Levelmap ueber ein Array von Tile IDs definiert.
+
+## 1. XML Dataset mit Level Metadaten
+```xml
+<?xml version="1.0" encoding="ASCII"?>
+<level>
+    <width>20</width> <!-- Breite des Levels -->
+    <height>20</height> <!-- Hoehe des Levels -->
+    <name>Geiles Level<name><!-- Name des Levels -->
+</level>
+```
+
+## 2. Tiles Array
+Das Tiles Array wird als array<uint8_t> in einem Dataset in der HDF5-Datei gespeichert.  
+Die Laenge des Arrays ist Breite X Hoehe (kann man aus XML Leveldefinition entnehmen).  
+Aus den einzelnen Werte in dem Array lassen sich die IDs der entsprechenden Gebaudes/Terrains ableiten.  
+0 - 29 sind Terrain IDs => Zuordnung siehe entsprechendes Enum in Tile.hpp  
+30-49 sind undefiniert  
+50-79  sind Gebaeude IDs:  
+50 => Faction ID 0, Gebaeude ID 0  
+51 => Faction ID 0, Gebaeude ID 1  
+...  
+55 => Faction ID 1, Gebaeude ID 0  
+56 => Faction ID 1, Gebaeude ID 1  
+57 => Faction ID 1, Gebaeude ID 2  
+...  
+Allgemein:  
+Sei t ein Wert im Tiles Array, dann gillt  
+falls t < 30: Terrain ID = t  
+falls t >= 50: Faction ID = (t - 50) / 5   Gebaeude ID = (t - 50) % 5  
+t wird ermittelt mit entweder t = Terrain ID fuer Terrains  
+oder t = 50 + 5*Faction Id + Gebaeude ID fuer Gebaeude
\ No newline at end of file
diff --git a/src/assets/ARCADECLASSIC.TTF b/src/assets/ARCADECLASSIC.TTF
new file mode 100644
index 0000000000000000000000000000000000000000..394a9f781cedaa283a11b3b8b43c9006f4e5bac7
GIT binary patch
literal 17296
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
RaA4qKU|^_ZcnVr^0|2fRI_>}f

literal 0
HcmV?d00001

diff --git a/src/assets/main_background.png b/src/assets/main_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..5958dc0d0a7144697dece04db5dc2a1646088207
GIT binary patch
literal 2633
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

literal 0
HcmV?d00001

diff --git a/src/building.cpp b/src/building.cpp
index b4af7f8..c6b47dc 100644
--- a/src/building.cpp
+++ b/src/building.cpp
@@ -1,30 +1,31 @@
 #include "building.hpp"
 #include "spritesheet.hpp"
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 Building::Building(int x, int y, BuildingId id, BuildingFaction faction)
-    : x(x), y(y), id(id), faction(faction) {};
+    : x(x), y(y), id(id), faction(faction){};
 
-void Building::render(Engine &engine, int scale) {
-  Spritesheet *spritesheet = engine.get_spritesheet();
+void Building::render(Engine* engine, int scale)
+{
+    Spritesheet* spritesheet = engine->get_spritesheet();
 
-  SDL_Rect src;
-  src.x = static_cast<int>(id) * spritesheet->get_building_width();
-  src.y = 0;
-  src.w = spritesheet->get_building_width();
-  src.h = spritesheet->get_building_height();
+    SDL_Rect src;
+    src.x = static_cast<int>(id) * spritesheet->get_building_width();
+    src.y = 0;
+    src.w = spritesheet->get_building_width();
+    src.h = spritesheet->get_building_height();
 
-  SDL_Rect dst;
-  dst.x = x * spritesheet->get_tile_width() * scale;
-  dst.y = (y - 1) * spritesheet->get_tile_height() * scale;
-  dst.w = spritesheet->get_building_width() * scale;
-  dst.h = spritesheet->get_building_height() * scale;
+    SDL_Rect dst;
+    dst.x = x * spritesheet->get_tile_width() * scale;
+    dst.y = (y - 1) * spritesheet->get_tile_height() * scale;
+    dst.w = spritesheet->get_building_width() * scale;
+    dst.h = spritesheet->get_building_height() * scale;
 
-  SDL_RenderCopyEx(
-      engine.renderer(),
-      spritesheet->get_building_textures()[static_cast<int>(faction)], &src,
-      &dst, 0, NULL, SDL_FLIP_NONE);
+    SDL_RenderCopyEx(
+        engine->renderer(), spritesheet->get_building_textures()[static_cast<int>(faction)], &src,
+        &dst, 0, NULL, SDL_FLIP_NONE);
 }
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/building.hpp b/src/building.hpp
index d83597f..fa7a39d 100644
--- a/src/building.hpp
+++ b/src/building.hpp
@@ -3,35 +3,39 @@
 #include "engine.hpp"
 #include "scene.hpp"
 
-namespace advanced_wars {
-
-enum class BuildingFaction {
-  RED = 0,
-  BLUE = 1,
-  YELLOW = 2,
-  GREEN = 3,
-  PURPLE = 4,
-  NEUTRAL = 5,
+namespace advanced_wars
+{
+
+enum class BuildingFaction
+{
+    RED = 0,
+    BLUE = 1,
+    YELLOW = 2,
+    GREEN = 3,
+    PURPLE = 4,
+    NEUTRAL = 5,
 };
 
-enum class BuildingId {
-  HEADQUARTER = 0,
-  CITY = 1,
-  FACTORY = 2,
-  PORT = 3,
-  SATELLITE = 4,
+enum class BuildingId
+{
+    HEADQUARTER = 0,
+    CITY = 1,
+    FACTORY = 2,
+    PORT = 3,
+    SATELLITE = 4,
 };
 
-class Building {
-public:
-  Building(int x, int y, BuildingId id, BuildingFaction faction);
+class Building
+{
+    public:
+        Building(int x, int y, BuildingId id, BuildingFaction faction);
 
-  int x;
-  int y;
-  BuildingId id;
-  BuildingFaction faction;
+        int             x;
+        int             y;
+        BuildingId      id;
+        BuildingFaction faction;
 
-  void render(Engine &engine, int scale);
+        void render(Engine* engine, int scale);
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/effect.cpp b/src/effect.cpp
index c0e22d6..f3ab594 100644
--- a/src/effect.cpp
+++ b/src/effect.cpp
@@ -2,28 +2,27 @@
 #include "spritesheet.hpp"
 #include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 Effect::Effect(int x, int y, EffectId id, bool repeat)
-    : x(x), y(y), id(id), repeat(repeat), start(0) {
+    : x(x), y(y), id(id), repeat(repeat), start(0){
 
-      };
+                                          };
 
-void Effect::render(Engine &engine, int scale) {
-  Spritesheet *spritesheet = engine.get_spritesheet();
-  if (start == 0) {
-    start = engine.get_stage();
-  }
+void Effect::render(Engine* engine, int scale)
+{
+    Spritesheet* spritesheet = engine->get_spritesheet();
+    if (start == 0)
+    {
+        start = engine->get_stage();
+    }
 
-  int step = engine.get_stage() %
-             spritesheet->get_effect_textures().at(static_cast<int>(id)).second;
+    int step =
+        engine->get_stage() % spritesheet->get_effect_textures().at(static_cast<int>(id)).second;
 
-  if (engine.get_stage() - start <=
-          spritesheet->get_effect_textures().at(static_cast<int>(id)).second ||
-      repeat) {
     SDL_Rect src;
-    src.x = step * spritesheet->get_effect_width() +
-            step * spritesheet->get_effect_height();
+    src.x = step * spritesheet->get_effect_width() + step * spritesheet->get_effect_height();
     src.y = 0;
     src.w = spritesheet->get_effect_width();
     src.h = spritesheet->get_effect_height();
@@ -35,10 +34,16 @@ void Effect::render(Engine &engine, int scale) {
     dest.h = spritesheet->get_effect_height() * scale;
 
     SDL_RenderCopyEx(
-        engine.renderer(),
-        spritesheet->get_effect_textures().at(static_cast<int>(id)).first, &src,
+        engine->renderer(), spritesheet->get_effect_textures().at(static_cast<int>(id)).first, &src,
         &dest, 0, NULL, SDL_FLIP_NONE);
-  }
+}
+
+bool Effect::is_finished(Engine* engine)
+{
+    return !(
+        engine->get_stage() - start <=
+            engine->get_spritesheet()->get_effect_textures().at(static_cast<int>(id)).second ||
+        repeat);
 }
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/effect.hpp b/src/effect.hpp
index e5b94a1..f33923d 100644
--- a/src/effect.hpp
+++ b/src/effect.hpp
@@ -2,27 +2,32 @@
 
 #include "engine.hpp"
 
-namespace advanced_wars {
-
-enum class EffectId {
-  LAND_EXPLOSION = 0,
-  AIR_EXPLOSION = 1,
-  NAVAL_EXPLOSION = 2,
-  SUBMARINE_HIDE = 3,
-  SUBMARINE_APPEAR = 4
+namespace advanced_wars
+{
+
+enum class EffectId
+{
+    LAND_EXPLOSION = 0,
+    AIR_EXPLOSION = 1,
+    NAVAL_EXPLOSION = 2,
+    SUBMARINE_HIDE = 3,
+    SUBMARINE_APPEAR = 4
 };
 
-class Effect {
-public:
-  Effect(int x, int y, EffectId id, bool repeat);
+class Effect
+{
+    public:
+        Effect(int x, int y, EffectId id, bool repeat);
+
+        void render(Engine* engine, int scale);
 
-  void render(Engine &engine, int scale);
+        bool is_finished(Engine* engine);
 
-  int x;
-  int y;
-  EffectId id;
-  bool repeat;
-  int start;
+        int      x;
+        int      y;
+        EffectId id;
+        bool     repeat;
+        int      start;
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/engine.cpp b/src/engine.cpp
index e5f9b8e..f7c58d6 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -1,85 +1,129 @@
 #include "engine.hpp"
+#include "SDL_events.h"
+#include "SDL_timer.h"
 #include "scene.hpp"
 #include "spritesheet.hpp"
 #include "window.hpp"
 #include <SDL.h>
 #include <SDL_image.h>
 #include <SDL_render.h>
+#include <deque>
+#include <memory>
+#include <optional>
 #include <stdexcept>
-#include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-Engine::Engine(Window &window) : window(window), quit(false) {
+Engine::Engine(Window& window) : window(window), quit(false)
+{
 
-  if (SDL_Init(SDL_INIT_VIDEO) < 0) {
-    throw std::runtime_error("SDL could not initialize: " +
-                             std::string(SDL_GetError()));
-  }
+    this->sdl_renderer = SDL_CreateRenderer(
+        this->window.sdl_window(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
 
-  int imgFlags = IMG_INIT_PNG;
-  if (!(IMG_Init(imgFlags) & imgFlags)) {
-    throw std::runtime_error(
-        "SDL_image could not initialize! SDL_image Error: " +
-        std::string(IMG_GetError()));
-  }
+    if (sdl_renderer == nullptr)
+    {
+        throw std::runtime_error("SDL could not generate renderer: " + std::string(SDL_GetError()));
+    }
+}
+
+std::deque<SDL_Event>& Engine::events()
+{
+    return this->_events;
+}
 
-  this->sdl_renderer =
-      SDL_CreateRenderer(this->window.sdl_window(), -1,
-                         SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+void Engine::push_scene(std::shared_ptr<Scene> scene)
+{
+    this->scenes.push_back(scene);
+}
 
-  if (sdl_renderer == nullptr) {
-    throw std::runtime_error("SDL could not generate renderer: " +
-                             std::string(SDL_GetError()));
-  }
+void Engine::return_to_menu()
+{
+    // TODO: discuss if we outsource this to a separate function
+    // clear everything except the first scene
+    while (this->scenes.size() > 1)
+    {
+        this->scenes.pop_back();
+    }
 }
 
-void Engine::set_scene(Scene &scene) { this->scene = &scene; }
+std::optional<std::shared_ptr<Scene>> Engine::pop_scene()
+{
+    if (this->scenes.empty())
+    {
+        return std::nullopt;
+    }
+    std::shared_ptr<Scene> tmp = scenes.back();
+    this->scenes.pop_back();
 
-void Engine::set_spritesheet(Spritesheet &spritesheet) {
-  this->spritesheet = &spritesheet;
+    return tmp;
 }
 
-Spritesheet *Engine::get_spritesheet() { return spritesheet.value(); }
+void Engine::set_spritesheet(Spritesheet& spritesheet)
+{
+    this->spritesheet = &spritesheet;
+}
 
-void Engine::pump() {
-  SDL_Event e;
-  while (SDL_PollEvent(&e)) {
-    if (e.type == SDL_QUIT) {
-      this->quit = true;
-    } else {
-      this->events.push_back(e);
+void Engine::pump()
+{
+    SDL_Event e;
+    while (SDL_PollEvent(&e))
+    {
+        if (e.type == SDL_QUIT)
+        {
+            this->quit = true;
+        }
+        else
+        {
+            this->_events.push_back(e);
+        }
     }
-  }
 }
 
-bool Engine::exited() { return this->quit; }
+void Engine::exit()
+{
+    this->quit = true;
+}
 
-int Engine::get_stage() { return this->stage; }
+bool Engine::exited()
+{
+    return this->quit;
+}
 
-void Engine::render() {
-  if (SDL_RenderClear(this->sdl_renderer) != 0) {
-    throw std::runtime_error("Could not clear renderer: " +
-                             std::string(SDL_GetError()));
-  }
+void Engine::render()
+{
+    if (SDL_RenderClear(this->sdl_renderer) != 0)
+    {
+        throw std::runtime_error("Could not clear renderer: " + std::string(SDL_GetError()));
+    }
 
-  if (!scene.has_value()) {
-    return;
-  }
+    std::shared_ptr<Scene> currentScene = scenes.back();
 
-  stage = SDL_GetTicks() / 300;
+    currentScene->render(this);
 
-  this->scene.value()->render(*this, this->events);
+    SDL_RenderPresent(this->sdl_renderer);
+}
 
-  SDL_RenderPresent(this->sdl_renderer);
+int Engine::get_stage()
+{
+    return SDL_GetTicks() / 300;
 }
 
-SDL_Renderer *Engine::renderer() { return this->sdl_renderer; }
+Spritesheet* Engine::get_spritesheet()
+{
+    return spritesheet.value();
+}
+
+SDL_Renderer* Engine::renderer()
+{
+    return this->sdl_renderer;
+}
 
-Engine::~Engine() {
-  SDL_DestroyRenderer(sdl_renderer);
-  IMG_Quit();
-  SDL_Quit();
+Engine::~Engine()
+{
+    SDL_DestroyRenderer(sdl_renderer);
+    IMG_Quit();
+    SDL_Quit();
 }
 
 } // namespace advanced_wars
diff --git a/src/engine.hpp b/src/engine.hpp
index 827d05d..4b247e8 100644
--- a/src/engine.hpp
+++ b/src/engine.hpp
@@ -1,51 +1,66 @@
 #pragma once
 
+#include "SDL_events.h"
 #include "scene.hpp"
 #include "spritesheet.hpp"
 #include "window.hpp"
 #include <SDL.h>
 #include <SDL_render.h>
+#include <deque>
+#include <memory>
 #include <optional>
-#include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
+
+// Forward declaration
+class Scene;
 
 /**
  * @brief The main window of the game
  */
-class Engine {
-public:
-  Engine(Window &window);
+class Engine
+{
+    public:
+        Engine(Window& window);
+
+        Engine(const Engine&) = delete;
+        Engine& operator=(const Engine&) = delete;
+
+        bool exited();
+
+        void exit();
+
+        void pump();
 
-  Engine(const Engine &) = delete;
-  Engine &operator=(const Engine &) = delete;
+        void push_scene(std::shared_ptr<Scene> scene);
 
-  bool exited();
+        std::optional<std::shared_ptr<Scene>> pop_scene();
 
-  void pump();
+        void return_to_menu();
 
-  void set_scene(Scene &scene);
+        std::deque<SDL_Event>& events();
 
-  void set_spritesheet(Spritesheet &spritesheet);
+        void set_spritesheet(Spritesheet& spritesheet);
 
-  Spritesheet *get_spritesheet();
+        Spritesheet* get_spritesheet();
 
-  int get_stage();
+        int get_stage();
 
-  void render();
+        void render();
 
-  SDL_Renderer *renderer();
+        SDL_Renderer* renderer();
 
-  ~Engine();
+        ~Engine();
 
-private:
-  Window &window;
-  SDL_Renderer *sdl_renderer;
-  std::optional<Scene *> scene;
-  std::optional<Spritesheet *> spritesheet;
-  std::vector<SDL_Event> events;
-  bool quit;
-  int stage;
+    private:
+        Window&                             window;
+        SDL_Renderer*                       sdl_renderer;
+        std::vector<std::shared_ptr<Scene>> scenes;
+        std::optional<Spritesheet*>         spritesheet;
+        std::deque<SDL_Event>               _events;
+        bool                                quit;
+        int                                 stage;
 };
 
 } // namespace advanced_wars
diff --git a/src/level.cpp b/src/level.cpp
index 154a2ea..927ca47 100644
--- a/src/level.cpp
+++ b/src/level.cpp
@@ -1,225 +1,342 @@
 #include "level.hpp"
-#include "SDL_error.h"
 #include "building.hpp"
 #include "effect.hpp"
 #include "engine.hpp"
 #include "spritesheet.hpp"
+#include "ui/contextmenu.hpp"
+#include "ui/pausemenu.hpp"
 #include "unit.hpp"
 #include <SDL.h>
+#include <algorithm>
 #include <iostream>
 #include <string>
-#include <algorithm>
 
 namespace advanced_wars
 {
 
-  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)
-      : name(name), width(width), height(height), tiles(tiles),
-        buildings(buildings), units(units), effects(effects)
-  {
+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)
+    : name(name), width(width), height(height), tiles(tiles), context_menu(ContextMenu()),
+      context_menu_active(false), id(0)
+{
+
+    context_menu.setOptions({"Move", "Info", "Wait"});
+
+    for (Building building : buildings)
+    {
+        this->add_building(building);
+    }
+
+    for (Unit unit : units)
+    {
+        this->add_unit(unit);
+    }
+
+    for (Effect effect : effects)
+    {
+        this->add_effect(effect);
+    }
 
     if ((size_t)(width * height) != tiles.size())
     {
-      throw std::runtime_error("level tile mismatch");
+        throw std::runtime_error("level tile mismatch");
     }
-  };
+};
 
-  const int RENDERING_SCALE = 3;
+const int RENDERING_SCALE = 3;
 
-  bool Level::click_check_left(int tileX, int tileY)
-  {
+bool Level::click_check_left(int tileX, int tileY)
+{
 
     if (selectUnit(tileX, tileY))
     {
-      return true;
+        return true;
     }
 
     if (selectBuilding(tileX, tileY))
     {
-      return true;
+        return true;
     }
 
     return false;
-  }
+}
 
-  bool Level::click_check_right(int tileX, int tileY)
-  {
+bool Level::click_check_right(int tileX, int tileY)
+{
 
     if (target_unit(tileX, tileY))
     {
-      return true;
+        return true;
     }
 
     return false;
-  }
+}
 
-  bool Level::selectUnit(int tileX, int tileY)
-  {
+bool Level::selectUnit(int tileX, int tileY)
+{
 
     // std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
-    for (auto &unit : units)
+    for (auto& [id, unit] : units)
     {
 
-      if (unit.x == tileX && unit.y == tileY)
-      {
-        // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
+        if (unit.x == tileX && unit.y == tileY)
+        {
+            // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
 
-        selectedUnit = &unit;
-        return true;
-      }
+            selectedUnit = id;
+            return true;
+        }
     }
 
     return false;
-  }
+}
 
-  bool Level::target_unit(int tileX, int tileY)
-  {
+bool Level::target_unit(int tileX, int tileY)
+{
 
     // std::cout << "tileX:" << tileX << "tileX:" << tileY << std::endl;
-    for (auto &unit : units)
+    for (auto& [id, unit] : units)
     {
 
-      if (unit.x == tileX && unit.y == tileY)
-      {
-        // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
+        if (unit.x == tileX && unit.y == tileY)
+        {
+            // std::cout << "unitX:" << unit.x << "unitY:" << unit.y << std::endl;
 
-        targetedUnit = &unit;
-        return true;
-      }
+            targetedUnit = id;
+            return true;
+        }
     }
 
     return false;
-  }
+}
 
-  bool Level::selectBuilding(int tileX, int tileY)
-  {
+bool Level::selectBuilding(int tileX, int tileY)
+{
 
-    for (auto &building : buildings)
+    for (auto& [id, building] : buildings)
     {
 
-      if (building.x == tileX && building.y == tileY)
-      {
-        // std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
-        selectedBuilding = &building;
-        return true;
-      }
+        if (building.x == tileX && building.y == tileY)
+        {
+            // std::cout << "X:" << unit.x << "Y:" << unit.y << std::endl;
+            selectedBuilding = id;
+            return true;
+        }
     }
     return false;
-  }
+}
 
-  void Level::handleEvent(Engine &engine, SDL_Event &event)
-  {
+void Level::handleEvent(Engine& engine, SDL_Event& event)
+{
 
     switch (event.type)
     {
     case SDL_MOUSEBUTTONDOWN:
 
-      if (event.button.button == SDL_BUTTON_LEFT)
-      {
-
-        int tileX = event.button.x / (16 * RENDERING_SCALE);
-        int tileY = event.button.y / (16 * RENDERING_SCALE);
-
-        if (click_check_left(tileX, tileY))
+        if (event.button.button == SDL_BUTTON_LEFT)
         {
 
-          if (selectedUnit)
-          {
-            selectedUnit->on_left_click(event, units);
-          }
-
-          if (selectedBuilding)
-          {
-            // building stuff
-          }
+            int tileX = event.button.x / (16 * RENDERING_SCALE);
+            int tileY = event.button.y / (16 * RENDERING_SCALE);
+
+            if (click_check_left(tileX, tileY))
+            {
+
+                if (selectedUnit > -1)
+                {
+                    units.at(selectedUnit).on_left_click(event);
+                }
+
+                if (selectedBuilding > -1)
+                {
+                    // building stuff
+                }
+            }
+            else
+            {
+
+                std::cout << "Neither building nor unit clicked!" << std::endl;
+                selectedUnit = -1;
+                selectedBuilding = -1;
+            }
         }
-        else
+        else if (event.button.button == SDL_BUTTON_RIGHT)
         {
 
-          std::cout << "Neither building nor unit clicked!" << std::endl;
-          selectedUnit = nullptr;
-          selectedBuilding = nullptr;
-        }
-      }
-      else if (event.button.button == SDL_BUTTON_RIGHT)
-      {
-
-        if (selectedUnit)
-        {
+            if (selectedUnit > -1)
+            {
 
-          int tileX = event.button.x / (16 * RENDERING_SCALE);
-          int tileY = event.button.y / (16 * RENDERING_SCALE);
+                int tileX = event.button.x / (16 * RENDERING_SCALE);
+                int tileY = event.button.y / (16 * RENDERING_SCALE);
 
-          if (click_check_right(tileX, tileY))
-          {
+                if (click_check_right(tileX, tileY))
+                {
 
-            selectedUnit->attack(targetedUnit);
+                    units.at(selectedUnit).attack(&(units.at(targetedUnit)));
 
-            units.erase(
-                std::remove_if(units.begin(), units.end(),
-                               [](const Unit &unit)
-                               { return unit.health <= 0; }),
-                units.end());
-          }
-          else
-          {
+                    if (units.at(selectedUnit).health <= 0)
+                    {
+                        remove_unit(selectedUnit);
+                    }
+                }
+                else
+                {
 
-            selectedUnit->update_position(tileX, tileY);
-          }
-        }
-        else
-        {
+                    units.at(selectedUnit).update_position(tileX, tileY);
+                }
+            }
+            else
+            {
 
-          std::cout << "No unit selected! " << std::endl;
+                std::cout << "No unit selected! " << std::endl;
+            }
         }
-      }
     }
-  }
+}
 
-  void Level::render(Engine &engine, std::vector<SDL_Event> &events)
-  {
+void Level::render(Engine* engine)
+{
 
     // Iterate over all events
-    while (!events.empty())
+    while (!engine->events().empty())
     {
-      // events.erase(events.begin());
-
-      handleEvent(engine, events.at(0));
-      events.erase(events.begin());
+        // handleEvent(engine, engine->events().at(0));
+        handleEvent(*engine, engine->events().at(0));
+        engine->events().pop_front();
     }
 
     // Tiles
-    for (Tile &tile : tiles)
+    for (Tile& tile : tiles)
     {
-      tile.render(engine, RENDERING_SCALE);
+        tile.render(engine, RENDERING_SCALE);
     }
 
     // Buildings
-    for (Building &building : buildings)
+    for (auto& [id, building] : buildings)
     {
-      building.render(engine, RENDERING_SCALE);
+        building.render(engine, RENDERING_SCALE);
     }
 
     // Units
-    for (Unit &unit : units)
+    for (auto& [id, unit] : units)
     {
-      unit.render(engine, RENDERING_SCALE);
+        unit.render(engine, RENDERING_SCALE);
     }
 
     // Effects
-    for (Effect &effect : effects)
+    std::vector<int> effects_to_remove;
+    for (auto& [id, effect] : effects)
+    {
+        if (effect.is_finished(engine))
+        {
+            effects_to_remove.push_back(id);
+        }
+        else
+        {
+            effect.render(engine, RENDERING_SCALE);
+        }
+    }
+
+    // Remove finished effects after iteration
+    for (int id : effects_to_remove)
     {
-      effect.render(engine, RENDERING_SCALE);
+        this->remove_effect(id);
     }
 
-    // Set background color for renderer
-    if (SDL_SetRenderDrawColor(engine.renderer(), 255, 0, 0, 0))
+    if (context_menu_active)
+    {
+        context_menu.render(engine);
+    }
+}
+
+void Level::handleEvent(Engine* engine, SDL_Event& event)
+{
+    // Handle events for the level
+    if (event.type == SDL_KEYDOWN)
+    {
+        if (event.key.keysym.sym == SDLK_ESCAPE)
+        {
+            // Pause the game
+            std::cout << "Pausing game..." << std::endl;
+            SDL_Texture* currentTexture = SDL_CreateTexture(
+                engine->renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 800, 600);
+
+            PauseMenu pauseMenu(0, currentTexture);
+            engine->push_scene(std::make_shared<PauseMenu>(pauseMenu));
+        }
+        if (context_menu_active)
+        {
+            if (event.key.keysym.sym == SDLK_DOWN)
+            {
+                context_menu.handleEvent(event);
+            }
+            if (event.key.keysym.sym == SDLK_UP)
+            {
+                context_menu.handleEvent(event);
+            }
+            if (event.key.keysym.sym == SDLK_RETURN)
+            {
+                if (context_menu.getSelectedOption() == "Wait")
+                {
+                    context_menu_active = false;
+                }
+            }
+        }
+    }
+    if (event.type == SDL_MOUSEBUTTONDOWN)
     {
-      std::cout << "Could not set render draw color: " << SDL_GetError()
-                << std::endl;
+        context_menu.update(event.button.x, event.button.y);
+        context_menu_active = true;
     }
-  }
+}
+
+int Level::add_building(Building building)
+{
+    buildings.insert({id, building});
+    id += 1;
+
+    return id - 1;
+}
+
+Building Level::remove_building(int id)
+{
+    Building value = buildings.at(id);
+    buildings.erase(id);
+
+    return value;
+}
+
+int Level::add_unit(Unit unit)
+{
+    units.insert({id, unit});
+    id += 1;
+
+    return id - 1;
+}
+
+Unit Level::remove_unit(int id)
+{
+    Unit value = units.at(id);
+    units.erase(id);
+
+    return value;
+}
+
+int Level::add_effect(Effect effect)
+{
+    effects.insert({id, effect});
+    id += 1;
+
+    return id - 1;
+}
+
+Effect Level::remove_effect(int id)
+{
+    Effect value = effects.at(id);
+    effects.erase(id);
+
+    return value;
+}
 
-} // namespace advanced_wars
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/level.hpp b/src/level.hpp
index 7c5e99b..0750148 100644
--- a/src/level.hpp
+++ b/src/level.hpp
@@ -5,43 +5,67 @@
 #include "engine.hpp"
 #include "scene.hpp"
 #include "tile.hpp"
+#include "ui/contextmenu.hpp"
 #include "unit.hpp"
 #include <SDL.h>
 #include <string>
+#include <unordered_map>
 #include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 /**
  * @brief The main window of the game
  */
-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>);
-
-  void render(Engine &engine, std::vector<SDL_Event> &events);
-
-  void handleEvent(Engine &engine, SDL_Event &event);
-
-private:
-  std::string name;
-  int width;
-  int height;
-  std::vector<Tile> tiles;
-  std::vector<Building> buildings;
-  std::vector<Unit> units;
-  std::vector<Effect> effects;
-  Unit* selectedUnit;
-  Unit* targetedUnit;
-  Building* selectedBuilding;
-  bool selectUnit (int tileX, int tileY);
-  bool target_unit (int tileX, int tileY);
-  bool selectBuilding(int tileX, int tileY);
-
-  bool click_check_left(int mouseX, int mouseY);
-  bool click_check_right(int mouseX, int mouseY);
+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>);
+
+        void render(Engine* engine);
+
+        void handleEvent(Engine* engine, SDL_Event& event);
+
+        int add_building(Building building);
+
+        Building remove_building(int id);
+
+        int add_unit(Unit unit);
+
+        Unit remove_unit(int id);
+
+        int add_effect(Effect effect);
+
+        Effect remove_effect(int id);
+
+        void handleEvent(Engine& engine, SDL_Event& event);
+
+    private:
+        std::string name;
+        int         width;
+        int         height;
+
+        std::vector<Tile>                 tiles;
+        std::unordered_map<int, Building> buildings;
+        std::unordered_map<int, Unit>     units;
+        std::unordered_map<int, Effect>   effects;
+        int                               selectedUnit;
+        int                               targetedUnit;
+        int                               selectedBuilding;
+        bool                              selectUnit(int tileX, int tileY);
+        bool                              target_unit(int tileX, int tileY);
+        bool                              selectBuilding(int tileX, int tileY);
+
+        bool click_check_left(int mouseX, int mouseY);
+        bool click_check_right(int mouseX, int mouseY);
+
+        ContextMenu context_menu;
+        bool        context_menu_active;
+
+        int id;
 };
 
 } // namespace advanced_wars
diff --git a/src/main.cpp b/src/main.cpp
index a6d4dd4..3d24912 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,96 +1,55 @@
-#include "building.hpp"
-#include "effect.hpp"
 #include "engine.hpp"
-#include "level.hpp"
 #include "spritesheet.hpp"
-#include "tile.hpp"
-#include "unit.hpp"
+#include "ui/contextmenu.hpp"
+#include "ui/menu.hpp"
 #include "window.hpp"
-#include <cstddef>
+#include <SDL2/SDL.h>
+#include <SDL_image.h>
+#include <memory>
+#include <stdexcept>
 #include <vector>
 
 using namespace advanced_wars;
 
-int main() {
+int main()
+{
 
-  Window window("Advanced Wars", 960, 960);
-
-  Engine engine(window);
-
-  // Construct a level
-  std::vector<Tile> tiles;
-  for (int y = 0; y < 20; y++) {
-    for (int x = 0; x < 20; x++) {
-      tiles.push_back(Tile(TileId::PLAIN, x, y));
+    if (SDL_Init(SDL_INIT_VIDEO) < 0)
+    {
+        throw std::runtime_error("SDL could not initialize: " + std::string(SDL_GetError()));
     }
-  }
-
-  // Fill the edges with water
-  for (size_t n = 0; n < 20; n++) {
-    // Vertical
-    tiles.at(n * 20) = Tile(TileId::WATER, 0, n);
-    tiles.at(n * 20 + 19) = Tile(TileId::WATER, 19, n);
-    // Horizontal
-    tiles.at(n) = Tile(TileId::WATER, n, 0);
-    tiles.at(19 * 20 + n) = Tile(TileId::WATER, n, 19);
-  }
-
-  // Make the edges cliffs
-  for (size_t n = 1; n < 19; n++) {
-    // Vertical
-    tiles.at(n * 20 + 1) = Tile(TileId::CLIFF_RIGHT, 1, n);
-    tiles.at(n * 20 + 18) = Tile(TileId::CLIFF_LEFT, 18, n);
-
-    // Horizontal
-    tiles.at(20 + n) = Tile(TileId::CLIFF_BOTTOM, n, 1);
-    tiles.at(18 * 20 + n) = Tile(TileId::CLIFF_TOP, n, 18);
-  }
 
-  // Fix the corners
-  tiles.at(20 + 1) = Tile(TileId::CLIFF_CORNER_TOP_LEFT, 1, 1);
-  tiles.at(20 + 18) = Tile(TileId::CLIFF_CORNER_TOP_RIGHT, 18, 1);
-  tiles.at(18 * 20 + 1) = Tile(TileId::CLIFF_CORNER_BOTTOM_LEFT, 1, 18);
-  tiles.at(18 * 20 + 18) = Tile(TileId::CLIFF_CORNER_BOTTOM_RIGHT, 18, 18);
-
-  // Buildings
-  std::vector<Building> buildings;
-
-  for (int y = 0; y < 6; y++) {
-    for (int x = 0; x < 5; x++) {
-      BuildingId id = static_cast<BuildingId>(x);
-      BuildingFaction faction = static_cast<BuildingFaction>(y);
-
-      buildings.push_back(Building(3 + x, 3 + 2 * y, id, faction));
+    int imgFlags = IMG_INIT_PNG;
+    if (!(IMG_Init(imgFlags) & imgFlags))
+    {
+        throw std::runtime_error(
+            "SDL_image could not initialize! SDL_image Error: " + std::string(IMG_GetError()));
     }
-  }
 
-  // Units
-  std::vector<Unit> units;
+    Window window("Advanced Wars", 960, 960);
 
-  for (int y = 0; y < 19; y++) {
-    for (int x = 0; x < 6; x++) {
-      units.push_back(Unit(x + 9, y + 2, UnitFaction::URED,
-                           static_cast<UnitId>(y), static_cast<UnitState>(x)));
-    }
-  }
+    Engine engine(window);
 
-  std::vector<Effect> effects({Effect(3, 15, EffectId::LAND_EXPLOSION, true),
-                               Effect(5, 15, EffectId::AIR_EXPLOSION, true),
-                               Effect(5, 18, EffectId::NAVAL_EXPLOSION, true)});
+    Spritesheet spritesheet("/media/data/rust/sprite-extractor/spritesheet.h5", engine);
 
-  Level level("Osnabrück", 20, 20, tiles, buildings, units, effects);
+    engine.set_spritesheet(spritesheet);
 
-  engine.set_scene(level);
+    std::shared_ptr<Menu>        menu = std::make_shared<Menu>(0);
+    std::shared_ptr<ContextMenu> context_menu = std::make_shared<ContextMenu>();
+    context_menu->setOptions({"Move", "Info", "Wait"});
 
-  Spritesheet spritesheet("./spritesheet.h5",
-                          engine);
+    std::string basePath = SDL_GetBasePath();
+    std::string relativePath = "assets/main_background.png";
+    std::string fullPath = basePath + relativePath;
+    menu->loadBackground(engine.renderer(), fullPath.c_str());
 
-  engine.set_spritesheet(spritesheet);
+    engine.push_scene(menu);
 
-  while (!engine.exited()) {
-    engine.pump();
-    engine.render();
-  }
+    while (!engine.exited())
+    {
+        engine.pump();
+        engine.render();
+    }
 
-  return 0;
+    return 0;
 }
diff --git a/src/scene.hpp b/src/scene.hpp
index 5bd5283..011b642 100644
--- a/src/scene.hpp
+++ b/src/scene.hpp
@@ -1,15 +1,18 @@
 #pragma once
 
+#include "engine.hpp"
 #include <SDL.h>
-#include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 // Forward declaration
 class Engine;
 
-class Scene {
-public:
-  virtual void render(Engine &engine, std::vector<SDL_Event> &events) = 0;
+class Scene
+{
+    public:
+        virtual void render(Engine* engine) = 0;
 };
+
 } // namespace advanced_wars
diff --git a/src/spritesheet.cpp b/src/spritesheet.cpp
index 96a8f2a..efd7a93 100644
--- a/src/spritesheet.cpp
+++ b/src/spritesheet.cpp
@@ -1,5 +1,12 @@
+/**
+ * Spritesheet.hpp
+ *
+ * @date 30.1.2025
+ * @author Frederik Keens
+ * @author David Maul
+ */
+
 #include "spritesheet.hpp"
-#include "SDL_pixels.h"
 #include "engine.hpp"
 #include "highfive/H5File.hpp"
 #include <SDL_image.h>
@@ -10,377 +17,446 @@
 #include <string>
 #include <vector>
 
-namespace advanced_wars {
-
-Spritesheet::Spritesheet(std::string path, Engine &engine) {
-
-  HighFive::File file(path, HighFive::File::ReadOnly);
-
-  // Tiles
-  std::vector<std::string> tiles({"plain",
-                                  "water",
-                                  "forest",
-                                  "mountain",
-                                  "bridge_horizontal",
-                                  "bridge_vertical",
-                                  "street_horizontal",
-                                  "street_vertical",
-                                  "street_crossing",
-                                  "street_junction_right",
-                                  "street_junction_left",
-                                  "street_junction_down",
-                                  "street_junction_up",
-                                  "street_corner_top_left",
-                                  "street_corner_top_right",
-                                  "street_corner_bottom_left",
-                                  "street_corner_bottom_right",
-                                  "riff",
-                                  "cliff_top",
-                                  "cliff_bottom",
-                                  "cliff_left",
-                                  "cliff_right",
-                                  "cliff_corner_top_left",
-                                  "cliff_corner_top_right",
-                                  "cliff_corner_bottom_left",
-                                  "cliff_corner_bottom_right",
-                                  "cliff_inverse_corner_top_left",
-                                  "cliff_inverse_corner_top_right",
-                                  "cliff_inverse_corner_bottom_left",
-                                  "cliff_inverse_corner_bottom_right"});
-
-  for (size_t tile_idx = 0; tile_idx < tiles.size(); tile_idx++) {
-    HighFive::DataSet units_ds = file.getDataSet("tiles/" + tiles[tile_idx]);
-
-    std::vector<std::vector<std::vector<uint32_t>>> tile_frames;
-    units_ds.read(tile_frames);
-
-    std::vector<uint32_t> tile_buffer(16 * 16 * tile_frames.size(), 0);
-
-    for (size_t n = 0; n < tile_frames.size(); n++) {
-      for (size_t y = 0; y < 16; y++) {
-        for (size_t x = 0; x < 16; x++) {
-          size_t index = (y * tile_frames.size() * 16) + (n * 16 + x);
-
-          tile_buffer.at(index) = tile_frames.at(n).at(16 - y - 1).at(x);
+namespace advanced_wars
+{
+
+Spritesheet::Spritesheet(std::string path, Engine& engine)
+{
+
+    HighFive::File file(path, HighFive::File::ReadOnly);
+
+    // Tiles
+    std::vector<std::string> tiles(
+        {"plain",
+         "water",
+         "forest",
+         "mountain",
+         "bridge_horizontal",
+         "bridge_vertical",
+         "street_horizontal",
+         "street_vertical",
+         "street_crossing",
+         "street_junction_right",
+         "street_junction_left",
+         "street_junction_down",
+         "street_junction_up",
+         "street_corner_top_left",
+         "street_corner_top_right",
+         "street_corner_bottom_left",
+         "street_corner_bottom_right",
+         "riff",
+         "cliff_top",
+         "cliff_bottom",
+         "cliff_left",
+         "cliff_right",
+         "cliff_corner_top_left",
+         "cliff_corner_top_right",
+         "cliff_corner_bottom_left",
+         "cliff_corner_bottom_right",
+         "cliff_inverse_corner_top_left",
+         "cliff_inverse_corner_top_right",
+         "cliff_inverse_corner_bottom_left",
+         "cliff_inverse_corner_bottom_right"});
+
+    // every sub data set of tiles
+    for (size_t tile_idx = 0; tile_idx < tiles.size(); tile_idx++)
+    {
+        HighFive::DataSet units_ds = file.getDataSet("tiles/" + tiles[tile_idx]);
+
+        std::vector<std::vector<std::vector<uint32_t>>> tile_frames;
+        units_ds.read(tile_frames);
+
+        std::vector<uint32_t> tile_buffer(16 * 16 * tile_frames.size(), 0);
+
+        // every animation frame
+        for (size_t n = 0; n < tile_frames.size(); n++)
+        {
+            for (size_t y = 0; y < 16; y++)
+            {
+                for (size_t x = 0; x < 16; x++)
+                {
+                    size_t index = (y * tile_frames.size() * 16) + (n * 16 + x);
+
+                    tile_buffer.at(index) = tile_frames.at(n).at(16 - y - 1).at(x);
+                }
+            }
         }
-      }
-    }
-
-    SDL_Texture *tmp = SDL_CreateTexture(
-        engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
-        tile_frames.size() * 16, 16);
-
-    SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
-
-    if (tmp == nullptr) {
-      throw std::runtime_error(
-          "Fehler beim Erstellen der Textur für die Units: " +
-          std::string(SDL_GetError()));
-    }
-
-    if (SDL_UpdateTexture(tmp, NULL, tile_buffer.data(),
-                          tile_frames.size() * 16 * sizeof(int32_t)) != 0) {
-      throw std::runtime_error(
-          "Fehler beim updaten der Textur für die Units: " +
-          std::string(SDL_GetError()));
-    }
 
-    tile_textures.push_back(
-        std::pair<SDL_Texture *, int>(tmp, tile_frames.size()));
-  }
+        SDL_Texture* tmp = SDL_CreateTexture(
+            engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
+            tile_frames.size() * 16, 16);
 
-  this->tile_width = 16;
-  this->tile_height = 16;
-
-  // Buildings
-  std::vector<std::string> building_factions(
-      {"red", "blue", "yellow", "green", "purple", "neutral"});
-
-  for (std::string faction : building_factions) {
-    HighFive::DataSet buildings_ds = file.getDataSet("buildings/" + faction);
-
-    std::vector<std::vector<std::vector<uint32_t>>> buildings_frames;
-
-    buildings_ds.read(buildings_frames);
-
-    std::vector<uint32_t> building_buffer(32 * 16 * buildings_frames.size(), 0);
-
-    for (size_t n = 0; n < buildings_frames.size(); n++) {
-      for (size_t y = 0; y < 32; y++) {
-        for (size_t x = 0; x < 16; x++) {
-          size_t index = (y * buildings_frames.size() * 16) + (n * 16 + x);
+        SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
 
-          building_buffer.at(index) =
-              buildings_frames.at(n).at(32 - y - 1).at(x);
+        if (tmp == nullptr)
+        {
+            throw std::runtime_error(
+                "Fehler beim Erstellen der Textur für die Units: " + std::string(SDL_GetError()));
         }
-      }
-    }
 
-    SDL_Texture *tmp = SDL_CreateTexture(
-        engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
-        buildings_frames.size() * 16, 32);
-
-    SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
-
-    if (tmp == nullptr) {
-      throw std::runtime_error(
-          "Fehler beim Erstellen der Textur für die Buildings: " +
-          std::string(SDL_GetError()));
-    }
+        if (SDL_UpdateTexture(
+                tmp, NULL, tile_buffer.data(), tile_frames.size() * 16 * sizeof(int32_t)) != 0)
+        {
+            throw std::runtime_error(
+                "Fehler beim updaten der Textur für die Units: " + std::string(SDL_GetError()));
+        }
 
-    if (SDL_UpdateTexture(tmp, NULL, building_buffer.data(),
-                          buildings_frames.size() * 16 * sizeof(int32_t)) !=
-        0) {
-      throw std::runtime_error(
-          "Fehler beim updaten der Textur für die Buildings: " +
-          std::string(SDL_GetError()));
+        tile_textures.push_back(std::pair<SDL_Texture*, int>(tmp, tile_frames.size()));
     }
 
-    this->building_textures.push_back(tmp);
-  }
-
-  this->building_width = 16;
-  this->building_height = 32;
-
-  // Units
-  std::vector<std::string> unit_factions(
-      {"red", "blue", "green", "yellow", "purple"});
-
-  std::vector<std::string> units(
-      {"infantery", "mechanized_infantery", "recon", "medium_tank",
-       "heavy_tank", "neo_tank", "apc", "anti_air_tank", "artillery",
-       "rocket_artillery", "anti_air_missile_launcher", "fighter", "bomber",
-       "battle_helicopter", "transport_helicopter", "battleship", "cruiser",
-       "lander", "submarine"});
-
-  std::vector<std::string> unit_states({"idle", "unavailable"});
-  std::vector<std::string> unit_movement_states(
-      {"left", "right", "down", "up"});
-
-  for (size_t faction_idx = 0; faction_idx < unit_factions.size();
-       faction_idx++) {
-    std::string faction = unit_factions.at(faction_idx);
-    // Create entry for units for in a faction
-    unit_textures.push_back(
-        std::vector<std::vector<std::pair<SDL_Texture *, int>>>());
+    this->tile_width = 16;
+    this->tile_height = 16;
 
-    for (size_t unit_idx = 0; unit_idx < units.size(); unit_idx++) {
-      std::string unit = units.at(unit_idx);
+    // Buildings
+    std::vector<std::string> building_factions(
+        {"red", "blue", "yellow", "green", "purple", "neutral"});
 
-      // Create entry for states for a unit
-      unit_textures.at(faction_idx)
-          .push_back(std::vector<std::pair<SDL_Texture *, int>>());
+    // every sub data set of buildings
+    for (std::string faction : building_factions)
+    {
+        HighFive::DataSet buildings_ds = file.getDataSet("buildings/" + faction);
 
-      for (size_t state_idx = 0; state_idx < unit_states.size(); state_idx++) {
-        std::string unit_state = unit_states.at(state_idx);
+        std::vector<std::vector<std::vector<uint32_t>>> buildings_frames;
 
-        HighFive::DataSet units_ds =
-            file.getDataSet("units/" + faction + "/" + unit + "/" + unit_state);
+        buildings_ds.read(buildings_frames);
 
-        std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
-        units_ds.read(unit_frames);
+        std::vector<uint32_t> building_buffer(32 * 16 * buildings_frames.size(), 0);
 
-        std::vector<uint32_t> unit_buffer(16 * 16 * unit_frames.size(), 0);
+        // every type of building
+        for (size_t n = 0; n < buildings_frames.size(); n++)
+        {
+            for (size_t y = 0; y < 32; y++)
+            {
+                for (size_t x = 0; x < 16; x++)
+                {
+                    size_t index = (y * buildings_frames.size() * 16) + (n * 16 + x);
 
-        for (size_t n = 0; n < unit_frames.size(); n++) {
-          for (size_t y = 0; y < 16; y++) {
-            for (size_t x = 0; x < 16; x++) {
-              size_t index = (y * unit_frames.size() * 16) + (n * 16 + x);
-
-              unit_buffer.at(index) = unit_frames.at(n).at(16 - y - 1).at(x);
+                    building_buffer.at(index) = buildings_frames.at(n).at(32 - y - 1).at(x);
+                }
             }
-          }
         }
 
-        SDL_Texture *tmp = SDL_CreateTexture(
-            engine.renderer(), SDL_PIXELFORMAT_RGBA8888,
-            SDL_TEXTUREACCESS_STATIC, unit_frames.size() * 16, 16);
+        SDL_Texture* tmp = SDL_CreateTexture(
+            engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
+            buildings_frames.size() * 16, 32);
 
         SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
 
-        if (tmp == nullptr) {
-          throw std::runtime_error(
-              "Fehler beim Erstellen der Textur für die Units: " +
-              std::string(SDL_GetError()));
+        if (tmp == nullptr)
+        {
+            throw std::runtime_error(
+                "Fehler beim Erstellen der Textur für die Buildings: " +
+                std::string(SDL_GetError()));
         }
 
-        if (SDL_UpdateTexture(tmp, NULL, unit_buffer.data(),
-                              unit_frames.size() * 16 * sizeof(int32_t)) != 0) {
-          throw std::runtime_error(
-              "Fehler beim updaten der Textur für die Units: " +
-              std::string(SDL_GetError()));
+        if (SDL_UpdateTexture(
+                tmp, NULL, building_buffer.data(),
+                buildings_frames.size() * 16 * sizeof(int32_t)) != 0)
+        {
+            throw std::runtime_error(
+                "Fehler beim updaten der Textur für die Buildings: " + std::string(SDL_GetError()));
         }
 
-        unit_textures.at(faction_idx)
-            .at(unit_idx)
-            .push_back(std::pair<SDL_Texture *, int>(tmp, unit_frames.size()));
-      }
-
-      for (size_t movement_state_idx = 0;
-           movement_state_idx < unit_movement_states.size();
-           movement_state_idx++) {
-        std::string movement_state =
-            unit_movement_states.at(movement_state_idx);
-
-        HighFive::DataSet units_ds = file.getDataSet(
-            "units/" + faction + "/" + unit + "/movement/" + movement_state);
-
-        std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
-        units_ds.read(unit_frames);
+        this->building_textures.push_back(tmp);
+    }
 
-        std::vector<uint32_t> unit_buffer(24 * 24 * unit_frames.size(), 0);
+    this->building_width = 16;
+    this->building_height = 32;
+
+    // Units
+    std::vector<std::string> unit_factions({"red", "blue", "green", "yellow", "purple"});
+
+    std::vector<std::string> units(
+        {"infantery", "mechanized_infantery", "recon", "medium_tank", "heavy_tank", "neo_tank",
+         "apc", "anti_air_tank", "artillery", "rocket_artillery", "anti_air_missile_launcher",
+         "fighter", "bomber", "battle_helicopter", "transport_helicopter", "battleship", "cruiser",
+         "lander", "submarine"});
+
+    std::vector<std::string> unit_states({"idle", "unavailable"});
+    std::vector<std::string> unit_movement_states({"left", "right", "down", "up"});
+
+    // every factions sub data set
+    for (size_t faction_idx = 0; faction_idx < unit_factions.size(); faction_idx++)
+    {
+        std::string faction = unit_factions.at(faction_idx);
+        // Create entry for units for in a faction
+        unit_textures.push_back(std::vector<std::vector<std::pair<SDL_Texture*, int>>>());
+
+        // every unit sub data set
+        for (size_t unit_idx = 0; unit_idx < units.size(); unit_idx++)
+        {
+            std::string unit = units.at(unit_idx);
+
+            // Create entry for states for a unit
+            unit_textures.at(faction_idx).push_back(std::vector<std::pair<SDL_Texture*, int>>());
+
+            // every state sub data set
+            for (size_t state_idx = 0; state_idx < unit_states.size(); state_idx++)
+            {
+                std::string unit_state = unit_states.at(state_idx);
+
+                HighFive::DataSet units_ds =
+                    file.getDataSet("units/" + faction + "/" + unit + "/" + unit_state);
+
+                std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
+                units_ds.read(unit_frames);
+
+                std::vector<uint32_t> unit_buffer(16 * 16 * unit_frames.size(), 0);
+
+                for (size_t n = 0; n < unit_frames.size(); n++)
+                {
+                    for (size_t y = 0; y < 16; y++)
+                    {
+                        for (size_t x = 0; x < 16; x++)
+                        {
+                            size_t index = (y * unit_frames.size() * 16) + (n * 16 + x);
+
+                            unit_buffer.at(index) = unit_frames.at(n).at(16 - y - 1).at(x);
+                        }
+                    }
+                }
+
+                SDL_Texture* tmp = SDL_CreateTexture(
+                    engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
+                    unit_frames.size() * 16, 16);
+
+                SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
+
+                if (tmp == nullptr)
+                {
+                    throw std::runtime_error(
+                        "Fehler beim Erstellen der Textur für die Units: " +
+                        std::string(SDL_GetError()));
+                }
+
+                if (SDL_UpdateTexture(
+                        tmp, NULL, unit_buffer.data(), unit_frames.size() * 16 * sizeof(int32_t)) !=
+                    0)
+                {
+                    throw std::runtime_error(
+                        "Fehler beim updaten der Textur für die Units: " +
+                        std::string(SDL_GetError()));
+                }
+
+                unit_textures.at(faction_idx)
+                    .at(unit_idx)
+                    .push_back(std::pair<SDL_Texture*, int>(tmp, unit_frames.size()));
+            }
 
-        for (size_t n = 0; n < unit_frames.size(); n++) {
-          for (size_t y = 0; y < 24; y++) {
-            for (size_t x = 0; x < 24; x++) {
-              size_t index = (y * unit_frames.size() * 24) + (n * 24 + x);
+            // every movement state sub data set
+            for (size_t movement_state_idx = 0; movement_state_idx < unit_movement_states.size();
+                 movement_state_idx++)
+            {
+                std::string movement_state = unit_movement_states.at(movement_state_idx);
+
+                HighFive::DataSet units_ds = file.getDataSet(
+                    "units/" + faction + "/" + unit + "/movement/" + movement_state);
+
+                std::vector<std::vector<std::vector<uint32_t>>> unit_frames;
+                units_ds.read(unit_frames);
+
+                std::vector<uint32_t> unit_buffer(24 * 24 * unit_frames.size(), 0);
+
+                for (size_t n = 0; n < unit_frames.size(); n++)
+                {
+                    for (size_t y = 0; y < 24; y++)
+                    {
+                        for (size_t x = 0; x < 24; x++)
+                        {
+                            size_t index = (y * unit_frames.size() * 24) + (n * 24 + x);
+
+                            unit_buffer.at(index) = unit_frames.at(n).at(24 - y - 1).at(x);
+                        }
+                    }
+                }
+
+                SDL_Texture* tmp = SDL_CreateTexture(
+                    engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
+                    unit_frames.size() * 24, 24);
+
+                SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
+
+                if (tmp == nullptr)
+                {
+                    throw std::runtime_error(
+                        "Fehler beim Erstellen der Textur für die Units: " +
+                        std::string(SDL_GetError()));
+                }
+
+                if (SDL_UpdateTexture(
+                        tmp, NULL, unit_buffer.data(), unit_frames.size() * 24 * sizeof(int32_t)) !=
+                    0)
+                {
+                    throw std::runtime_error(
+                        "Fehler beim updaten der Textur für die Units: " +
+                        std::string(SDL_GetError()));
+                }
+
+                unit_textures.at(faction_idx)
+                    .at(unit_idx)
+                    .push_back(std::pair<SDL_Texture*, int>(tmp, unit_frames.size()));
+            }
+        }
+    }
 
-              unit_buffer.at(index) = unit_frames.at(n).at(24 - y - 1).at(x);
+    this->unit_width = 16;
+    this->unit_height = 16;
+    this->unit_moving_width = 24;
+    this->unit_moving_height = 24;
+
+    // Effects
+    std::vector<std::string> effects(
+        {"land_explosion", "air_explosion", "naval_explosion", "submarine_hide",
+         "submarine_appear"});
+
+    // Every effect sub data set
+    for (size_t effect_idx = 0; effect_idx < effects.size(); effect_idx++)
+    {
+        HighFive::DataSet effect_ds = file.getDataSet("effects/" + effects[effect_idx]);
+
+        std::vector<std::vector<std::vector<uint32_t>>> effect_frames;
+        effect_ds.read(effect_frames);
+
+        std::vector<uint32_t> effect_buffer(32 * 32 * effect_frames.size(), 0);
+
+        // every animation frame
+        for (size_t n = 0; n < effect_frames.size(); n++)
+        {
+            for (size_t y = 0; y < 32; y++)
+            {
+                for (size_t x = 0; x < 32; x++)
+                {
+                    size_t index = (y * effect_frames.size() * 32) + (n * 32 + x);
+
+                    effect_buffer.at(index) = effect_frames.at(n).at(32 - y - 1).at(x);
+                }
             }
-          }
         }
 
-        SDL_Texture *tmp = SDL_CreateTexture(
-            engine.renderer(), SDL_PIXELFORMAT_RGBA8888,
-            SDL_TEXTUREACCESS_STATIC, unit_frames.size() * 24, 24);
+        SDL_Texture* tmp = SDL_CreateTexture(
+            engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
+            effect_frames.size() * 32, 32);
 
         SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
 
-        if (tmp == nullptr) {
-          throw std::runtime_error(
-              "Fehler beim Erstellen der Textur für die Units: " +
-              std::string(SDL_GetError()));
+        if (tmp == nullptr)
+        {
+            throw std::runtime_error(
+                "Fehler beim Erstellen der Textur für die Effects: " + std::string(SDL_GetError()));
         }
 
-        if (SDL_UpdateTexture(tmp, NULL, unit_buffer.data(),
-                              unit_frames.size() * 24 * sizeof(int32_t)) != 0) {
-          throw std::runtime_error(
-              "Fehler beim updaten der Textur für die Units: " +
-              std::string(SDL_GetError()));
+        if (SDL_UpdateTexture(
+                tmp, NULL, effect_buffer.data(), effect_frames.size() * 32 * sizeof(int32_t)) != 0)
+        {
+            throw std::runtime_error(
+                "Fehler beim updaten der Textur für die Tiles: " + std::string(SDL_GetError()));
         }
 
-        unit_textures.at(faction_idx)
-            .at(unit_idx)
-            .push_back(std::pair<SDL_Texture *, int>(tmp, unit_frames.size()));
-      }
+        effect_textures.push_back(std::pair<SDL_Texture*, int>(tmp, effect_frames.size()));
     }
-  }
-
-  this->unit_width = 16;
-  this->unit_height = 16;
-  this->unit_moving_width = 24;
-  this->unit_moving_height = 24;
-
-  // Effects
-  std::vector<std::string> effects({"land_explosion", "air_explosion",
-                                    "naval_explosion", "submarine_hide",
-                                    "submarine_appear"});
-
-  for (size_t effect_idx = 0; effect_idx < effects.size(); effect_idx++) {
-    HighFive::DataSet effect_ds =
-        file.getDataSet("effects/" + effects[effect_idx]);
-
-    std::vector<std::vector<std::vector<uint32_t>>> effect_frames;
-    effect_ds.read(effect_frames);
-
-    std::vector<uint32_t> effect_buffer(32 * 32 * effect_frames.size(), 0);
-
-    for (size_t n = 0; n < effect_frames.size(); n++) {
-      for (size_t y = 0; y < 32; y++) {
-        for (size_t x = 0; x < 32; x++) {
-          size_t index = (y * effect_frames.size() * 32) + (n * 32 + x);
-
-          effect_buffer.at(index) = effect_frames.at(n).at(32 - y - 1).at(x);
-        }
-      }
-    }
-
-    SDL_Texture *tmp = SDL_CreateTexture(
-        engine.renderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC,
-        effect_frames.size() * 32, 32);
-
-    SDL_SetTextureBlendMode(tmp, SDL_BLENDMODE_BLEND);
-
-    if (tmp == nullptr) {
-      throw std::runtime_error(
-          "Fehler beim Erstellen der Textur für die Effects: " +
-          std::string(SDL_GetError()));
-    }
-
-    if (SDL_UpdateTexture(tmp, NULL, effect_buffer.data(),
-                          effect_frames.size() * 32 * sizeof(int32_t)) != 0) {
-      throw std::runtime_error(
-          "Fehler beim updaten der Textur für die Tiles: " +
-          std::string(SDL_GetError()));
-    }
-
-    effect_textures.push_back(
-        std::pair<SDL_Texture *, int>(tmp, effect_frames.size()));
-  }
 
-  this->effect_width = 32;
-  this->effect_height = 32;
+    this->effect_width = 32;
+    this->effect_height = 32;
 }
 
 // Tiles
 
-int Spritesheet::get_tile_width() { return tile_width; }
+int Spritesheet::get_tile_width()
+{
+    return tile_width;
+}
 
-int Spritesheet::get_tile_height() { return tile_height; }
+int Spritesheet::get_tile_height()
+{
+    return tile_height;
+}
 
-std::vector<std::pair<SDL_Texture *, int>> &Spritesheet::get_tile_textures() {
-  return tile_textures;
+std::vector<std::pair<SDL_Texture*, int>>& Spritesheet::get_tile_textures()
+{
+    return tile_textures;
 }
 
 // Buildings
-int Spritesheet::get_building_width() { return this->building_width; }
+int Spritesheet::get_building_width()
+{
+    return this->building_width;
+}
 
-int Spritesheet::get_building_height() { return this->building_height; }
+int Spritesheet::get_building_height()
+{
+    return this->building_height;
+}
 
-std::vector<SDL_Texture *> &Spritesheet::get_building_textures() {
-  return building_textures;
+std::vector<SDL_Texture*>& Spritesheet::get_building_textures()
+{
+    return building_textures;
 }
 
 // Units
-int Spritesheet::get_unit_width() { return this->unit_width; }
+int Spritesheet::get_unit_width()
+{
+    return this->unit_width;
+}
 
-int Spritesheet::get_unit_height() { return this->unit_height; }
+int Spritesheet::get_unit_height()
+{
+    return this->unit_height;
+}
 
-int Spritesheet::get_unit_moving_width() { return this->unit_moving_width; }
+int Spritesheet::get_unit_moving_width()
+{
+    return this->unit_moving_width;
+}
 
-int Spritesheet::get_unit_moving_height() { return this->unit_moving_height; }
+int Spritesheet::get_unit_moving_height()
+{
+    return this->unit_moving_height;
+}
 
-std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>> &
-Spritesheet::get_unit_textures() {
-  return this->unit_textures;
+std::vector<std::vector<std::vector<std::pair<SDL_Texture*, int>>>>&
+Spritesheet::get_unit_textures()
+{
+    return this->unit_textures;
 }
 
 // Effects
-int Spritesheet::get_effect_width() { return this->effect_width; }
+int Spritesheet::get_effect_width()
+{
+    return this->effect_width;
+}
 
-int Spritesheet::get_effect_height() { return this->effect_height; }
+int Spritesheet::get_effect_height()
+{
+    return this->effect_height;
+}
 
-std::vector<std::pair<SDL_Texture *, int>> &Spritesheet::get_effect_textures() {
-  return this->effect_textures;
+std::vector<std::pair<SDL_Texture*, int>>& Spritesheet::get_effect_textures()
+{
+    return this->effect_textures;
 }
 
-Spritesheet::~Spritesheet() {
-  for (std::pair<SDL_Texture *, int> tile_texture : tile_textures) {
-    SDL_DestroyTexture(tile_texture.first);
-  }
-
-  for (SDL_Texture *building_texture : building_textures) {
-    SDL_DestroyTexture(building_texture);
-  }
-
-  for (std::vector<std::vector<std::pair<SDL_Texture *, int>>> faction :
-       unit_textures) {
-    for (std::vector<std::pair<SDL_Texture *, int>> unit : faction) {
-      for (std::pair<SDL_Texture *, int> state : unit) {
-        SDL_DestroyTexture(state.first);
-      }
+Spritesheet::~Spritesheet()
+{
+    for (std::pair<SDL_Texture*, int> tile_texture : tile_textures)
+    {
+        SDL_DestroyTexture(tile_texture.first);
+    }
+
+    for (SDL_Texture* building_texture : building_textures)
+    {
+        SDL_DestroyTexture(building_texture);
+    }
+
+    for (std::vector<std::vector<std::pair<SDL_Texture*, int>>> faction : unit_textures)
+    {
+        for (std::vector<std::pair<SDL_Texture*, int>> unit : faction)
+        {
+            for (std::pair<SDL_Texture*, int> state : unit)
+            {
+                SDL_DestroyTexture(state.first);
+            }
+        }
     }
-  }
 }
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/spritesheet.hpp b/src/spritesheet.hpp
index d7d8b07..c6ae316 100644
--- a/src/spritesheet.hpp
+++ b/src/spritesheet.hpp
@@ -1,81 +1,180 @@
+/**
+ * Spritesheet.hpp
+ *
+ * @date 30.1.2025
+ * @author Frederik Keens
+ * @author David Maul
+ */
+
 #pragma once
 
+#include <SDL_render.h>
 #include <SDL.h>
 #include <SDL_render.h>
 #include <string>
 #include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 // Forward declaration
 class Engine;
 
-class Spritesheet {
-public:
-  Spritesheet(std::string path, Engine &engine);
-
-  ~Spritesheet();
-
-  Spritesheet(const Spritesheet &) = delete;
-
-  Spritesheet &operator=(const Spritesheet &) = delete;
-
-  // Tiles
-
-  int get_tile_width();
-
-  int get_tile_height();
-
-  std::vector<std::pair<SDL_Texture *, int>> &get_tile_textures();
-
-  // Buildings
-  int get_building_width();
-
-  int get_building_height();
-
-  std::vector<SDL_Texture *> &get_building_textures();
-
-  // Units
-  int get_unit_width();
-
-  int get_unit_height();
-
-  int get_unit_moving_width();
-
-  int get_unit_moving_height();
-
-  std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>> &
-  get_unit_textures();
-
-  // Effects
-  int get_effect_width();
-
-  int get_effect_height();
-
-  std::vector<std::pair<SDL_Texture *, int>> &get_effect_textures();
-
-private:
-  // Tiles
-  int tile_width;
-  int tile_height;
-  std::vector<std::pair<SDL_Texture *, int>> tile_textures;
-
-  // Buildings
-  std::vector<SDL_Texture *> building_textures;
-  int building_width;
-  int building_height;
-
-  // Units
-  std::vector<std::vector<std::vector<std::pair<SDL_Texture *, int>>>>
-      unit_textures;
-  int unit_width;
-  int unit_height;
-  int unit_moving_width;
-  int unit_moving_height;
-
-  // Effects
-  std::vector<std::pair<SDL_Texture *, int>> effect_textures;
-  int effect_width;
-  int effect_height;
+/**
+ * Spritesheet representation
+ */
+class Spritesheet
+{
+    public:
+        /**
+         * Constructor
+         *
+         * @param path Path to the file to load the spritesheet from
+         * @param path Engine object with valid SDL context
+         */
+        Spritesheet(std::string path, Engine& engine);
+
+        /**
+         * Destructor
+         */
+        ~Spritesheet();
+
+        Spritesheet(const Spritesheet&) = delete;
+
+        Spritesheet& operator=(const Spritesheet&) = delete;
+
+        // Tiles
+
+        /**
+         * @return The width of a floor tile in pixels
+         */
+        int get_tile_width();
+
+        /**
+         * @return The height of a floor tile in pixels
+         */
+        int get_tile_height();
+
+        /**
+         * Gets vector containing the pairs of an SDL Texture
+         * and the number animations steps it has.
+         *
+         * E.g. The vector at 1 contains a pair of an SDL Texture for water, its animations
+         * and the number of animation steps. Animation frames are store linearised.
+         *
+         * Which index respresents which tile can be found in the enum TileId of tile.hpp
+         *
+         * @return A vector of all floor tile textures and their animations
+         */
+        std::vector<std::pair<SDL_Texture*, int>>& get_tile_textures();
+
+        // Buildings
+
+        /**
+         * @return The width of a building in pixels
+         */
+        int get_building_width();
+
+        /**
+         * @return The height of a building in pixels
+         */
+        int get_building_height();
+
+        /**
+         * Every element represents the texture for all buildings from a faction linearised.
+         *
+         * Which FactionId represents which color
+         * can be found in the BuildingId enum in building.hpp
+         *
+         * Order of the building sprites is the same as in buildingId enum in building.hpp
+         *
+         * @return Vector of all Building textures
+         */
+        std::vector<SDL_Texture*>& get_building_textures();
+
+        // Units
+
+        /**
+         * @return The width of a unit while standing still in pixels
+         */
+        int get_unit_width();
+
+        /**
+         * @return The height of a unit while standing still in pixels
+         */
+        int get_unit_height();
+
+        /**
+         * @return The width of a unit while moving in pixels
+         */
+        int get_unit_moving_width();
+
+        /**
+         * @return The height of a unit while moving in pixels
+         */
+        int get_unit_moving_height();
+
+        /**
+         * Gets the hierarchical vector of all unit textures.
+         *
+         * The vector groups the faction, the UnitId and the state for each unit.
+         * The pair consist of the texture for that combination and the number of animation steps.
+         *
+         * E.g. A red faction(0) Recon(2) Unit that's unavailable(1) would be at [0][2][1].
+         * Animation frames are linearised.
+         *
+         * Indices can be found in the enums of unit.hpp
+         *
+         * @return A 3-dimensional vector of pairs consisting of a texture and
+         * the number of animation steps
+         */
+        std::vector<std::vector<std::vector<std::pair<SDL_Texture*, int>>>>& get_unit_textures();
+
+        // Effects
+
+        /**
+         * @return The width of an effect in pixels
+         */
+        int get_effect_width();
+
+        /**
+         * @return The height of an effect in pixels
+         */
+        int get_effect_height();
+
+        /**
+         * Vector that contains pairs of effect textures and the number of animation steps it has.
+         *
+         * Each texture of an element is a pair of an effect
+         * and all its animation frames linearised.
+         *
+         * Which index represents which effect can be found in the EffectId enum in effect.hpp
+         *
+         * @return A vector of all effects and its animations
+         */
+        std::vector<std::pair<SDL_Texture*, int>>& get_effect_textures();
+
+    private:
+        // Tiles
+        int                                       tile_width;
+        int                                       tile_height;
+        std::vector<std::pair<SDL_Texture*, int>> tile_textures;
+
+        // Buildings
+        std::vector<SDL_Texture*> building_textures;
+        int                       building_width;
+        int                       building_height;
+
+        // Units
+        std::vector<std::vector<std::vector<std::pair<SDL_Texture*, int>>>> unit_textures;
+        int                                                                 unit_width;
+        int                                                                 unit_height;
+        int                                                                 unit_moving_width;
+        int                                                                 unit_moving_height;
+
+        // Effects
+        std::vector<std::pair<SDL_Texture*, int>> effect_textures;
+        int                                       effect_width;
+        int                                       effect_height;
 };
 } // namespace advanced_wars
diff --git a/src/tile.cpp b/src/tile.cpp
index 909b7fc..525ee83 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -2,35 +2,33 @@
 #include "spritesheet.hpp"
 #include <vector>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-Tile::Tile(TileId id, int x, int y)
-    : id(id), x(x), y(y) {
+Tile::Tile(TileId id, int x, int y) : id(id), x(x), y(y) {}
 
-      };
+void Tile::render(Engine* engine, int scale)
+{
+    Spritesheet* spritesheet = engine->get_spritesheet();
 
-void Tile::render(Engine &engine, int scale) {
-  Spritesheet *spritesheet = engine.get_spritesheet();
+    int step =
+        engine->get_stage() % spritesheet->get_tile_textures().at(static_cast<int>(id)).second;
 
-  int step = engine.get_stage() %
-             spritesheet->get_tile_textures().at(static_cast<int>(id)).second;
+    SDL_Rect src;
+    src.x = step * spritesheet->get_tile_width();
+    src.y = 0;
+    src.w = spritesheet->get_tile_width();
+    src.h = spritesheet->get_tile_height();
 
-  SDL_Rect src;
-  src.x = step * spritesheet->get_tile_width();
-  src.y = 0;
-  src.w = spritesheet->get_tile_width();
-  src.h = spritesheet->get_tile_height();
+    SDL_Rect dest;
+    dest.x = x * spritesheet->get_tile_width() * scale;
+    dest.y = y * spritesheet->get_tile_height() * scale;
+    dest.w = spritesheet->get_tile_width() * scale;
+    dest.h = spritesheet->get_tile_height() * scale;
 
-  SDL_Rect dest;
-  dest.x = x * spritesheet->get_tile_width() * scale;
-  dest.y = y * spritesheet->get_tile_height() * scale;
-  dest.w = spritesheet->get_tile_width() * scale;
-  dest.h = spritesheet->get_tile_height() * scale;
-
-  SDL_RenderCopyEx(
-      engine.renderer(),
-      spritesheet->get_tile_textures().at(static_cast<int>(id)).first, &src,
-      &dest, 0, NULL, SDL_FLIP_NONE);
+    SDL_RenderCopyEx(
+        engine->renderer(), spritesheet->get_tile_textures().at(static_cast<int>(id)).first, &src,
+        &dest, 0, NULL, SDL_FLIP_NONE);
 }
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/tile.hpp b/src/tile.hpp
index cf54b32..ae147b8 100644
--- a/src/tile.hpp
+++ b/src/tile.hpp
@@ -3,49 +3,52 @@
 #include "engine.hpp"
 #include "scene.hpp"
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-enum class TileId {
-  PLAIN = 0,
-  WATER = 1,
-  FOREST = 2,
-  MOUNTAIN = 3,
-  BRIDGE_HORIZONTAL = 4,
-  BRIDGE_VERTICAL = 5,
-  STREET_HORIZONTAL = 6,
-  STREET_VERTICAL = 7,
-  STREET_CROSSING = 8,
-  STREET_JUNCTION_RIGHT = 9,
-  STREET_JUNCTION_LEFT = 10,
-  STREET_JUNCTION_DOWN = 11,
-  STREET_JUNCTION_UP = 12,
-  STREET_CORNER_TOP_LEFT = 13,
-  STREET_CORNER_TOP_RIGHT = 14,
-  STREET_CORNER_BOTTOM_LEFT = 15,
-  STREET_CORNER_BOTTOM_RIGHT = 16,
-  RIFF = 17,
-  CLIFF_TOP = 18,
-  CLIFF_BOTTOM = 19,
-  CLIFF_LEFT = 20,
-  CLIFF_RIGHT = 21,
-  CLIFF_CORNER_TOP_LEFT = 22,
-  CLIFF_CORNER_TOP_RIGHT = 23,
-  CLIFF_CORNER_BOTTOM_LEFT = 24,
-  CLIFF_CORNER_BOTTOM_RIGHT = 25,
-  CLIFF_INVERSE_CORNER_TOP_LEFT = 26,
-  CLIFF_INVERSE_CORNER_TOP_RIGHT = 27,
-  CLIFF_INVERSE_CORNER_BOTTOM_LEFT = 28,
-  CLIFF_INVERSE_CORNER_BOTTOM_RIGHT = 29,
+enum class TileId
+{
+    PLAIN = 0,
+    WATER = 1,
+    FOREST = 2,
+    MOUNTAIN = 3,
+    BRIDGE_HORIZONTAL = 4,
+    BRIDGE_VERTICAL = 5,
+    STREET_HORIZONTAL = 6,
+    STREET_VERTICAL = 7,
+    STREET_CROSSING = 8,
+    STREET_JUNCTION_RIGHT = 9,
+    STREET_JUNCTION_LEFT = 10,
+    STREET_JUNCTION_DOWN = 11,
+    STREET_JUNCTION_UP = 12,
+    STREET_CORNER_TOP_LEFT = 13,
+    STREET_CORNER_TOP_RIGHT = 14,
+    STREET_CORNER_BOTTOM_LEFT = 15,
+    STREET_CORNER_BOTTOM_RIGHT = 16,
+    RIFF = 17,
+    CLIFF_TOP = 18,
+    CLIFF_BOTTOM = 19,
+    CLIFF_LEFT = 20,
+    CLIFF_RIGHT = 21,
+    CLIFF_CORNER_TOP_LEFT = 22,
+    CLIFF_CORNER_TOP_RIGHT = 23,
+    CLIFF_CORNER_BOTTOM_LEFT = 24,
+    CLIFF_CORNER_BOTTOM_RIGHT = 25,
+    CLIFF_INVERSE_CORNER_TOP_LEFT = 26,
+    CLIFF_INVERSE_CORNER_TOP_RIGHT = 27,
+    CLIFF_INVERSE_CORNER_BOTTOM_LEFT = 28,
+    CLIFF_INVERSE_CORNER_BOTTOM_RIGHT = 29,
 };
 
-class Tile {
-public:
-  Tile(TileId id, int x, int y);
-  TileId id;
-  int x;
-  int y;
+class Tile
+{
+    public:
+        Tile(TileId id, int x, int y);
+        TileId id;
+        int    x;
+        int    y;
 
-  void render(Engine &engine, int scale);
+        void render(Engine* engine, int scale);
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/ui/contextmenu.cpp b/src/ui/contextmenu.cpp
new file mode 100644
index 0000000..8bae5ff
--- /dev/null
+++ b/src/ui/contextmenu.cpp
@@ -0,0 +1,83 @@
+#include "contextmenu.hpp"
+#include <iostream>
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+    ContextMenu::ContextMenu()
+        : selectedOption(0) {}
+
+    ContextMenu::~ContextMenu() {}
+
+    void ContextMenu::setOptions(const std::vector<std::string>& newOptions) {
+        options = newOptions;
+        selectedOption = 0; // Reset auf die erste Option
+    }
+
+    void ContextMenu::render(Engine* engine) {
+        if (!options.empty()) {
+            if (TTF_Init() == -1) {
+                std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+                return;
+            }
+
+            std::string basePath = SDL_GetBasePath();
+            std::string relativePath = "assets/ARCADECLASSIC.TTF";
+            std::string fullPath = basePath + relativePath;
+            TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 16);
+            if (!font) {
+                std::cerr << "Failed to load font: " << TTF_GetError() << std::endl;
+                return;
+            }
+
+            SDL_Color white = {255, 255, 255, 255};
+            SDL_Color yellow = {192, 255, 0, 255};
+
+            int spacing = 20; // Abstand zwischen den Optionen
+
+            //box around options
+            SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 255, 255);
+            SDL_Rect box = {x, y - 3, 50, static_cast<int>(options.size() * spacing)};
+            SDL_RenderFillRect(engine->renderer(), &box);
+
+            SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255);
+            
+            for (size_t i = 0; i < options.size(); ++i) {
+                SDL_Surface* textSurface = TTF_RenderText_Solid(font, options[i].c_str(), (i == selectedOption) ? yellow : white);
+                if (!textSurface) {
+                    continue;
+                }
+
+                SDL_Texture* textTexture = SDL_CreateTextureFromSurface(engine->renderer(), textSurface);
+                SDL_Rect textRect = {x+10, y + static_cast<int>(i * spacing), textSurface->w, textSurface->h};
+                SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect);
+
+                SDL_DestroyTexture(textTexture);
+                SDL_FreeSurface(textSurface);
+            }
+
+            TTF_CloseFont(font);
+            TTF_Quit();
+        }
+    }
+
+    void ContextMenu::handleEvent(SDL_Event& event) {
+        if (event.type == SDL_KEYDOWN) {
+            if (event.key.keysym.sym == SDLK_DOWN) {
+                selectedOption = (selectedOption + 1) % options.size();
+            } else if (event.key.keysym.sym == SDLK_UP) {
+                selectedOption = (selectedOption - 1 + options.size()) % options.size();
+            }
+        }
+    }
+
+    std::string ContextMenu::getSelectedOption() {
+        return options[selectedOption];
+    }
+
+    void ContextMenu::update(int x, int y) {
+        this->x = x;
+        this->y = y;
+    }
+
+}
diff --git a/src/ui/contextmenu.hpp b/src/ui/contextmenu.hpp
new file mode 100644
index 0000000..94b095f
--- /dev/null
+++ b/src/ui/contextmenu.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <SDL.h>
+#include <vector>
+#include <string>
+#include "../scene.hpp"
+#include "../engine.hpp"
+
+namespace advanced_wars {
+
+class ContextMenu : public Scene {
+private:
+    size_t selectedOption;
+    std::vector<std::string> options;
+    int x;
+    int y;
+
+public:
+    ContextMenu();    
+
+    void setOptions(const std::vector<std::string>& newOptions);
+
+    void render(Engine* engine) override;
+
+    void handleEvent(SDL_Event& event);
+
+    void update(int x, int y);
+
+    std::string getSelectedOption();
+
+    ~ContextMenu();
+};
+
+}
\ No newline at end of file
diff --git a/src/ui/menu.cpp b/src/ui/menu.cpp
new file mode 100644
index 0000000..8029729
--- /dev/null
+++ b/src/ui/menu.cpp
@@ -0,0 +1,249 @@
+#include "menu.hpp"
+#include "../building.hpp"
+#include "../level.hpp"
+#include "../spritesheet.hpp"
+#include "../tile.hpp"
+#include "../unit.hpp"
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_ttf.h>
+#include <iostream>
+#include <string>
+
+namespace advanced_wars
+{
+
+Menu::Menu(int selectedOption)
+    : selectedOption(selectedOption), options({"Start Game", "Options", "Exit"}),
+      backgroundTexture(nullptr)
+{
+    if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG))
+    {
+        std::cerr << "Failed to initialize SDL_image: " << IMG_GetError() << std::endl;
+    }
+}
+
+Menu::~Menu()
+{
+    if (backgroundTexture)
+    {
+        SDL_DestroyTexture(backgroundTexture);
+    }
+    IMG_Quit();
+};
+
+void Menu::render(Engine* engine)
+{
+
+    // Iterate over all events
+    while (!engine->events().empty())
+    {
+        SDL_Event event = engine->events().at(0);
+        engine->events().pop_front();
+        handleEvent(engine, event);
+    }
+
+    if (backgroundTexture)
+    {
+        SDL_RenderCopy(engine->renderer(), backgroundTexture, nullptr, nullptr);
+    }
+    else
+    {
+        SDL_SetRenderDrawColor(engine->renderer(), 0, 0, 0, 255);
+        SDL_RenderClear(engine->renderer());
+    }
+
+    if (TTF_Init() == -1)
+    {
+        std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+        return;
+    }
+
+    std::string basePath = SDL_GetBasePath();
+    std::string relativePath = "assets/ARCADECLASSIC.TTF";
+    std::string fullPath = basePath + relativePath;
+    TTF_Font*   titleFont = TTF_OpenFont(fullPath.c_str(), 48);
+    if (!titleFont)
+    {
+        std::cerr << "Failed to load title font: " << fullPath << TTF_GetError() << std::endl;
+        return;
+    }
+
+    TTF_Font* menuFont = TTF_OpenFont(fullPath.c_str(), 24);
+    if (!menuFont)
+    {
+        TTF_CloseFont(titleFont);
+        std::cerr << "Failed to load menu font: " << fullPath << TTF_GetError() << std::endl;
+        return;
+    }
+
+    SDL_Color white = {255, 255, 255, 255};
+    SDL_Color yellow = {255, 255, 0, 255};
+
+    SDL_Surface* titleSurface = TTF_RenderText_Solid(titleFont, "Advanced Wars", white);
+    if (titleSurface)
+    {
+        SDL_Texture* titleTexture = SDL_CreateTextureFromSurface(engine->renderer(), titleSurface);
+        SDL_Rect     titleRect = {
+            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);
+    }
+
+    for (size_t i = 0; i < options.size(); ++i)
+    {
+        SDL_Surface* textSurface = TTF_RenderText_Solid(
+            menuFont, options[i].c_str(), (i == selectedOption) ? yellow : white);
+        if (!textSurface)
+        {
+            continue;
+        }
+
+        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};
+        SDL_RenderCopy(engine->renderer(), textTexture, nullptr, &textRect);
+
+        SDL_DestroyTexture(textTexture);
+        SDL_FreeSurface(textSurface);
+    }
+
+    TTF_CloseFont(titleFont);
+    TTF_CloseFont(menuFont);
+    TTF_Quit();
+
+    SDL_RenderPresent(engine->renderer());
+}
+
+void Menu::handleEvent(Engine* engine, SDL_Event& event)
+{
+    if (event.type == SDL_KEYDOWN)
+    {
+        if (event.key.keysym.sym == SDLK_DOWN)
+        {
+            selectedOption = (selectedOption + 1) % options.size();
+        }
+        else if (event.key.keysym.sym == SDLK_UP)
+        {
+            selectedOption = (selectedOption - 1 + options.size()) % options.size();
+        }
+        else if (event.key.keysym.sym == SDLK_RETURN)
+        {
+            if (options[selectedOption] == "Exit")
+            {
+                std::cout << "Exiting game..." << std::endl;
+                engine->exit();
+            }
+            else if (options[selectedOption] == "Start Game")
+            {
+                std::cout << "Starting game..." << std::endl;
+
+                // Construct a level
+                std::vector<Tile> tiles;
+                for (int y = 0; y < 20; y++)
+                {
+                    for (int x = 0; x < 20; x++)
+                    {
+                        tiles.push_back(Tile(TileId::PLAIN, x, y));
+                    }
+                }
+
+                // Fill the edges with water
+                for (size_t n = 0; n < 20; n++)
+                {
+                    // Vertical
+                    tiles.at(n * 20) = Tile(TileId::WATER, 0, n);
+                    tiles.at(n * 20 + 19) = Tile(TileId::WATER, 19, n);
+                    // Horizontal
+                    tiles.at(n) = Tile(TileId::WATER, n, 0);
+                    tiles.at(19 * 20 + n) = Tile(TileId::WATER, n, 19);
+                }
+
+                // Make the edges cliffs
+                for (size_t n = 1; n < 19; n++)
+                {
+                    // Vertical
+                    tiles.at(n * 20 + 1) = Tile(TileId::CLIFF_RIGHT, 1, n);
+                    tiles.at(n * 20 + 18) = Tile(TileId::CLIFF_LEFT, 18, n);
+
+                    // Horizontal
+                    tiles.at(20 + n) = Tile(TileId::CLIFF_BOTTOM, n, 1);
+                    tiles.at(18 * 20 + n) = Tile(TileId::CLIFF_TOP, n, 18);
+                }
+
+                // Fix the corners
+                tiles.at(20 + 1) = Tile(TileId::CLIFF_CORNER_TOP_LEFT, 1, 1);
+                tiles.at(20 + 18) = Tile(TileId::CLIFF_CORNER_TOP_RIGHT, 18, 1);
+                tiles.at(18 * 20 + 1) = Tile(TileId::CLIFF_CORNER_BOTTOM_LEFT, 1, 18);
+                tiles.at(18 * 20 + 18) = Tile(TileId::CLIFF_CORNER_BOTTOM_RIGHT, 18, 18);
+
+                // Buildings
+                std::vector<Building> buildings;
+
+                for (int y = 0; y < 6; y++)
+                {
+                    for (int x = 0; x < 5; x++)
+                    {
+                        BuildingId      id = static_cast<BuildingId>(x);
+                        BuildingFaction faction = static_cast<BuildingFaction>(y);
+
+                        buildings.push_back(Building(3 + x, 3 + 2 * y, id, faction));
+                    }
+                }
+
+                // Units
+                std::vector<Unit> units;
+
+                for (int y = 0; y < 19; y++)
+                {
+                    for (int x = 0; x < 6; x++)
+                    {
+                        units.push_back(Unit(
+                            x + 9, y + 2, UnitFaction::URED, static_cast<UnitId>(y),
+                            static_cast<UnitState>(x)));
+                    }
+                }
+
+                std::vector<Effect> effects(
+                    {Effect(3, 15, EffectId::LAND_EXPLOSION, false),
+                     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);
+
+                engine->push_scene(level);
+            }
+            else if (options[selectedOption] == "Options")
+            {
+                std::cout << "Opening options..." << std::endl;
+            }
+        }
+    }
+}
+
+void Menu::loadBackground(SDL_Renderer* renderer, const std::string& imagePath)
+{
+    // Lade das Hintergrundbild
+    SDL_Surface* backgroundSurface = IMG_Load(imagePath.c_str());
+    if (!backgroundSurface)
+    {
+        std::cerr << "Failed to load background image: " << IMG_GetError() << std::endl;
+        return;
+    }
+
+    // Erstelle eine Textur aus der Oberfläche und speichere sie als
+    // Klassenmitglied
+    backgroundTexture = SDL_CreateTextureFromSurface(renderer, backgroundSurface);
+    SDL_FreeSurface(backgroundSurface); // Oberfläche freigeben, da sie nicht mehr
+                                        // benötigt wird
+
+    if (!backgroundTexture)
+    {
+        std::cerr << "Failed to create background texture: " << SDL_GetError() << std::endl;
+    }
+}
+
+} // namespace advanced_wars
diff --git a/src/ui/menu.hpp b/src/ui/menu.hpp
new file mode 100644
index 0000000..43f84d0
--- /dev/null
+++ b/src/ui/menu.hpp
@@ -0,0 +1,86 @@
+#pragma once
+
+#include "../scene.hpp"
+#include <SDL.h>
+#include <array>
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace advanced_wars {
+
+/**
+ * @class Menu
+ * @brief Represents the main menu of the game, allowing navigation between different options.
+ * 
+ * This menu provides three selectable options:
+ * - "Start Game": Begins a new game session.
+ * - "Options": Opens the game settings.
+ * - "Exit": Closes the application.
+ */
+class Menu : public Scene {
+private:
+  size_t selectedOption; ///< Index of the currently selected menu option.
+  std::array<std::string, 3> options; ///< The available menu options.
+  SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if any).
+
+public:
+  /**
+   * @brief Constructs the Menu with an initial selected option.
+   * 
+   * Initializes the menu with the available options and sets the currently
+   * selected option based on the given index.
+   * 
+   * @param selectedOption The index of the initially selected menu option.
+   */
+  Menu(int selectedOption);
+
+  /**
+   * @brief Renders the menu on the screen.
+   * 
+   * This method clears the screen, draws the background (if available),
+   * renders the menu title, and displays the selectable options. The currently
+   * selected option is highlighted in a different color.
+   * 
+   * @param engine Pointer to the game engine, used for rendering.
+   */
+  void render(Engine *engine) override;
+
+  /**
+   * @brief Handles user input events for menu navigation.
+   * 
+   * This method processes keyboard input to navigate through the menu options.
+   * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option.
+   * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option.
+   * - **Enter (`SDLK_RETURN`)**: Confirms the selection:
+   *   - **"Start Game"**: Loads the game scene.
+   *   - **"Options"**: Opens the settings menu.
+   *   - **"Exit"**: Closes the application.
+   * 
+   * @param engine Pointer to the game engine, used to manage scenes.
+   * @param event The SDL event containing user input data.
+   */
+  void handleEvent(Engine *engine, SDL_Event &event);
+
+  /**
+   * @brief Loads a background image as a texture.
+   * 
+   * This method loads an image file, converts it into an SDL texture, and 
+   * assigns it as the menu's background. If the loading fails, an error is 
+   * logged, and the menu will display a plain black background instead.
+   * 
+   * @param renderer The SDL renderer used to create the texture.
+   * @param imagePath The file path to the background image.
+   */
+  void loadBackground(SDL_Renderer *renderer, const std::string &imagePath);
+
+  /**
+   * @brief Destroys the menu and releases resources.
+   * 
+   * Cleans up allocated resources, including the background texture (if loaded),
+   * and ensures that SDL_Image is properly shut down.
+   */
+  ~Menu();
+};
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/ui/pausemenu.cpp b/src/ui/pausemenu.cpp
new file mode 100644
index 0000000..0dd5928
--- /dev/null
+++ b/src/ui/pausemenu.cpp
@@ -0,0 +1,118 @@
+#include "pausemenu.hpp"
+#include "../engine.hpp"
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+PauseMenu::PauseMenu(int selectedOption, SDL_Texture *backgroundTexture)
+    : selectedOption(selectedOption),
+      options({"Resume", "Options", "Exit"}), backgroundTexture(backgroundTexture) {
+  // Initialize SDL_ttf
+  if (TTF_Init() == -1) {
+    std::cerr << "Failed to initialize SDL_ttf: " << TTF_GetError() << std::endl;
+  }
+
+  if (!backgroundTexture) {
+    this->backgroundTexture = nullptr;
+  }
+}
+
+PauseMenu::~PauseMenu() {
+  if (backgroundTexture) {
+    SDL_DestroyTexture(backgroundTexture);
+    backgroundTexture = nullptr;
+  }
+  TTF_Quit();
+}
+
+void PauseMenu::render(Engine *engine) {
+
+  while (!engine->events().empty()) {
+    SDL_Event event = engine->events().at(0);
+    engine->events().pop_front();
+    handleEvent(engine, event);
+  }
+
+  SDL_Renderer *renderer = engine->renderer();
+
+  // Render the existing level
+  //engine->render();
+
+  // Render the dialog background
+  if (backgroundTexture) {
+    SDL_RenderCopy(renderer, backgroundTexture, nullptr, nullptr);
+  }
+
+  if (TTF_Init() == -1) {
+    std::cerr << "Failed to initialize TTF: " << TTF_GetError() << std::endl;
+    return;
+  }
+
+  // Render the dialog options on top of the background
+  std::string basePath = SDL_GetBasePath();
+  std::string relativePath = "assets/ARCADECLASSIC.TTF";
+  std::string fullPath = basePath + relativePath;
+
+  TTF_Font *font = TTF_OpenFont(fullPath.c_str(), 24);
+  if (!font) {
+    std::cerr << "Failed to load menu font: " << fullPath << " " << TTF_GetError()
+              << std::endl;
+    return;
+  }
+
+  SDL_Color white = {255, 255, 255, 255};
+  SDL_Color yellow = {255, 255, 0, 255};
+
+  for (size_t i = 0; i < options.size(); ++i) {
+    SDL_Surface *textSurface = TTF_RenderText_Solid(
+        font, options[i].c_str(), (i == selectedOption) ? yellow : white);
+    SDL_Texture *textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
+    
+    SDL_Rect destRect = {100, static_cast<int>(100 + i * 50), textSurface->w, textSurface->h};  
+    SDL_RenderCopy(renderer, textTexture, nullptr, &destRect);
+
+    SDL_FreeSurface(textSurface);
+    SDL_DestroyTexture(textTexture);
+  }
+  TTF_CloseFont(font);
+  SDL_RenderPresent(renderer);
+}
+
+void PauseMenu::handleEvent(Engine *engine, SDL_Event &event) {
+  if (event.type == SDL_KEYDOWN) {
+    if (event.key.keysym.sym == SDLK_DOWN) {
+      selectedOption = (selectedOption + 1) % options.size();
+    } else if (event.key.keysym.sym == SDLK_UP) {
+      selectedOption = (selectedOption - 1 + options.size()) % options.size();
+    } else if (event.key.keysym.sym == SDLK_ESCAPE) {
+      std::cout << "Resuming game..." << std::endl;
+      engine->pop_scene();
+    } else if (event.key.keysym.sym == SDLK_RETURN) {
+      if (options[selectedOption] == "Exit") {
+        // exit into main menu
+        std::cout << "Exiting game..." << std::endl;
+        engine->return_to_menu();
+      } else if (options[selectedOption] == "Resume") {
+        // resume game
+        std::cout << "Resuming game..." << std::endl;
+        engine->pop_scene();
+      }
+    }
+
+  }
+  // Handle events for the pause menu
+}
+
+
+
+void PauseMenu::loadBackground(SDL_Renderer *renderer, const std::string &imagePath) {
+  SDL_Surface *surface = IMG_Load(imagePath.c_str());
+  if (!surface) {
+    std::cerr << "Failed to load image: " << IMG_GetError() << std::endl;
+    return;
+  }
+  backgroundTexture = SDL_CreateTextureFromSurface(renderer, surface);
+  SDL_FreeSurface(surface);
+}
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/ui/pausemenu.hpp b/src/ui/pausemenu.hpp
new file mode 100644
index 0000000..6dc2d2c
--- /dev/null
+++ b/src/ui/pausemenu.hpp
@@ -0,0 +1,92 @@
+#pragma once
+
+#include "../scene.hpp"
+#include <SDL.h>
+#include <array>
+#include <iostream>
+#include <string>
+#include <vector>
+#include <SDL_image.h>
+#include <SDL_ttf.h>
+
+namespace advanced_wars {
+
+/**
+ * @class PauseMenu
+ * @brief A scene that represents the in-game pause menu.
+ * 
+ * The pause menu allows the player to:
+ * - **Resume**: Return to the current game scene.
+ * - **Options**: (Currently not implemented).
+ * - **Exit**: Return to the main menu.
+ * 
+ * The menu supports keyboard navigation and responds to user input.
+ */
+class PauseMenu : public Scene {
+private:
+  size_t selectedOption; ///< Index of the currently selected menu option.
+  std::array<std::string, 3> options; ///< The available pause menu options.
+  SDL_Texture *backgroundTexture; ///< Pointer to the background texture (if available).
+
+public:
+  /**
+   * @brief Constructs the pause menu with a background texture.
+   * 
+   * The pause menu initializes the menu options and stores the provided
+   * background texture. If no texture is provided, a default black background is used.
+   * 
+   * @param selectedOption The index of the initially selected menu option.
+   * @param backgroundTexture A pointer to the background texture (can be nullptr).
+   */
+  PauseMenu(int selectedOption, SDL_Texture *backgroundTexture);
+
+  /**
+   * @brief Renders the pause menu on the screen.
+   * 
+   * This method:
+   * - Draws the background (if available).
+   * - Displays the menu options with the currently selected option highlighted.
+   * - Presents the rendered frame to the screen.
+   * 
+   * @param engine Pointer to the game engine, used for rendering.
+   */
+  void render(Engine *engine) override;
+
+  /**
+   * @brief Handles user input events for menu navigation.
+   * 
+   * This method processes keyboard input to navigate and interact with the pause menu.
+   * - **Arrow Down (`SDLK_DOWN`)**: Moves the selection to the next option.
+   * - **Arrow Up (`SDLK_UP`)**: Moves the selection to the previous option.
+   * - **Escape (`SDLK_ESCAPE`)**: Resumes the game by removing the pause menu.
+   * - **Enter (`SDLK_RETURN`)**: Executes the selected option:
+   *   - **"Resume"**: Closes the pause menu and resumes the game.
+   *   - **"Exit"**: Returns to the main menu.
+   * 
+   * @param engine Pointer to the game engine, used to manage scenes.
+   * @param event The SDL event containing user input data.
+   */
+  void handleEvent(Engine *engine, SDL_Event &event);
+
+  /**
+   * @brief Loads a background image as a texture.
+   * 
+   * This method loads an image file, converts it into an SDL texture, and assigns it
+   * as the menu’s background. If the loading fails, an error is logged, and the menu
+   * will display a plain black background instead.
+   * 
+   * @param renderer The SDL renderer used to create the texture.
+   * @param imagePath The file path to the background image.
+   */
+  void loadBackground(SDL_Renderer *renderer, const std::string &imagePath);
+
+  /**
+   * @brief Destroys the pause menu and releases resources.
+   * 
+   * Cleans up allocated resources, including the background texture (if loaded),
+   * and ensures that SDL_ttf is properly shut down.
+   */
+  ~PauseMenu();
+};
+
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.cpp b/src/unit.cpp
index c938f48..4ece9fb 100644
--- a/src/unit.cpp
+++ b/src/unit.cpp
@@ -1,187 +1,219 @@
 #include "unit.hpp"
 #include <iostream>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
-    : x(x), y(y), faction(faction), id(id), state(state), max_health(100) {
-  // das ist nur für Testzwecke
-  if (id == UnitId::INFANTERY) {
-    secondary_weapon = Weapon("Machine-Gun", {{UnitId::INFANTERY, 55}});
-  }
-  health = max_health;
-};
-
-void Unit::render(Engine &engine, int scale) {
-  Spritesheet *spritesheet = engine.get_spritesheet();
-
-  int step = engine.get_stage() % spritesheet->get_unit_textures()
-                                      .at(static_cast<int>(faction))
-                                      .at(static_cast<int>(id))
-                                      .at(static_cast<int>(state))
-                                      .second;
-
-  if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE) {
-
-    SDL_Rect src;
-    src.x = step * spritesheet->get_unit_width();
-    src.y = 0;
-    src.w = spritesheet->get_unit_width();
-    src.h = spritesheet->get_unit_height();
-
-    SDL_Rect dst;
-    dst.x = x * spritesheet->get_unit_width() * scale;
-    dst.y = y * spritesheet->get_unit_height() * scale;
-    dst.w = spritesheet->get_unit_width() * scale;
-    dst.h = spritesheet->get_unit_height() * scale;
-
-    SDL_RenderCopyEx(engine.renderer(),
-                     spritesheet->get_unit_textures()
-                         .at(static_cast<int>(faction))
-                         .at(static_cast<int>(id))
-                         .at(static_cast<int>(state))
-                         .first,
-                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
-  } else {
-    // The moving states have a resolution of 24x24 instead of 16x16 and need to
-    // be handled separately
-    SDL_Rect src;
-    src.x = step * spritesheet->get_unit_moving_width();
-    src.y = 0;
-    src.w = spritesheet->get_unit_moving_width();
-    src.h = spritesheet->get_unit_moving_height();
-
-    SDL_Rect dst;
-    dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
-    dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
-    dst.w = spritesheet->get_unit_moving_width() * scale;
-    dst.h = spritesheet->get_unit_moving_height() * scale;
-
-    SDL_RenderCopyEx(engine.renderer(),
-                     spritesheet->get_unit_textures()
-                         .at(static_cast<int>(faction))
-                         .at(static_cast<int>(id))
-                         .at(static_cast<int>(state))
-                         .first,
-                     &src, &dst, 0, NULL, SDL_FLIP_NONE);
-  }
+    : x(x), y(y), faction(faction), id(id), state(state), max_health(100)
+{
+    // das ist nur für Testzwecke
+    if (id == UnitId::INFANTERY)
+    {
+        secondary_weapon = Weapon(
+            "Machine-Gun", {
+                               {UnitId::INFANTERY, 55}
+        });
+    }
+    health = max_health;
+}
+
+void Unit::render(Engine* engine, int scale)
+{
+    Spritesheet* spritesheet = engine->get_spritesheet();
+
+    int step = engine->get_stage() % spritesheet->get_unit_textures()
+                                         .at(static_cast<int>(faction))
+                                         .at(static_cast<int>(id))
+                                         .at(static_cast<int>(state))
+                                         .second;
+
+    if (state == UnitState::IDLE || state == UnitState::UNAVAILABLE)
+    {
+
+        SDL_Rect src;
+        src.x = step * spritesheet->get_unit_width();
+        src.y = 0;
+        src.w = spritesheet->get_unit_width();
+        src.h = spritesheet->get_unit_height();
+
+        SDL_Rect dst;
+        dst.x = x * spritesheet->get_unit_width() * scale;
+        dst.y = y * spritesheet->get_unit_height() * scale;
+        dst.w = spritesheet->get_unit_width() * scale;
+        dst.h = spritesheet->get_unit_height() * scale;
+
+        SDL_RenderCopyEx(
+            engine->renderer(),
+            spritesheet->get_unit_textures()
+                .at(static_cast<int>(faction))
+                .at(static_cast<int>(id))
+                .at(static_cast<int>(state))
+                .first,
+            &src, &dst, 0, NULL, SDL_FLIP_NONE);
+    }
+    else
+    {
+        // The moving states have a resolution of 24x24 instead of 16x16 and need to
+        // be handled separately
+        SDL_Rect src;
+        src.x = step * spritesheet->get_unit_moving_width();
+        src.y = 0;
+        src.w = spritesheet->get_unit_moving_width();
+        src.h = spritesheet->get_unit_moving_height();
+
+        SDL_Rect dst;
+        dst.x = ((x * spritesheet->get_unit_width()) - 4) * scale;
+        dst.y = ((y * spritesheet->get_unit_height()) - 4) * scale;
+        dst.w = spritesheet->get_unit_moving_width() * scale;
+        dst.h = spritesheet->get_unit_moving_height() * scale;
+
+        SDL_RenderCopyEx(
+            engine->renderer(),
+            spritesheet->get_unit_textures()
+                .at(static_cast<int>(faction))
+                .at(static_cast<int>(id))
+                .at(static_cast<int>(state))
+                .first,
+            &src, &dst, 0, NULL, SDL_FLIP_NONE);
+    }
 }
 
-void Unit::attack(Unit *enemy) {
-  // Angenommen, primary_weapon und secondary_weapon wurden bereits korrekt
-  // initialisiert
-  auto primary_weapon_damage_it = primary_weapon.damage.find(enemy->id);
-  auto secondary_weapon_damage_it = secondary_weapon.damage.find(enemy->id);
+void Unit::attack(Unit* enemy)
+{
+    // Angenommen, primary_weapon und secondary_weapon wurden bereits korrekt
+    // initialisiert
+    auto primary_weapon_damage_it = primary_weapon.damage.find(enemy->id);
+    auto secondary_weapon_damage_it = secondary_weapon.damage.find(enemy->id);
+
+    int attacker_damage_value = 0;
 
-  int attacker_damage_value = 0;
+    // Die Waffe mit dem höchsten Schaden wählen
+    if (secondary_weapon_damage_it != secondary_weapon.damage.end())
+    {
+        attacker_damage_value = secondary_weapon_damage_it->second;
+    }
 
-  // Die Waffe mit dem höchsten Schaden wählen
-  if (secondary_weapon_damage_it != secondary_weapon.damage.end()) {
-    attacker_damage_value = secondary_weapon_damage_it->second;
-  }
+    if (primary_weapon_damage_it != primary_weapon.damage.end())
+    {
+        if (primary_weapon_damage_it->second > attacker_damage_value)
+        {
+            // Munitionsabzug sollte hier erfolgen, falls zutreffend
+            attacker_damage_value = primary_weapon_damage_it->second;
+        }
+    }
 
-  if (primary_weapon_damage_it != primary_weapon.damage.end()) {
-    if (primary_weapon_damage_it->second > attacker_damage_value) {
-      // Munitionsabzug sollte hier erfolgen, falls zutreffend
-      attacker_damage_value = primary_weapon_damage_it->second;
+    if (attacker_damage_value == 0)
+    {
+        std::cout << "No damage value found for attack from unit " << static_cast<int>(id)
+                  << " against unit " << static_cast<int>(enemy->id) << std::endl;
     }
-  }
-
-  if (attacker_damage_value == 0) {
-    std::cout << "No damage value found for attack from unit "
-              << static_cast<int>(id) << " against unit "
-              << static_cast<int>(enemy->id) << std::endl;
-  } else {
-    int off_damage =
-        attacker_damage_value * (static_cast<float>(health) / max_health);
-    enemy->health -= off_damage;
-    enemy->health = std::max(
-        0,
-        enemy->health); // Sicherstellen, dass die Gesundheit nicht negativ wird
-    std::cout << "Enemy health after attack: " << enemy->health << std::endl;
-
-    // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
-    if (enemy->health > 0) {
-      // Weapon tables for the defender
-      auto defender_primary_weapon_damage_it =
-          enemy->primary_weapon.damage.find(id);
-      auto defender_secondary_weapon_damage_it =
-          enemy->secondary_weapon.damage.find(id);
-
-      int defender_damage_value = 0; // Declare outside for later use
-
-      // Determine the damage value for the defender
-      if (defender_secondary_weapon_damage_it !=
-          enemy->secondary_weapon.damage.end()) {
-        defender_damage_value = defender_secondary_weapon_damage_it->second;
-      }
-
-      if (defender_primary_weapon_damage_it !=
-          enemy->primary_weapon.damage.end()) {
-        if (defender_primary_weapon_damage_it->second > defender_damage_value) {
-          // Munitionsabzug für primäre Waffe, falls zutreffend
-          defender_damage_value = defender_primary_weapon_damage_it->second;
+    else
+    {
+        int off_damage = attacker_damage_value * (static_cast<float>(health) / max_health);
+        enemy->health -= off_damage;
+        enemy->health = std::max(
+            0,
+            enemy->health); // Sicherstellen, dass die Gesundheit nicht negativ wird
+        std::cout << "Enemy health after attack: " << enemy->health << std::endl;
+
+        // Prüfen, ob der Gegner noch am Leben ist um zurückzuschlagen
+        if (enemy->health > 0)
+        {
+            // Weapon tables for the defender
+            auto defender_primary_weapon_damage_it = enemy->primary_weapon.damage.find(id);
+            auto defender_secondary_weapon_damage_it = enemy->secondary_weapon.damage.find(id);
+
+            int defender_damage_value = 0; // Declare outside for later use
+
+            // Determine the damage value for the defender
+            if (defender_secondary_weapon_damage_it != enemy->secondary_weapon.damage.end())
+            {
+                defender_damage_value = defender_secondary_weapon_damage_it->second;
+            }
+
+            if (defender_primary_weapon_damage_it != enemy->primary_weapon.damage.end())
+            {
+                if (defender_primary_weapon_damage_it->second > defender_damage_value)
+                {
+                    // Munitionsabzug für primäre Waffe, falls zutreffend
+                    defender_damage_value = defender_primary_weapon_damage_it->second;
+                }
+            }
+
+            // If a valid damage value was determined for retaliation
+            if (defender_damage_value > 0)
+            {
+                int def_damage = static_cast<int>(
+                    defender_damage_value * static_cast<float>(enemy->health) / enemy->max_health);
+                this->health -= def_damage;
+                this->health = std::max(0, this->health); // Safeguard against negative health
+                std::cout << "Ally health after retaliation: " << this->health << std::endl;
+            }
         }
-      }
-
-      // If a valid damage value was determined for retaliation
-      if (defender_damage_value > 0) {
-        int def_damage = static_cast<int>(defender_damage_value *
-                                          static_cast<float>(enemy->health) /
-                                          enemy->max_health);
-        this->health -= def_damage;
-        this->health =
-            std::max(0, this->health); // Safeguard against negative health
-        std::cout << "Ally health after retaliation: " << this->health
-                  << std::endl;
-      }
     }
-  }
 }
 
-void Unit::update_position(int posX, int posY) {
-  calc_state(posX, posY);
+void Unit::update_position(int posX, int posY)
+{
+    calc_state(posX, posY);
 
-  this->x = posX;
-  this->y = posY;
+    this->x = posX;
+    this->y = posY;
 }
 
-void Unit::calc_state(int posX, int posY) {
-  int deltaX = this->x - posX;
-  int deltaY = this->y - posY;
+void Unit::calc_state(int posX, int posY)
+{
+    int deltaX = this->x - posX;
+    int deltaY = this->y - posY;
 
-  if (deltaX == 0 && deltaY == 0) {
-    // Unit is already at the target position
-    return;
-  }
+    if (deltaX == 0 && deltaY == 0)
+    {
+        // Unit is already at the target position
+        return;
+    }
 
-  if (abs(deltaX) >= abs(deltaY)) {
-    if (deltaX > 0) {
-      this->state = advanced_wars::UnitState::MOVEMENTLEFT;
-    } else {
-      this->state = advanced_wars::UnitState::MOVEMENTRIGHT;
+    if (abs(deltaX) >= abs(deltaY))
+    {
+        if (deltaX > 0)
+        {
+            this->state = advanced_wars::UnitState::MOVEMENTLEFT;
+        }
+        else
+        {
+            this->state = advanced_wars::UnitState::MOVEMENTRIGHT;
+        }
     }
-  } else {
-    if (deltaY > 0) {
-      this->state = advanced_wars::UnitState::MOVEMENTUP;
-    } else {
-      this->state = advanced_wars::UnitState::MOVEMENTDOWN;
+    else
+    {
+        if (deltaY > 0)
+        {
+            this->state = advanced_wars::UnitState::MOVEMENTUP;
+        }
+        else
+        {
+            this->state = advanced_wars::UnitState::MOVEMENTDOWN;
+        }
     }
-  }
 }
 
-void Unit::on_left_click(SDL_Event event, std::vector<Unit> &unitVector) {
+void Unit::on_left_click(SDL_Event event)
+{
 
-  std::cout << "Left-button pressed on unit: " << this->health << std::endl;
+    std::cout << "Left-button pressed on unit: " << this->health << std::endl;
 }
 
-bool Unit::inRange(Unit *enemy) {
-  if (this->x == enemy->x) {
-    return abs(this->y - enemy->y) <= this->range;
-  } else if (this->y == enemy->y) {
-    return abs(this->x - enemy->x) <= this->range;
-  }
-  return false;
+bool Unit::inRange(Unit* enemy)
+{
+    if (this->x == enemy->x)
+    {
+        return abs(this->y - enemy->y) <= this->range;
+    }
+    else if (this->y == enemy->y)
+    {
+        return abs(this->x - enemy->x) <= this->range;
+    }
+    return false;
 }
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/unit.hpp b/src/unit.hpp
index 722e52f..489dd3c 100644
--- a/src/unit.hpp
+++ b/src/unit.hpp
@@ -1,137 +1,139 @@
 #pragma once
 
-#include <unordered_map>
 #include "engine.hpp"
 #include "weapon.hpp"
 #include <optional>
+#include <unordered_map>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
-enum class UnitFaction {
-  URED = 0,
-  UBLUE = 1,
-  UGREEN = 2,
-  UYELLOW = 3,
-  UPURPLE = 4,
+enum class UnitFaction
+{
+    URED = 0,
+    UBLUE = 1,
+    UGREEN = 2,
+    UYELLOW = 3,
+    UPURPLE = 4,
 };
 
-enum class UnitId {
-  INFANTERY = 0,
-  MECHANIZED_INFANTERY = 1,
-  RECON = 2,
-  MEDIUM_TANK = 3,
-  HEAVY_TANK = 4,
-  NEO_TANK = 5,
-  APC = 6,
-  ANTI_AIR_TANK = 7,
-  ARTILLERY = 8,
-  ROCKET_ARTILLERY = 9,
-  ANTI_AIR_MISSILE_LAUNCHER = 10,
-  FIGHTER = 11,
-  BOMBER = 12,
-  BATTLE_HELICOPTER = 13,
-  TRANSPORT_HELICOPTER = 14,
-  BATTLESHIP = 15,
-  CRUISER = 16,
-  LANDER = 17,
-  SUBMARINE = 18,
+enum class UnitId
+{
+    INFANTERY = 0,
+    MECHANIZED_INFANTERY = 1,
+    RECON = 2,
+    MEDIUM_TANK = 3,
+    HEAVY_TANK = 4,
+    NEO_TANK = 5,
+    APC = 6,
+    ANTI_AIR_TANK = 7,
+    ARTILLERY = 8,
+    ROCKET_ARTILLERY = 9,
+    ANTI_AIR_MISSILE_LAUNCHER = 10,
+    FIGHTER = 11,
+    BOMBER = 12,
+    BATTLE_HELICOPTER = 13,
+    TRANSPORT_HELICOPTER = 14,
+    BATTLESHIP = 15,
+    CRUISER = 16,
+    LANDER = 17,
+    SUBMARINE = 18,
 };
 
-enum class UnitState {
-  IDLE = 0,
-  UNAVAILABLE = 1,
-  MOVEMENTLEFT = 2,
-  MOVEMENTRIGHT = 3,
-  MOVEMENTDOWN = 4,
-  MOVEMENTUP = 5,
+enum class UnitState
+{
+    IDLE = 0,
+    UNAVAILABLE = 1,
+    MOVEMENTLEFT = 2,
+    MOVEMENTRIGHT = 3,
+    MOVEMENTDOWN = 4,
+    MOVEMENTUP = 5,
 };
 
-enum class MovementType {
-  FOOT = 0,
-  TIRES = 1,
-  TREAD = 2,
-  AIR = 3,
-  SHIP = 4,
-  LANDER = 5,
+enum class MovementType
+{
+    FOOT = 0,
+    TIRES = 1,
+    TREAD = 2,
+    AIR = 3,
+    SHIP = 4,
+    LANDER = 5,
 };
 
 using MatchupTable = std::unordered_map<UnitId, std::unordered_map<UnitId, int>>;
 
-class Unit {
-public:
-  int x;
-  int y;
-  int health; //health equals max_health at construction
-
-
-  Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
-  ~Unit() {
-        //Assuming that the destruktion of a unit triggers events
-    }
-
-  void render(Engine &engine, int scale);
-
-  /*
-  Check if attacker is in Range to initiate combat
-  TODO: This should probably tie back into rendering the units differently
-  If a unit is selected, it should call inRange on all other enemy units on the field
-  */
-
- bool inRange(Unit *enemy);
-
-  /*
-  The attacker will move towards the defender and thus initiate combat
-  @params Takes a reference to the defender
-
-  Will Update the health for both units
-  Attacker deals damage to the defender first
-  */
-
-  void attack(Unit* enemy) ;
-
-
-  /*
-  @params Takes the desired position of the unit and updates its values
-  This will teleport the unit, there is no smooth transition between tiles
-  */
-  void update_position(int posX, int posY);
-
-  /*
-  This function needs to be able to determine the possible movement-paths the unit can take
-  MUST take into consideration that different units behave differently on certain terrain
-  MUST show all movements possible
-  */
-  void calculate_movement();
-
-  
-  void calc_state(int posX, int posY);
-
-/*
-This function will be called by an external event-handler, eventually.
-It should start displaying standard unit information, such as UI and move_range
-*/
-void on_left_click(SDL_Event event, std::vector<Unit> &unitVector);
-
-private:
-  UnitFaction faction;
-  UnitId id;
-  UnitState state;
-
- 
-  int max_health; // max_health required for damage_scaling
-  int range;
-  int fuel;
-  int max_fuel;
-
-  bool has_moved;
-  bool has_attacked;
-  bool is_selected;
-  bool is_targeted;
-  Weapon secondary_weapon;
-  Weapon primary_weapon;
-
-  int ammo;
- 
+class Unit
+{
+    public:
+        int x;
+        int y;
+        int health; // health equals max_health at construction
+
+        Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
+        ~Unit()
+        {
+            // Assuming that the destruktion of a unit triggers events
+        }
+
+        void render(Engine* engine, int scale);
+
+        /*
+        Check if attacker is in Range to initiate combat
+        TODO: This should probably tie back into rendering the units differently
+        If a unit is selected, it should call inRange on all other enemy units on the field
+        */
+
+        bool inRange(Unit* enemy);
+
+        /*
+        The attacker will move towards the defender and thus initiate combat
+        @params Takes a reference to the defender
+
+        Will Update the health for both units
+        Attacker deals damage to the defender first
+        */
+
+        void attack(Unit* enemy);
+
+        /*
+        @params Takes the desired position of the unit and updates its values
+        This will teleport the unit, there is no smooth transition between tiles
+        */
+        void update_position(int posX, int posY);
+
+        /*
+        This function needs to be able to determine the possible movement-paths the unit can take
+        MUST take into consideration that different units behave differently on certain terrain
+        MUST show all movements possible
+        */
+        void calculate_movement();
+
+        void calc_state(int posX, int posY);
+
+        /*
+        This function will be called by an external event-handler, eventually.
+        It should start displaying standard unit information, such as UI and move_range
+        */
+        void on_left_click(SDL_Event event);
+
+    private:
+        UnitFaction faction;
+        UnitId      id;
+        UnitState   state;
+
+        int max_health; // max_health required for damage_scaling
+        int range;
+        int fuel;
+        int max_fuel;
+
+        bool   has_moved;
+        bool   has_attacked;
+        bool   is_selected;
+        bool   is_targeted;
+        Weapon secondary_weapon;
+        Weapon primary_weapon;
+
+        int ammo;
 };
 
 } // namespace advanced_wars
\ No newline at end of file
diff --git a/src/weapon.cpp b/src/weapon.cpp
index b93d09c..e324130 100644
--- a/src/weapon.cpp
+++ b/src/weapon.cpp
@@ -2,26 +2,28 @@
 
 namespace advanced_wars
 {
-    Weapon::Weapon() : name(""), damage() {}
+Weapon::Weapon() : name(""), damage() {}
 
-    Weapon::Weapon(const std::string &weaponName, const std::unordered_map<UnitId, int> &damageValues)
-        : name(weaponName), damage(damageValues) {}
+Weapon::Weapon(const std::string& weaponName, const std::unordered_map<UnitId, int>& damageValues)
+    : name(weaponName), damage(damageValues)
+{
+}
 
-    // Funktion zum Hinzufügen von Schadenswerten
-    void Weapon::addDamageValue(UnitId unitId, int value)
-    {
-        damage[unitId] = value;
-    }
+// Funktion zum Hinzufügen von Schadenswerten
+void Weapon::addDamageValue(UnitId unitId, int value)
+{
+    damage[unitId] = value;
+}
 
-    // Funktion zum Abrufen eines Schadenswertes
-    int Weapon::getDamageValue(UnitId unitId) const
+// Funktion zum Abrufen eines Schadenswertes
+int Weapon::getDamageValue(UnitId unitId) const
+{
+    auto it = damage.find(unitId);
+    if (it != damage.end())
     {
-        auto it = damage.find(unitId);
-        if (it != damage.end())
-        {
-            return it->second;
-        }
-        return 0; // oder ein Fehlerwert
+        return it->second;
     }
+    return 0; // oder ein Fehlerwert
+}
 
-}
\ No newline at end of file
+} // namespace advanced_wars
\ No newline at end of file
diff --git a/src/weapon.hpp b/src/weapon.hpp
index 2192e61..028eef1 100644
--- a/src/weapon.hpp
+++ b/src/weapon.hpp
@@ -3,27 +3,29 @@
 #include <string>
 #include <unordered_map>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 enum class UnitId;
 
-class Weapon {
-public:
-  // Konstruktoren
-  Weapon();
-  Weapon(const std::string &weaponName, const std::unordered_map<UnitId, int> &damageValues);
+class Weapon
+{
+    public:
+        // Konstruktoren
+        Weapon();
+        Weapon(const std::string& weaponName, const std::unordered_map<UnitId, int>& damageValues);
 
-  // Methode, um einen Schadenswert hinzuzufügen
-  void addDamageValue(UnitId unitId, int value);
+        // Methode, um einen Schadenswert hinzuzufügen
+        void addDamageValue(UnitId unitId, int value);
 
-  // Methode, um einen Schadenswert abzurufen
-  int getDamageValue(UnitId unitId) const;
+        // Methode, um einen Schadenswert abzurufen
+        int getDamageValue(UnitId unitId) const;
 
-  // Name der Waffe
-  std::string name;
+        // Name der Waffe
+        std::string name;
 
-  // Schadenstabelle
-  std::unordered_map<UnitId, int> damage;
+        // Schadenstabelle
+        std::unordered_map<UnitId, int> damage;
 };
 
 } // namespace advanced_wars
diff --git a/src/window.cpp b/src/window.cpp
index aa75681..926cbf7 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -1,35 +1,49 @@
 #include "window.hpp"
 #include <stdexcept>
 
-namespace advanced_wars {
-
-Window::Window(std::string title, int w, int h) {
-  /// Init width and height
-  width = w;
-  height = h;
-
-  // Generate SDL main window
-  window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED,
-                            SDL_WINDOWPOS_UNDEFINED, width, height,
-                            SDL_WINDOW_SHOWN);
-
-  if (window == nullptr) {
-    throw std::runtime_error("SDL window could not be generated: " +
-                             std::string(SDL_GetError()));
-  }
+namespace advanced_wars
+{
+
+Window::Window(std::string title, int w, int h)
+{
+    /// Init width and height
+    width = w;
+    height = h;
+
+    // Generate SDL main window
+    window = SDL_CreateWindow(
+        title.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height,
+        SDL_WINDOW_SHOWN);
+
+    if (window == nullptr)
+    {
+        throw std::runtime_error(
+            "SDL window could not be generated: " + std::string(SDL_GetError()));
+    }
 }
 
-int Window::w() { return width; }
+int Window::w()
+{
+    return width;
+}
 
-int Window::h() { return height; }
+int Window::h()
+{
+    return height;
+}
 
-SDL_Window *Window::sdl_window() { return window; }
+SDL_Window* Window::sdl_window()
+{
+    return window;
+}
 
-Window::~Window() {
-  if (window) {
-    SDL_DestroyWindow(window);
-    window = nullptr;
-  }
+Window::~Window()
+{
+    if (window)
+    {
+        SDL_DestroyWindow(window);
+        window = nullptr;
+    }
 }
 
 } // namespace advanced_wars
diff --git a/src/window.hpp b/src/window.hpp
index 9cd664d..a53586b 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -3,50 +3,52 @@
 #include <SDL.h>
 #include <string>
 
-namespace advanced_wars {
+namespace advanced_wars
+{
 
 /**
  * @brief The main window of the game
  */
-class Window {
-public:
-  /***
-   * Creates a main window with given \ref title, width \ref w and height \ref h
-   *
-   * @param title		Title of the window
-   * @param w			Width
-   * @param h			Height
-   */
-  Window(std::string title, int w, int h);
-
-  /**
-   * Forbids the creation of copies of a window
-   */
-  Window(const Window &) = delete;
-  // Window& operator=(const Window&) = delete;
-
-  /***
-   * Destructor.
-   */
-  ~Window();
-
-  /// Retruns the current width of the window
-  int w();
-
-  /// Returns the current height of the window
-  int h();
-
-  SDL_Window *sdl_window();
-
-private:
-  /// SDL main window struct
-  SDL_Window *window;
-
-  /// Window width
-  int width;
-
-  /// Window height
-  int height;
+class Window
+{
+    public:
+        /***
+         * Creates a main window with given \ref title, width \ref w and height \ref h
+         *
+         * @param title		Title of the window
+         * @param w			Width
+         * @param h			Height
+         */
+        Window(std::string title, int w, int h);
+
+        /**
+         * Forbids the creation of copies of a window
+         */
+        Window(const Window&) = delete;
+        Window& operator=(const Window&) = delete;
+
+        /***
+         * Destructor.
+         */
+        ~Window();
+
+        /// Retruns the current width of the window
+        int w();
+
+        /// Returns the current height of the window
+        int h();
+
+        SDL_Window* sdl_window();
+
+    private:
+        /// SDL main window struct
+        SDL_Window* window;
+
+        /// Window width
+        int width;
+
+        /// Window height
+        int height;
 };
 
 } // namespace advanced_wars
-- 
GitLab