diff --git a/Linked-List-Snake/Linked-List-Snake.vcxproj b/Linked-List-Snake/Linked-List-Snake.vcxproj
index 99de33c33..3d7d11dc1 100644
--- a/Linked-List-Snake/Linked-List-Snake.vcxproj
+++ b/Linked-List-Snake/Linked-List-Snake.vcxproj
@@ -134,9 +134,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -148,14 +160,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -168,6 +198,7 @@
+
diff --git a/Linked-List-Snake/Linked-List-Snake.vcxproj.filters b/Linked-List-Snake/Linked-List-Snake.vcxproj.filters
index 02d87bf38..d472163d2 100644
--- a/Linked-List-Snake/Linked-List-Snake.vcxproj.filters
+++ b/Linked-List-Snake/Linked-List-Snake.vcxproj.filters
@@ -66,6 +66,48 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
@@ -119,5 +161,62 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Element/ElementData.h b/Linked-List-Snake/include/Element/ElementData.h
new file mode 100644
index 000000000..da32c7314
--- /dev/null
+++ b/Linked-List-Snake/include/Element/ElementData.h
@@ -0,0 +1,22 @@
+#pragma once
+#include
+
+namespace Element
+{
+ enum class ElementType
+ {
+ OBSTACLE,
+ };
+
+ struct ElementData
+ {
+ ElementData(ElementType type, sf::Vector2i pos)
+ {
+ element_type = type;
+ position = pos;
+ }
+
+ ElementType element_type;
+ sf::Vector2i position;
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Element/ElementService.h b/Linked-List-Snake/include/Element/ElementService.h
new file mode 100644
index 000000000..66c038208
--- /dev/null
+++ b/Linked-List-Snake/include/Element/ElementService.h
@@ -0,0 +1,27 @@
+#pragma once
+#include
+#include
+
+namespace Element
+{
+ class Obstacle;
+ struct ElementData;
+
+ class ElementService
+ {
+ private:
+ std::vector obstacle_list;
+
+ void spawnObstacle(sf::Vector2i position, float cell_width, float cell_height);
+
+ public:
+ ElementService();
+ ~ElementService();
+
+ void initialize();
+ void update();
+ void render();
+
+ const void spawnElements(std::vector& element_data_list, float cell_width, float cell_height);
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Element/Obstacle.h b/Linked-List-Snake/include/Element/Obstacle.h
new file mode 100644
index 000000000..89801778f
--- /dev/null
+++ b/Linked-List-Snake/include/Element/Obstacle.h
@@ -0,0 +1,29 @@
+#pragma once
+#pragma once
+#include
+#include "UI/UIElement/ImageView.h"
+
+namespace Element
+{
+ class Obstacle
+ {
+ private:
+ UI::UIElement::ImageView* obstacle_image;
+
+ sf::Vector2i grid_position;
+
+ float cell_width;
+ float cell_height;
+
+ void initializeObstacleImage();
+ sf::Vector2f getObstacleImagePosition();
+
+ public:
+ Obstacle();
+ ~Obstacle();
+
+ void initialize(sf::Vector2i grid_pos, float width, float height);
+ void update();
+ void render();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Food/FoodItem.h b/Linked-List-Snake/include/Food/FoodItem.h
new file mode 100644
index 000000000..2a23ee13f
--- /dev/null
+++ b/Linked-List-Snake/include/Food/FoodItem.h
@@ -0,0 +1,37 @@
+#pragma once
+#include
+#include "UI/UIElement/ImageView.h"
+
+namespace Food
+{
+ enum class FoodType;
+
+ class FoodItem
+ {
+ private:
+ UI::UIElement::ImageView* food_image;
+
+ sf::Vector2i grid_position;
+
+ float cell_width;
+ float cell_height;
+
+ FoodType food_type;
+
+ void initializeFoodImage();
+ sf::String getFoodTexturePath();
+ sf::Vector2f getFoodImagePosition();
+
+ public:
+ static const int number_of_foods = 8;
+
+ FoodItem();
+ ~FoodItem();
+
+ void initialize(sf::Vector2i grid_pos, float width, float height, FoodType type);
+ void update();
+ void render();
+
+ FoodType getFoodType();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Food/FoodService.h b/Linked-List-Snake/include/Food/FoodService.h
new file mode 100644
index 000000000..b6e4225be
--- /dev/null
+++ b/Linked-List-Snake/include/Food/FoodService.h
@@ -0,0 +1,61 @@
+#pragma once
+#include
+#include
+#include
+
+namespace Food
+{
+ enum class FoodType;
+ class FoodItem;
+
+ enum FoodSpawningStatus
+ {
+ ACTIVE,
+ IN_ACTIVE,
+ };
+
+ class FoodService
+ {
+ private:
+ const float spawn_duration = 4.f;
+
+ float elapsed_duration;
+
+ FoodSpawningStatus current_spawning_status;
+ FoodItem* current_food_item;
+
+ float cell_width;
+ float cell_height;
+
+ // To generate random values.
+ std::default_random_engine random_engine;
+
+ // To give random seed to generator.
+ std::random_device random_device;
+
+ FoodItem* createFood(sf::Vector2i position, FoodType type);
+ void spawnFood();
+
+ sf::Vector2i getValidSpawnPosition();
+ sf::Vector2i getRandomPosition();
+ FoodType getRandomFoodType();
+
+ bool isValidPosition(std::vector position_data, sf::Vector2i food_position);
+
+ void destroyFood();
+ void updateElapsedDuration();
+ void handleFoodSpawning();
+ void reset();
+
+ public:
+ FoodService();
+ ~FoodService();
+
+ void initialize();
+ void update();
+ void render();
+
+ void startFoodSpawning();
+ void stopFoodSpawning();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Food/FoodType.h b/Linked-List-Snake/include/Food/FoodType.h
new file mode 100644
index 000000000..f6f555ccc
--- /dev/null
+++ b/Linked-List-Snake/include/Food/FoodType.h
@@ -0,0 +1,15 @@
+#pragma once
+namespace Food
+{
+ enum class FoodType
+ {
+ APPLE,
+ MANGO,
+ ORANGE,
+ PIZZA,
+ BURGER,
+ CHEESE,
+ POISION,
+ ALCOHOL,
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Global/ServiceLocator.h b/Linked-List-Snake/include/Global/ServiceLocator.h
index b73213ab9..b21452f60 100644
--- a/Linked-List-Snake/include/Global/ServiceLocator.h
+++ b/Linked-List-Snake/include/Global/ServiceLocator.h
@@ -12,6 +12,7 @@ namespace Global
private:
Event::EventService* event_service;
Graphics::GraphicService* graphic_service;
+ //Level::LevelService* level_service;
Sound::SoundService* sound_service;
UI::UIService* ui_service;
Time::TimeService* time_service;
diff --git a/Linked-List-Snake/include/Level/LevelController.h b/Linked-List-Snake/include/Level/LevelController.h
new file mode 100644
index 000000000..a6668149b
--- /dev/null
+++ b/Linked-List-Snake/include/Level/LevelController.h
@@ -0,0 +1,27 @@
+#pragma once
+#pragma once
+#include
+#include "LevelModel.h"
+
+namespace Level
+{
+ class LevelView;
+
+ class LevelController
+ {
+ private:
+ LevelModel* level_model;
+ LevelView* level_view;
+
+ public:
+ LevelController();
+ ~LevelController();
+
+ void initialize();
+ void update();
+ void render();
+
+ float getCellWidth();
+ float getCellHeight();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Level/LevelData.h b/Linked-List-Snake/include/Level/LevelData.h
new file mode 100644
index 000000000..f7fbab5b8
--- /dev/null
+++ b/Linked-List-Snake/include/Level/LevelData.h
@@ -0,0 +1,18 @@
+//#pragma once
+//#include "Level/LevelService.h"
+//#include "Element/ElementData.h"
+//
+//namespace Level
+//{
+// struct LevelData
+// {
+// LevelData(LevelNumber ind, std::vector* data_list)
+// {
+// level_index = ind;
+// element_data_list = data_list;
+// }
+//
+// LevelNumber level_index;
+// std::vector* element_data_list;
+// };
+//}
diff --git a/Linked-List-Snake/include/Level/LevelModel.h b/Linked-List-Snake/include/Level/LevelModel.h
new file mode 100644
index 000000000..de9ff0f59
--- /dev/null
+++ b/Linked-List-Snake/include/Level/LevelModel.h
@@ -0,0 +1,30 @@
+#pragma once
+#include
+#include "Level/LevelData.h"
+#include
+
+namespace Level
+{
+ class LevelModel
+ {
+ private:
+ //std::vector level_configurations;
+
+ float cell_width;
+ float cell_height;
+
+
+ public:
+ static const int number_of_rows = 28;
+ static const int number_of_columns = 50;
+
+ LevelModel();
+ ~LevelModel();
+
+ void initialize(int width, int height);
+
+ float getCellWidth();
+ float getCellHeight();
+
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Level/LevelView.h b/Linked-List-Snake/include/Level/LevelView.h
new file mode 100644
index 000000000..d26e6184d
--- /dev/null
+++ b/Linked-List-Snake/include/Level/LevelView.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include
+#include "UI/UIElement/RectangleShapeView.h"
+namespace Level
+{
+ class LevelView
+ {
+ private:
+ const sf::Color background_color = sf::Color(180, 200, 160);
+ const sf::Color border_color = sf::Color::Black;
+
+ UI::UIElement::RectangleShapeView* background_rectangle;
+ UI::UIElement::RectangleShapeView* border_rectangle;
+
+ float grid_width;
+ float grid_height;
+
+ void createViews();
+ void initializeBackground();
+ void initializeBorder();
+ void calculateGridExtents();
+ void destroy();
+
+ public:
+ static const int border_thickness = 10;
+
+ static const int border_offset_left = 40;
+ static const int border_offset_top = 100; // Increased top offset
+ static const int border_offset_bottom = 40;
+
+ LevelView();
+ ~LevelView();
+
+ void initialize();
+ void update();
+ void render();
+
+ float getGridWidth();
+ float getGridHeight();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/LinkedList/SingleLinkedList.h b/Linked-List-Snake/include/LinkedList/SingleLinkedList.h
new file mode 100644
index 000000000..fabafb6bb
--- /dev/null
+++ b/Linked-List-Snake/include/LinkedList/SingleLinkedList.h
@@ -0,0 +1,31 @@
+#pragma once
+#include
+#include "Player/Node.h"
+#include "Player/Direction.h"
+
+namespace LinkedList
+{
+ class SingleLinkedList
+ {
+ private:
+ Node* head_node;
+
+ float node_width;
+ float node_height;
+
+ sf::Vector2i default_position;
+ Direction default_direction;
+
+ Node* createNode();
+ sf::Vector2i SingleLinkedList::getNewNodePosition(Node* reference_node, Operation operation) { }
+
+ public:
+ SingleLinkedList();
+ ~SingleLinkedList();
+
+ void initialize(float width, float height, sf::Vector2i position, Direction direction);
+ void render();
+ };
+
+
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Player/BodyPart.h b/Linked-List-Snake/include/Player/BodyPart.h
new file mode 100644
index 000000000..e39b94283
--- /dev/null
+++ b/Linked-List-Snake/include/Player/BodyPart.h
@@ -0,0 +1,50 @@
+#pragma once
+#include
+#include "UI/UIElement/ImageView.h"
+#include "Direction.h"
+
+namespace Player
+{
+ class BodyPart
+ {
+ protected:
+ UI::UIElement::ImageView* bodypart_image;
+
+ sf::Vector2i grid_position;
+ Direction direction;
+ Direction previous_direction;
+
+ float bodypart_width;
+ float bodypart_height;
+
+ void createBodyPartImage();
+ void initializeBodyPartImage();
+ sf::Vector2f getBodyPartScreenPosition();
+ float getRotationAngle();
+
+ sf::Vector2i getNextPositionUp();
+ sf::Vector2i getNextPositionDown();
+ sf::Vector2i getNextPositionLeft();
+ sf::Vector2i getNextPositionRight();
+
+ void destroy();
+
+ public:
+ BodyPart();
+ ~BodyPart();
+
+ void initialize(float width, float height, sf::Vector2i pos, Direction dir);
+ void updatePosition();
+ void render();
+
+ Direction getDirection();
+ Direction getPreviousDirection();
+ void setDirection(Direction direction);
+ sf::Vector2i getPosition();
+ void setPosition(sf::Vector2i position);
+
+ sf::Vector2i getNextPosition();
+ sf::Vector2i getPrevPosition();
+
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Player/Direction.h b/Linked-List-Snake/include/Player/Direction.h
new file mode 100644
index 000000000..76a647353
--- /dev/null
+++ b/Linked-List-Snake/include/Player/Direction.h
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace Player
+{
+ enum class Direction
+ {
+ UP,
+ DOWN,
+ LEFT,
+ RIGHT,
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Player/Node.h b/Linked-List-Snake/include/Player/Node.h
new file mode 100644
index 000000000..12391d86a
--- /dev/null
+++ b/Linked-List-Snake/include/Player/Node.h
@@ -0,0 +1,13 @@
+#pragma once
+#include "Player/BodyPart.h"
+
+namespace LinkedListLib
+{
+ //using namespace Player;
+
+ struct Node
+ {
+ BodyPart body_part;
+ Node* next = nullptr;
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Player/PlayerService.h b/Linked-List-Snake/include/Player/PlayerService.h
new file mode 100644
index 000000000..9603bccad
--- /dev/null
+++ b/Linked-List-Snake/include/Player/PlayerService.h
@@ -0,0 +1,25 @@
+#pragma once
+
+namespace Player
+{
+ class SnakeController;
+
+ class PlayerService
+ {
+ private:
+ SnakeController* snake_controller;
+
+ void createController();
+ void destroy();
+
+ public:
+ PlayerService();
+ ~PlayerService();
+
+ void initialize();
+ void update();
+ void render();
+
+ void spawnPlayer();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/Player/SnakeController.h b/Linked-List-Snake/include/Player/SnakeController.h
new file mode 100644
index 000000000..c70ce7cf1
--- /dev/null
+++ b/Linked-List-Snake/include/Player/SnakeController.h
@@ -0,0 +1,51 @@
+#pragma once
+#include
+#include "Direction.h"
+namespace Player
+{
+ enum class SnakeState
+ {
+ ALIVE,
+ DEAD,
+ };
+
+ enum class InputState
+ {
+ WAITING,
+ PROCESSING
+ };
+
+ class SnakeController
+ {
+ private:
+ const int initial_snake_length = 10;
+
+ const sf::Vector2i default_position = sf::Vector2i(25, 13);
+ const Direction default_direction = Direction::RIGHT;
+
+
+ SnakeState current_snake_state;
+ Direction current_snake_direction;
+
+ void processPlayerInput();
+ void updateSnakeDirection();
+ void moveSnake();
+ void processSnakeCollision();
+ void handleRestart();
+ void reset();
+ void destroy();
+
+ public:
+ SnakeController();
+ ~SnakeController();
+
+ void initialize();
+ void update();
+ void render();
+
+ void spawnSnake();
+ void respawnSnake();
+ void setSnakeState(SnakeState state);
+ SnakeState getSnakeState();
+ };
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/UI/GameplayUI/GameplayUIController.h b/Linked-List-Snake/include/UI/GameplayUI/GameplayUIController.h
new file mode 100644
index 000000000..fec7e9c3a
--- /dev/null
+++ b/Linked-List-Snake/include/UI/GameplayUI/GameplayUIController.h
@@ -0,0 +1,55 @@
+#pragma once
+#include "UI/Interface/IUIController.h"
+#include "UI/UIElement/TextView.h"
+
+namespace UI
+{
+ namespace GameplayUI
+ {
+ class GameplayUIController : public Interface::IUIController
+ {
+ private:
+ // Constants:
+ const float font_size = 60.f;
+
+ const float text_y_position = 7.f;
+ const float level_number_text_x_position = 65.f;
+ const float score_text_x_position = 800.f;
+
+ // Constants: Operations and Time Complexities
+ const float operations_font_size = 36.f;
+ const float operations_text_x_position = 1330.f;
+ const float operations_text_y_position = 10.f;
+ const float time_complexity_text_x_position = 1330.f;
+ const float time_complexity_text_y_position = 45.f;
+
+ UI::UIElement::TextView* level_number_text;
+ UI::UIElement::TextView* score_text;
+ UI::UIElement::TextView* time_complexity_text;
+ UI::UIElement::TextView* operation_text;
+
+ void createTexts();
+ void initializeTexts();
+ void initializeLevelNumberText();
+ void initializeScoreText();
+ void initializeTimeComplexityText();
+ void initializeOperationText();
+
+ void updateLevelNumberText();
+ void updateScoreText();
+ void updateTimeComplexityText();
+ void updateOperationText();
+
+ void destroy();
+
+ public:
+ GameplayUIController();
+ ~GameplayUIController();
+
+ void initialize() override;
+ void update() override;
+ void render() override;
+ void show() override;
+ };
+ }
+}
diff --git a/Linked-List-Snake/include/UI/LevelSelection/LevelSelectionUIController.h b/Linked-List-Snake/include/UI/LevelSelection/LevelSelectionUIController.h
new file mode 100644
index 000000000..324dd4b4f
--- /dev/null
+++ b/Linked-List-Snake/include/UI/LevelSelection/LevelSelectionUIController.h
@@ -0,0 +1,53 @@
+#pragma once
+#include
+#include "UI/Interface/IUIController.h"
+#include "UI/UIElement/ButtonView.h"
+#include "UI/UIElement/ImageView.h"
+
+namespace UI
+{
+ namespace LevelSelection
+ {
+ class LevelSelectionUIController : public Interface::IUIController
+ {
+ private:
+ // Constants:
+ const float button_width = 400.f;
+ const float button_height = 140.f;
+
+ const float level_one_button_y_position = 500.f;
+ const float level_two_button_y_position = 700.f;
+ const float menu_button_y_position = 900.f;
+
+ const float background_alpha = 85.f;
+
+ UI::UIElement::ImageView* background_image;
+
+ UI::UIElement::ButtonView* level_one_button;
+ UI::UIElement::ButtonView* level_two_button;
+ UI::UIElement::ButtonView* menu_button;
+
+ void createImage();
+ void createButtons();
+ void initializeBackgroundImage();
+ void initializeButtons();
+ void registerButtonCallback();
+ float calculateLeftOffsetForButton();
+
+ void levelOneButtonCallback();
+ void levelTwoButtonCallback();
+ void menuButtonCallback();
+
+ void destroy();
+
+ public:
+ LevelSelectionUIController();
+ ~LevelSelectionUIController();
+
+ void initialize() override;
+ void update() override;
+ void render() override;
+ void show() override;
+ };
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/UI/UIElement/RectangleShapeView.h b/Linked-List-Snake/include/UI/UIElement/RectangleShapeView.h
new file mode 100644
index 000000000..dc25fff18
--- /dev/null
+++ b/Linked-List-Snake/include/UI/UIElement/RectangleShapeView.h
@@ -0,0 +1,28 @@
+#pragma once
+#include "UIView.h"
+
+namespace UI
+{
+ namespace UIElement
+ {
+ class RectangleShapeView : public UIView
+ {
+ protected:
+ sf::RectangleShape rectangle_shape;
+
+ public:
+ RectangleShapeView();
+ virtual ~RectangleShapeView();
+
+ virtual void initialize(sf::Vector2f rectangle_size, sf::Vector2f rectangle_position, int outline_thikness = 0, sf::Color fill_color = sf::Color::Transparent, sf::Color outline_color = sf::Color::Transparent);
+ virtual void update() override;
+ virtual void render() override;
+
+ virtual void setSize(sf::Vector2f rectangle_size);
+ virtual void setPosition(sf::Vector2f rectangle_position);
+ virtual void setFillColor(sf::Color fill_color);
+ virtual void setOutlineColor(sf::Color outline_color);
+ virtual void setOutlineThickness(int outline_thikness);
+ };
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/include/UI/UIService.h b/Linked-List-Snake/include/UI/UIService.h
index 756cb730e..3c2c97cc0 100644
--- a/Linked-List-Snake/include/UI/UIService.h
+++ b/Linked-List-Snake/include/UI/UIService.h
@@ -14,6 +14,7 @@ namespace UI
MainMenu::MainMenuUIController* main_menu_controller;
Instructions::InstructionsScreenUIController* instructions_screen_ui_controller;
Credits::CreditsScreenUIController* credits_screen_ui_controller;
+ LevelSelection::LevelSelectionUIController* level_selection_ui_controller;
void createControllers();
diff --git a/Linked-List-Snake/sfml/include/SFML/Config.hpp b/Linked-List-Snake/sfml/include/SFML/Config.hpp
index f4ea4ef3e..3093a7a51 100644
--- a/Linked-List-Snake/sfml/include/SFML/Config.hpp
+++ b/Linked-List-Snake/sfml/include/SFML/Config.hpp
@@ -31,7 +31,7 @@
////////////////////////////////////////////////////////////
#define SFML_VERSION_MAJOR 2
#define SFML_VERSION_MINOR 6
-#define SFML_VERSION_PATCH 0
+#define SFML_VERSION_PATCH 1
////////////////////////////////////////////////////////////
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s-d.pdb
new file mode 100644
index 000000000..bbd97a4b6
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s.pdb
new file mode 100644
index 000000000..bbd97a4b6
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-audio-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-audio.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-audio.pdb
new file mode 100644
index 000000000..e0cd93576
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-audio.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s-d.pdb
new file mode 100644
index 000000000..d187d9728
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s.pdb
new file mode 100644
index 000000000..d187d9728
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-graphics.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics.pdb
new file mode 100644
index 000000000..310a084ae
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-graphics.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-main-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-main-d.pdb
new file mode 100644
index 000000000..432660dd8
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-main-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-main-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-main-s.pdb
new file mode 100644
index 000000000..432660dd8
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-main-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-network-s-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-network-s-d.pdb
new file mode 100644
index 000000000..446f1fb80
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-network-s-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-network-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-network-s.pdb
new file mode 100644
index 000000000..446f1fb80
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-network-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-network.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-network.pdb
new file mode 100644
index 000000000..fa073311f
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-network.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-system-s-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-system-s-d.pdb
new file mode 100644
index 000000000..aa448263a
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-system-s-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-system-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-system-s.pdb
new file mode 100644
index 000000000..aa448263a
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-system-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-system.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-system.pdb
new file mode 100644
index 000000000..ea487f4f0
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-system.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-window-s-d.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-window-s-d.pdb
new file mode 100644
index 000000000..98a4c966e
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-window-s-d.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-window-s.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-window-s.pdb
new file mode 100644
index 000000000..98a4c966e
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-window-s.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/Debug/sfml-window.pdb b/Linked-List-Snake/sfml/lib/Debug/sfml-window.pdb
new file mode 100644
index 000000000..1e2442bd4
Binary files /dev/null and b/Linked-List-Snake/sfml/lib/Debug/sfml-window.pdb differ
diff --git a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfig.cmake b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfig.cmake
index f8b915b60..f28497b6c 100644
--- a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfig.cmake
+++ b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfig.cmake
@@ -144,5 +144,5 @@ if (NOT SFML_FOUND)
endif()
if (SFML_FOUND AND NOT SFML_FIND_QUIETLY)
- message(STATUS "Found SFML 2.6.0 in ${CMAKE_CURRENT_LIST_DIR}")
+ message(STATUS "Found SFML 2.6.1 in ${CMAKE_CURRENT_LIST_DIR}")
endif()
diff --git a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfigVersion.cmake b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfigVersion.cmake
index b2208ca9f..25db87605 100644
--- a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfigVersion.cmake
+++ b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLConfigVersion.cmake
@@ -9,19 +9,19 @@
# The variable CVF_VERSION must be set before calling configure_file().
-set(PACKAGE_VERSION "2.6.0")
+set(PACKAGE_VERSION "2.6.1")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
- if("2.6.0" MATCHES "^([0-9]+)\\.")
+ if("2.6.1" MATCHES "^([0-9]+)\\.")
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
else()
- set(CVF_VERSION_MAJOR "2.6.0")
+ set(CVF_VERSION_MAJOR "2.6.1")
endif()
if(PACKAGE_FIND_VERSION_RANGE)
diff --git a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLSharedTargets.cmake b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLSharedTargets.cmake
index 1c1c3c062..852e1a8d4 100644
--- a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLSharedTargets.cmake
+++ b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLSharedTargets.cmake
@@ -7,7 +7,7 @@ if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.3...3.24)
+cmake_policy(VERSION 2.8.3...3.25)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
diff --git a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLStaticTargets.cmake b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLStaticTargets.cmake
index 7257de655..419bb1b85 100644
--- a/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLStaticTargets.cmake
+++ b/Linked-List-Snake/sfml/lib/cmake/SFML/SFMLStaticTargets.cmake
@@ -7,7 +7,7 @@ if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
-cmake_policy(VERSION 2.8.3...3.24)
+cmake_policy(VERSION 2.8.3...3.25)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
diff --git a/Linked-List-Snake/source/Element/ElementService.cpp b/Linked-List-Snake/source/Element/ElementService.cpp
new file mode 100644
index 000000000..feb939196
--- /dev/null
+++ b/Linked-List-Snake/source/Element/ElementService.cpp
@@ -0,0 +1,64 @@
+#include "Element/ElementService.h"
+#include "Level/LevelModel.h"
+#include "Global/ServiceLocator.h"
+#include "Level/LevelController.h"
+#include "Element/Obstacle.h"
+#include "Level/LevelModel.h"
+
+namespace Element
+{
+ ElementService::ElementService() = default;
+
+ ElementService::~ElementService() = default;
+
+ void ElementService::initialize() { }
+
+ void ElementService::update()
+ {
+ for (int i = 0; i < obstacle_list.size(); i++)
+ {
+ obstacle_list[i]->update();
+ }
+ }
+
+ void ElementService::render()
+ {
+ for (int i = 0; i < obstacle_list.size(); i++)
+ {
+ obstacle_list[i]->render();
+ }
+ }
+
+ const void ElementService::spawnElements(std::vector& element_data_list, float cell_width, float cell_height)
+ {
+ for (int i = 0; i < element_data_list.size(); i++)
+ {
+ switch (element_data_list[i].element_type)
+ {
+ case::Element::ElementType::OBSTACLE:
+ spawnObstacle(element_data_list[i].position, cell_width, cell_height);
+ break;
+ }
+ }
+ }
+
+ void ElementService::spawnObstacle(sf::Vector2i position, float cell_width, float cell_height)
+ {
+ Obstacle* obstacle = new Obstacle();
+
+ obstacle->initialize(position, cell_width, cell_height);
+ obstacle_list.push_back(obstacle);
+ }
+
+ std::vector ElementService::getElementsPositionList()
+ {
+ std::vector elements_position_list;
+
+ for (int i = 0; i < obstacle_list.size(); i++)
+ {
+ elements_position_list.push_back(obstacle_list[i]->getObstaclePosition());
+ }
+
+ return elements_position_list;
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Element/Obstacle.cpp b/Linked-List-Snake/source/Element/Obstacle.cpp
new file mode 100644
index 000000000..77f90036d
--- /dev/null
+++ b/Linked-List-Snake/source/Element/Obstacle.cpp
@@ -0,0 +1,59 @@
+#include "Element/Obstacle.h"
+#include "Global/ServiceLocator.h"
+#include "Level/LevelView.h"
+#include "Global/Config.h"
+
+namespace Element
+{
+ using namespace Global;
+ using namespace Level;
+ using namespace UI::UIElement;
+
+ Obstacle::Obstacle()
+ {
+ obstacle_image = new ImageView();
+ }
+
+ Obstacle::~Obstacle()
+ {
+ delete (obstacle_image);
+ }
+
+ void Obstacle::initialize(sf::Vector2i grid_pos, float width, float height)
+ {
+ grid_position = grid_pos;
+ cell_width = width;
+ cell_height = height;
+
+ initializeObstacleImage();
+ }
+
+ void Obstacle::initializeObstacleImage()
+ {
+ sf::Vector2f screen_position = getObstacleImagePosition();
+ obstacle_image->initialize(Config::obstacle_texture_path, cell_width, cell_height, screen_position);
+
+ obstacle_image->show();
+ }
+
+ void Obstacle::update()
+ {
+ obstacle_image->update();
+ }
+
+ void Obstacle::render()
+ {
+ obstacle_image->render();
+ }
+ sf::Vector2i Obstacle::getObstaclePosition()
+ {
+ return grid_position;
+ }
+ sf::Vector2f Obstacle::getObstacleImagePosition()
+ {
+ float screen_position_x = LevelView::border_offset_left + (cell_width * grid_position.x);
+ float screen_position_y = LevelView::border_offset_top + (cell_height * grid_position.y);
+
+ return sf::Vector2f(screen_position_x, screen_position_y);
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Food/FoodItem.cpp b/Linked-List-Snake/source/Food/FoodItem.cpp
new file mode 100644
index 000000000..209c04096
--- /dev/null
+++ b/Linked-List-Snake/source/Food/FoodItem.cpp
@@ -0,0 +1,94 @@
+#include "Food/FoodItem.h"
+#include "Global/ServiceLocator.h"
+#include "Level/LevelView.h"
+#include "Global/Config.h"
+#include "Food/FoodType.h"
+
+namespace Food
+{
+ using namespace Global;
+ using namespace Level;
+ using namespace UI::UIElement;
+
+ FoodItem::FoodItem()
+ {
+ food_image = new ImageView();
+ }
+
+ FoodItem::~FoodItem()
+ {
+ delete (food_image);
+ }
+
+ void FoodItem::initialize(sf::Vector2i grid_pos, float width, float height, FoodType type)
+ {
+ grid_position = grid_pos;
+ cell_width = width;
+ cell_height = height;
+ food_type = type;
+
+ initializeFoodImage();
+ }
+
+ void FoodItem::initializeFoodImage()
+ {
+ sf::Vector2f screen_position = getFoodImagePosition();
+ sf::String food_texture_path = getFoodTexturePath();
+
+ food_image->initialize(food_texture_path, cell_width, cell_height, screen_position);
+ food_image->show();
+ }
+
+ sf::String FoodItem::getFoodTexturePath()
+ {
+ switch (food_type)
+ {
+ case Food::FoodType::APPLE:
+ return Config::apple_texture_path;
+
+ case Food::FoodType::MANGO:
+ return Config::mango_texture_path;
+
+ case Food::FoodType::ORANGE:
+ return Config::orange_texture_path;
+
+ case Food::FoodType::PIZZA:
+ return Config::pizza_texture_path;
+
+ case Food::FoodType::BURGER:
+ return Config::burger_texture_path;
+
+ case Food::FoodType::CHEESE:
+ return Config::cheese_texture_path;
+
+ case Food::FoodType::POISION:
+ return Config::poision_texture_path;
+
+ case Food::FoodType::ALCOHOL:
+ return Config::alcohol_texture_path;
+ }
+ }
+
+ void FoodItem::update()
+ {
+ food_image->update();
+ }
+
+ void FoodItem::render()
+ {
+ food_image->render();
+ }
+
+ FoodType FoodItem::getFoodType()
+ {
+ return food_type;
+ }
+
+ sf::Vector2f FoodItem::getFoodImagePosition()
+ {
+ float screen_position_x = LevelView::border_offset_left + (cell_width * grid_position.x);
+ float screen_position_y = LevelView::border_offset_top + (cell_height * grid_position.y);
+
+ return sf::Vector2f(screen_position_x, screen_position_y);
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Food/FoodService.cpp b/Linked-List-Snake/source/Food/FoodService.cpp
new file mode 100644
index 000000000..c5a7b12ea
--- /dev/null
+++ b/Linked-List-Snake/source/Food/FoodService.cpp
@@ -0,0 +1,136 @@
+#include "Food/FoodService.h"
+#include "Global/ServiceLocator.h"
+#include "Food/FoodItem.h"
+#include "Level/LevelModel.h"
+#include "Player/PlayerService.h"
+
+namespace Food
+{
+ using namespace Time;
+ using namespace Global;
+ using namespace Level;
+ using namespace Player;
+
+ FoodService::FoodService() : random_engine(random_device())
+ {
+ current_food_item = nullptr;
+ }
+
+ FoodService::~FoodService()
+ {
+ destroyFood();
+ }
+
+ void FoodService::initialize()
+ {
+ elapsed_duration = spawn_duration;
+ }
+
+ void FoodService::update()
+ {
+ if (current_spawning_status == FoodSpawningStatus::ACTIVE)
+ {
+ updateElapsedDuration();
+ handleFoodSpawning();
+ }
+
+ if (current_food_item) current_food_item->update();
+ }
+
+ void FoodService::render()
+ {
+ if (current_food_item) current_food_item->render();
+ }
+
+ void FoodService::startFoodSpawning()
+ {
+ current_spawning_status = FoodSpawningStatus::ACTIVE;
+
+ cell_width = ServiceLocator::getInstance()->getLevelService()->getCellWidth();
+ cell_height = ServiceLocator::getInstance()->getLevelService()->getCellHeight();
+ }
+
+ void FoodService::stopFoodSpawning()
+ {
+ current_spawning_status = FoodSpawningStatus::IN_ACTIVE;
+ destroyFood();
+ reset();
+ }
+
+ FoodItem* FoodService::createFood(sf::Vector2i position, FoodType type)
+ {
+ FoodItem* food = new FoodItem();
+ food->initialize(position, cell_width, cell_height, type);
+ return food;
+ }
+
+ void FoodService::spawnFood()
+ {
+ current_food_item = createFood(getValidSpawnPosition(), getRandomFoodType());
+ }
+
+ sf::Vector2i FoodService::getValidSpawnPosition()
+ {
+ std::vector player_position_data = ServiceLocator::getInstance()->getPlayerService()->getCurrentSnakePositionList();
+ std::vector elements_position_data = ServiceLocator::getInstance()->getElementService()->getElementsPositionList();
+ sf::Vector2i spawn_position;
+
+ do spawn_position = getRandomPosition();
+ while (!isValidPosition(player_position_data, spawn_position) || !isValidPosition(elements_position_data, spawn_position));
+
+ return spawn_position;
+ }
+
+ sf::Vector2i FoodService::getRandomPosition()
+ {
+ // Co-ordinate distribution i.e. selecting random position for food.
+ std::uniform_int_distribution x_distribution(0, LevelModel::number_of_columns - 1);
+ std::uniform_int_distribution y_distribution(0, LevelModel::number_of_rows - 1);
+
+ int x_position = static_cast(x_distribution(random_engine));
+ int y_position = static_cast(y_distribution(random_engine));
+
+ return sf::Vector2i(x_position, y_position);
+ }
+
+ FoodType FoodService::getRandomFoodType()
+ {
+ std::uniform_int_distribution distribution(0, FoodItem::number_of_foods - 1);
+
+ return static_cast(distribution(random_engine));
+ }
+
+ bool FoodService::isValidPosition(std::vector position_data, sf::Vector2i food_position)
+ {
+ for (int i = 0; i < position_data.size(); i++)
+ {
+ if (food_position == position_data[i]) return false;
+ }
+ return true;
+ }
+
+ void FoodService::destroyFood()
+ {
+ if (current_food_item) delete(current_food_item);
+ }
+
+ void FoodService::updateElapsedDuration()
+ {
+ elapsed_duration += ServiceLocator::getInstance()->getTimeService()->getDeltaTime();
+ }
+
+ void FoodService::handleFoodSpawning()
+ {
+ if (elapsed_duration >= spawn_duration)
+ {
+ destroyFood();
+ reset();
+ spawnFood();
+ }
+ }
+
+ void FoodService::reset()
+ {
+ elapsed_duration = 0.f;
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Global/ServiceLocator.cpp b/Linked-List-Snake/source/Global/ServiceLocator.cpp
index 84c99f938..370d1f09f 100644
--- a/Linked-List-Snake/source/Global/ServiceLocator.cpp
+++ b/Linked-List-Snake/source/Global/ServiceLocator.cpp
@@ -7,7 +7,7 @@ namespace Global
using namespace Sound;
using namespace UI;
using namespace Time;
-
+ //using namespace Level;
ServiceLocator::ServiceLocator()
{
graphic_service = nullptr;
diff --git a/Linked-List-Snake/source/Level/LevelController.cpp b/Linked-List-Snake/source/Level/LevelController.cpp
new file mode 100644
index 000000000..a65678e42
--- /dev/null
+++ b/Linked-List-Snake/source/Level/LevelController.cpp
@@ -0,0 +1,44 @@
+#include "Level/LevelController.h"
+#include "Level/LevelModel.h"
+#include "Level/LevelView.h"
+
+namespace Level
+{
+ LevelController::LevelController()
+ {
+ level_model = new LevelModel();
+ level_view = new LevelView();
+ }
+
+ LevelController::~LevelController()
+ {
+ delete level_model;
+ delete level_view;
+ }
+
+ void LevelController::initialize()
+ {
+ level_view->initialize();
+ level_model->initialize(level_view->getGridWidth(), level_view->getGridHeight());
+ }
+
+ void LevelController::update()
+ {
+ level_view->update();
+ }
+
+ void LevelController::render()
+ {
+ level_view->render();
+ }
+
+ float LevelController::getCellWidth()
+ {
+ return level_model->getCellWidth();
+ }
+
+ float LevelController::getCellHeight()
+ {
+ return level_model->getCellHeight();
+ }
+}
diff --git a/Linked-List-Snake/source/Level/LevelModel.cpp b/Linked-List-Snake/source/Level/LevelModel.cpp
new file mode 100644
index 000000000..ae3b6e809
--- /dev/null
+++ b/Linked-List-Snake/source/Level/LevelModel.cpp
@@ -0,0 +1,24 @@
+#include "Level/LevelModel.h"
+
+namespace Level
+{
+ LevelModel::LevelModel() = default;
+
+ LevelModel::~LevelModel() = default;
+
+ void LevelModel::initialize(int width, int height)
+ {
+ cell_width = width / number_of_columns;
+ cell_height = height / number_of_rows;
+ }
+
+ float LevelModel::getCellWidth()
+ {
+ return cell_width;
+ }
+
+ float LevelModel::getCellHeight()
+ {
+ return cell_height;
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Level/LevelView.cpp b/Linked-List-Snake/source/Level/LevelView.cpp
new file mode 100644
index 000000000..3c3e86618
--- /dev/null
+++ b/Linked-List-Snake/source/Level/LevelView.cpp
@@ -0,0 +1,96 @@
+#include "Level/LevelView.h"
+#include "Global/ServiceLocator.h"
+#include "Graphics/GraphicService.h"
+#include "UI/UIElement/RectangleShapeView.h"
+
+namespace Level
+{
+ using namespace UI::UIElement;
+ using namespace Global;
+
+ LevelView::LevelView()
+ {
+ createViews();
+ }
+
+ LevelView::~LevelView()
+ {
+ destroy();
+ }
+
+ void LevelView::calculateGridExtents() {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+
+ grid_width = game_window->getSize().x - 2 * border_offset_left;
+ grid_height = game_window->getSize().y - border_offset_top - border_offset_bottom; // Adjusted to new top and bottom offsets
+ }
+ void LevelView::createViews()
+ {
+ background_rectangle = new RectangleShapeView();
+ border_rectangle = new RectangleShapeView();
+ }
+
+ void LevelView::initialize()
+ {
+ initializeBackground();
+ calculateGridExtents();
+ initializeBorder();
+ }
+
+ void LevelView::initializeBackground()
+ {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+
+ sf::Vector2f background_size = sf::Vector2f(game_window->getSize().x, game_window->getSize().y);
+
+ background_rectangle->initialize(background_size, sf::Vector2f(0, 0), 0, background_color);
+ background_rectangle->show();
+ }
+
+ void LevelView::initializeBorder()
+ {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+
+ sf::Vector2f border_size = sf::Vector2f(grid_width, grid_height);
+ sf::Vector2f border_position = sf::Vector2f(border_offset_left, border_offset_top);
+
+ border_rectangle->initialize(border_size, border_position, border_thickness, sf::Color::Transparent, border_color);
+ border_rectangle->show();
+ }
+
+ void LevelView::calculateGridExtents()
+ {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+
+ grid_width = game_window->getSize().x - 2 * border_offset_left;
+ grid_height = game_window->getSize().y - (border_offset_top + border_offset_bottom);
+ }
+
+ void LevelView::destroy()
+ {
+ delete (background_rectangle);
+ delete (border_rectangle);
+ }
+
+ void LevelView::update()
+ {
+ background_rectangle->update();
+ border_rectangle->update();
+ }
+
+ void LevelView::render()
+ {
+ background_rectangle->render();
+ border_rectangle->render();
+ }
+
+ float LevelView::getGridWidth()
+ {
+ return grid_width;
+ }
+
+ float LevelView::getGridHeight()
+ {
+ return grid_height;
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/LinkedList/SingleLinkedList.cpp b/Linked-List-Snake/source/LinkedList/SingleLinkedList.cpp
new file mode 100644
index 000000000..d0fdd71f5
--- /dev/null
+++ b/Linked-List-Snake/source/LinkedList/SingleLinkedList.cpp
@@ -0,0 +1,304 @@
+#include "LinkedList/SingleLinkedList.h"
+#include "Player/BodyPart.h"
+#include "Level/LevelView.h"
+
+namespace LinkedList
+{
+ SingleLinkedList::SingleLinkedList()
+ {
+ head_node = nullptr;
+ }
+ SingleLinkedList::~SingleLinkedList() = default;
+ void SingleLinkedList::initialize(float width, float height, sf::Vector2i position, Direction direction)
+ {
+ node_width = width;
+ node_height = height;
+ default_position = position;
+ default_direction = direction;
+ }
+ void SingleLinkedList::render()
+ {
+ head_node->body_part.render();
+ }
+ void SingleLinkedList::createHeadNode()
+ {
+ head_node = createNode();
+ head_node->body_part.initialize(node_width, node_height, default_position, default_direction);
+ return;
+ }
+ Node* SingleLinkedList::createNode()
+ {
+ return new Node();
+ }
+
+ sf::Vector2i SingleLinkedList::getNewNodePosition(Node* reference_node, Operation operation)
+ {
+ switch (operation)
+ {
+ case Operation::HEAD:
+ return reference_node->body_part.getNextPosition();
+ case Operation::TAIL:
+ return reference_node->body_part.getPrevPosition();
+ }
+
+ return default_position;
+ }
+
+ void SingleLinkedList::initializeNode(Node* new_node, Node* reference_node, Operation operation)
+ {
+ if (reference_node == nullptr)
+ {
+ new_node->body_part.initialize(node_width, node_height, default_position, default_direction);
+ return;
+ }
+
+ sf::Vector2i position = getNewNodePosition(reference_node, operation);
+
+ new_node->body_part.initialize(node_width, node_height, position, reference_node->body_part.getDirection());
+ }
+
+ void SingleLinkedList::insertNodeAtHead()
+ {
+ linked_list_size++;
+ Node* new_node = createNode();
+
+ if (head_node == nullptr)
+ {
+ head_node = new_node;
+ initializeNode(new_node, nullptr, Operation::HEAD);
+ return;
+ }
+
+ initializeNode(new_node, head_node, Operation::HEAD);
+ new_node->next = head_node;
+ head_node = new_node;
+ }
+
+ void SingleLinkedList::insertNodeAtTail()
+ {
+ linked_list_size++;
+ Node* new_node = createNode();
+ Node* cur_node = head_node;
+
+ if (cur_node == nullptr)
+ {
+ head_node = new_node;
+ initializeNode(new_node, nullptr, Operation::TAIL);
+ return;
+ }
+
+ while (cur_node->next != nullptr)
+ {
+ cur_node = cur_node->next;
+ }
+
+ cur_node->next = new_node;
+ initializeNode(new_node, cur_node, Operation::TAIL);
+ }
+
+ void SingleLinkedList::shiftNodesAfterInsertion(Node* new_node, Node* cur_node, Node* prev_node)
+ {
+ Node* next_node = cur_node;
+ cur_node = new_node;
+
+ while (cur_node != nullptr && next_node != nullptr)
+ {
+ cur_node->body_part.setPosition(next_node->body_part.getPosition());
+ cur_node->body_part.setDirection(next_node->body_part.getDirection());
+
+ prev_node = cur_node;
+ cur_node = next_node;
+ next_node = next_node->next;
+ }
+
+ initializeNode(cur_node, prev_node, Operation::TAIL);
+ }
+
+ int SingleLinkedList::findMiddleNode()
+ {
+ Node* slow = head_node;
+ Node* fast = head_node;
+ int midIndex = 0; // This will track the index of the middle node.
+
+ // Move fast pointer at 2x speed and slow pointer at 1x speed.
+ while (fast != nullptr && fast->next != nullptr) {
+ slow = slow->next;
+ fast = fast->next->next;
+ midIndex++;
+ }
+
+ // Now, slow is at the middle node
+ return midIndex;
+ }
+
+ void SingleLinkedList::insertNodeAtMiddle()
+ {
+ if (head_node == nullptr) {
+ insertNodeAtHead(); // If the list is empty, insert at the head.
+ return;
+ }
+
+ int midIndex = findMiddleNode(); // Use the existing function to find the middle index
+ insertNodeAt(midIndex); // Use the existing function to insert the node at the found index
+ }
+
+ void SingleLinkedList::removeNodeAtHead()
+ {
+ Node* cur_node = head_node;
+ head_node = head_node->next;
+
+ cur_node->next = nullptr;
+ delete (cur_node);
+ }
+
+ void SingleLinkedList::removeNodeAtTail()
+ {
+ if (head_node == nullptr) return;
+ linked_list_size--; //Decrement linked list size when you are deleting a node
+
+ Node* cur_node = head_node;
+
+ if (cur_node->next == nullptr) //If there is only 1 node in the linked list
+ {
+ removeNodeAtHead();
+ return;
+ }
+
+ while (cur_node->next->next != nullptr) //If there is more than 1 node in the linked list
+ {
+ cur_node = cur_node->next;
+ }
+
+ delete (cur_node->next);
+ cur_node->next = nullptr; //Set the new tail node's next pointer to nullptr
+ }
+
+ void SingleLinkedList::removeHalfNodes()
+ {
+ if (linked_list_size <= 1) return;
+ int half_length = linked_list_size / 2;
+ int new_tail_index = half_length - 1;
+
+ Node* prev_node = findNodeAtIndex(new_tail_index);
+ Node* cur_node = prev_node->next;
+
+ while (cur_node != nullptr)
+ {
+ Node* node_to_delete = cur_node;
+ cur_node = cur_node->next;
+
+ delete (node_to_delete);
+ linked_list_size--;
+ }
+
+ prev_node->next = nullptr;
+ }
+
+ void SingleLinkedList::reverseNodeDirections()
+ {
+ Node* curr_node = head_node;
+
+ while (curr_node != nullptr)
+ {
+ curr_node->body_part.setDirection(getReverseDirection(curr_node->body_part.getPreviousDirection()));
+ curr_node = curr_node->next;
+ }
+ }
+
+ Direction SingleLinkedList::reverse()
+ {
+ Node* cur_node = head_node;
+ Node* prev_node = nullptr;
+ Node* next_node = nullptr;
+
+ while (cur_node != nullptr)
+ {
+ next_node = cur_node->next;
+ cur_node->next = prev_node;
+
+ prev_node = cur_node;
+ cur_node = next_node;
+ }
+
+ head_node = prev_node;
+
+ reverseNodeDirections();
+ return head_node->body_part.getDirection();
+ }
+
+
+ void SingleLinkedList::insertNodeAtTail() {
+ Node* new_node = createNode();
+ Node* cur_node = head_node;
+
+ if (cur_node == nullptr) { // If the list is empty, set the new node as the head
+ head_node = new_node;
+ new_node->body_part.initialize(node_width, node_height, default_position, default_direction);
+ return;
+ }
+
+ // Traverse to the end of the list
+ while (cur_node->next != nullptr) {
+ cur_node = cur_node->next;
+ }
+
+ // Attach the new node at the end
+ cur_node->next = new_node;
+ new_node->body_part.initialize(node_width, node_height, getNewNodePosition(cur_node), cur_node->body_part.getDirection());
+ }
+ void SingleLinkedList::updateNodePosition()
+ {
+ Node* cur_node = head_node;
+
+ while (cur_node != nullptr)
+ {
+ cur_node->body_part.updatePosition();
+ cur_node = cur_node->next;
+ }
+ }
+
+ bool SingleLinkedList::processNodeCollision()
+ {
+ if (head_node == nullptr) return false;
+
+ sf::Vector2i predicted_position = head_node->body_part.getNextPosition();
+
+ Node* cur_node = head_node->next;
+ while (cur_node != nullptr)
+ {
+ if (cur_node->body_part.getNextPosition() == predicted_position) return true;
+ cur_node = cur_node->next;
+ }
+
+ return false;
+ }
+
+ void SingleLinkedList::render() {
+ Node* cur_node = head_node;
+
+ while (cur_node != nullptr) { // Traverse through the linked list and render each node's body part
+ cur_node->body_part.render();
+ cur_node = cur_node->next;
+ }
+ }
+
+ void SingleLinkedList::removeAllNodes()
+ {
+ if (head_node == nullptr) return;
+
+ while (head_node != nullptr)
+ {
+ removeNodeAtHead();
+ }
+ }
+
+ void SingleLinkedList::removeNodeAtHead()
+ {
+ Node* cur_node = head_node;
+ head_node = head_node->next;
+
+ cur_node->next = nullptr;
+ delete (cur_node);
+ }
+}}
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Player/BodyPart.cpp b/Linked-List-Snake/source/Player/BodyPart.cpp
new file mode 100644
index 000000000..5d07a033e
--- /dev/null
+++ b/Linked-List-Snake/source/Player/BodyPart.cpp
@@ -0,0 +1,127 @@
+#include "Player/BodyPart.h"
+#include "Global/ServiceLocator.h"
+#include "Level/LevelView.h"
+#include "Level/LevelModel.h"
+#include "Global/Config.h"
+
+
+namespace Player
+{
+ using namespace Global;
+ using namespace Level;
+ using namespace UI::UIElement;
+
+ BodyPart::BodyPart()
+ {
+ grid_position = sf::Vector2i(0, 0);
+ createBodyPartImage();
+ }
+
+ BodyPart::~BodyPart()
+ {
+ destroy();
+ }
+
+ void BodyPart::initialize(float width, float height, sf::Vector2i pos, Direction dir)
+ {
+ bodypart_width = width;
+ bodypart_height = height;
+ direction = dir;
+ grid_position = pos;
+
+ initializeBodyPartImage();
+ }
+
+ void BodyPart::setDirection(Direction direction)
+ {
+ previous_direction = this->direction;
+ this->direction = direction;
+ }
+
+ sf::Vector2f BodyPart::getBodyPartScreenPosition()
+ {
+ float x_screen_position = LevelView::border_offset_left + (grid_position.x * bodypart_width) + (bodypart_width / 2);
+ float y_screen_position = LevelView::border_offset_top + (grid_position.y * bodypart_height) + (bodypart_height / 2);
+
+ return sf::Vector2f(x_screen_position, y_screen_position);
+ }
+
+
+ float BodyPart::getRotationAngle()
+ {
+ switch (direction)
+ {
+ case Direction::UP:
+ return 270.f;
+ case Direction::DOWN:
+ return 90.f;
+ case Direction::RIGHT:
+ return 0;
+ case Direction::LEFT:
+ return 180.f;
+ }
+ }
+
+ void BodyPart::setDirection(Direction direction)
+ {
+ this->direction = direction;
+ }
+
+ void BodyPart::updatePosition()
+ {
+ bodypart_image->setPosition(getBodyPartScreenPosition());
+ bodypart_image->setRotation(getRotationAngle());
+ bodypart_image->update();
+ }
+
+ sf::Vector2i BodyPart::getNextPosition()
+ {
+ switch (direction)
+ {
+ case Direction::UP:
+ return getNextPositionUp();
+ case Direction::DOWN:
+ return getNextPositionDown();
+ case Direction::RIGHT:
+ return getNextPositionRight();
+ case Direction::LEFT:
+ return getNextPositionLeft();
+ default:
+ return grid_position;
+ }
+ }
+
+ void BodyPart::setPosition(sf::Vector2i position)
+ {
+ grid_position = position;
+ }
+
+ void BodyPart::updatePosition()
+ {
+
+
+ bodypart_image->setPosition(getBodyPartScreenPosition());
+ bodypart_image->setRotation(getRotationAngle());
+ bodypart_image->update();
+ }
+
+ sf::Vector2i BodyPart::getNextPositionDown()
+ {
+ return sf::Vector2i(grid_position.x, (grid_position.y + 1) % (LevelModel::number_of_rows));
+ }
+
+ sf::Vector2i BodyPart::getNextPositionUp()
+ {
+ return sf::Vector2i(grid_position.x, (grid_position.y - 1 + (LevelModel::number_of_rows)) % (LevelModel::number_of_rows));
+ }
+
+ sf::Vector2i BodyPart::getNextPositionRight()
+ {
+ return sf::Vector2i((grid_position.x + 1) % (LevelModel::number_of_columns), grid_position.y);
+ }
+
+ sf::Vector2i BodyPart::getNextPositionLeft()
+ {
+ return sf::Vector2i((grid_position.x - 1 + LevelModel::number_of_columns) % (LevelModel::number_of_columns), grid_position.y);
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Player/PlayerService.cpp b/Linked-List-Snake/source/Player/PlayerService.cpp
new file mode 100644
index 000000000..cd90ee189
--- /dev/null
+++ b/Linked-List-Snake/source/Player/PlayerService.cpp
@@ -0,0 +1,44 @@
+#include "Player/PlayerService.h"
+#include "Player/SnakeController.h"
+
+namespace Player
+{
+ PlayerService::PlayerService()
+ {
+ snake_controller = nullptr;
+
+ createController();
+ }
+
+ PlayerService::~PlayerService()
+ {
+ destroy();
+ }
+
+ void PlayerService::createController()
+ {
+ snake_controller = new SnakeController();
+ }
+
+ void PlayerService::initialize()
+ {
+ snake_controller->initialize();
+ }
+
+ void PlayerService::update()
+ {
+ snake_controller->update();
+ }
+
+ void PlayerService::render()
+ {
+ snake_controller->render();
+ }
+
+ void PlayerService::spawnPlayer() { }
+
+ void PlayerService::destroy()
+ {
+ delete (snake_controller);
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/Player/SnakeController.cpp b/Linked-List-Snake/source/Player/SnakeController.cpp
new file mode 100644
index 000000000..fc84a98c7
--- /dev/null
+++ b/Linked-List-Snake/source/Player/SnakeController.cpp
@@ -0,0 +1,282 @@
+#include "Player/SnakeController.h"
+#include "Global/ServiceLocator.h"
+#include "Level/LevelService.h"
+
+namespace Player
+{
+ using namespace LinkedList;
+ using namespace Global;
+ using namespace Level;
+
+ SnakeController::SnakeController()
+ {
+ single_linked_list = nullptr;
+ createLinkedList();
+ }
+
+ SnakeController::~SnakeController()
+ {
+ destroy();
+ }
+
+ void SnakeController::createLinkedList()
+ {
+ single_linked_list = new SingleLinkedList();
+ }
+
+ void SnakeController::initialize()
+ {
+ float width = ServiceLocator::getInstance()->getLevelService()->getCellWidth();
+ float height = ServiceLocator::getInstance()->getLevelService()->getCellHeight();
+
+ single_linked_list->initialize(width, height, default_position, default_direction);
+ }
+ void SnakeController::processPlayerInput()
+ {
+ EventService* event_service = ServiceLocator::getInstance()->getEventService();
+
+ if (event_service->pressedUpArrowKey() && current_snake_direction != Direction::DOWN)
+ {
+ current_snake_direction = Direction::UP;
+ }
+ else if (event_service->pressedDownArrowKey() && current_snake_direction != Direction::UP)
+ {
+ current_snake_direction = Direction::DOWN;
+ }
+ else if (event_service->pressedLeftArrowKey() && current_snake_direction != Direction::RIGHT)
+ {
+ current_snake_direction = Direction::LEFT;
+ }
+ else if (event_service->pressedRightArrowKey() && current_snake_direction != Direction::LEFT)
+ {
+ current_snake_direction = Direction::RIGHT;
+ }
+ }
+ void SnakeController::update()
+ {
+ switch (current_snake_state)
+ {
+ case SnakeState::ALIVE:
+ processPlayerInput();
+ updateSnakeDirection();
+ processSnakeCollision();
+ moveSnake();
+ break;
+
+ case SnakeState::DEAD:
+ handleRestart();
+ break;
+ }
+ }
+ void SnakeController::processSnakeCollision()
+ {
+ processBodyCollision();
+ processElementsCollision();
+ processFoodCollision();
+ }
+
+ void SnakeController::processBodyCollision()
+ {
+ if (single_linked_list->processNodeCollision())
+ {
+ current_snake_state = SnakeState::DEAD;
+ ServiceLocator::getInstance()->getSoundService()->playSound(SoundType::DEATH);
+ }
+ }
+
+ void SnakeController::processElementsCollision()
+ {
+ }
+
+ void SnakeController::processFoodCollision()
+ {
+ FoodService* food_service = ServiceLocator::getInstance()->getFoodService();
+ FoodType food_type;
+
+ if (food_service->processFoodCollision(single_linked_list->getHeadNode(), food_type))
+ {
+ ServiceLocator::getInstance()->getSoundService()->playSound(SoundType::PICKUP);
+
+ food_service->destroyFood();
+ OnFoodCollected(food_type);
+ }
+ }
+
+ void SnakeController::OnFoodCollected(FoodType food_type)
+ {
+ switch (food_type)
+ {
+ case FoodType::PIZZA:
+ //Insert At Tail
+ break;
+
+ case FoodType::BURGER:
+ //Insert At Head
+ break;
+
+ case FoodType::CHEESE:
+ //Insert in Middle
+ break;
+
+ case FoodType::APPLE:
+ //Delete at Head
+ break;
+
+ case FoodType::MANGO:
+ //Delete at Middle
+ break;
+
+ case FoodType::ORANGE:
+ //Delete at Tail
+ break;
+
+ case FoodType::POISION:
+ //Delete half the snake
+ break;
+
+ case FoodType::ALCOHOL:
+ //Reverse the snake
+ break;
+ }
+ }
+
+ void SnakeController::render()
+ {
+ single_linked_list->render();
+ }
+ void SnakeController::OnFoodCollected(FoodType food_type)
+ {
+ switch (food_type)
+ {
+ case FoodType::PIZZA:
+ //Insert at TAIL
+ single_linked_list->insertNodeAtTail();
+ break;
+
+ case FoodType::BURGER:
+ //Insert at HEAD
+ single_linked_list->insertNodeAtHead();
+ break;
+
+ case FoodType::CHEESE:
+ //Insert at MIDDLE
+ single_linked_list->insertNodeAtMiddle();
+ break;
+
+ case FoodType::APPLE:
+ //Delete at HEAD
+ single_linked_list->removeNodeAtHead();
+ break;
+
+ case FoodType::MANGO:
+ //Delete at MIDDLE
+ single_linked_list->removeNodeAtMiddle();
+ break;
+
+ case FoodType::ORANGE:
+ //Delete at TAIL
+ single_linked_list->removeNodeAtTail();
+ break;
+
+ case FoodType::POISION:
+ //Delete half nodes
+ single_linked_list->removeHalfNodes();
+ break;
+
+ case FoodType::ALCOHOL:
+ //Reverse Direction
+ current_snake_direction = single_linked_list->reverse();
+ break;
+ }
+ }
+ void SnakeController::processPlayerInput() { }
+
+ void SnakeController::updateSnakeDirection() { }
+
+ void SnakeController::moveSnake() { }
+
+ void SnakeController::processSnakeCollision() { }
+
+ void SnakeController::handleRestart() { }
+
+ void SnakeController::spawnSnake()
+ {
+ single_linked_list->createHeadNode();
+ }
+
+ void SnakeController::reset() {
+ }
+
+ void SnakeController::respawnSnake() { }
+
+ void SnakeController::setSnakeState(SnakeState state)
+ {
+ current_snake_state = state;
+ }
+
+ SnakeState SnakeController::getSnakeState()
+ {
+ return current_snake_state;
+ }
+
+ void SnakeController::destroy()
+ {
+ delete (single_linked_list);
+ }
+
+ void SnakeController::update()
+ {
+ switch (current_snake_state)
+ {
+ case SnakeState::ALIVE:
+ processPlayerInput();
+ updateSnakeDirection();
+ processSnakeCollision();
+ moveSnake();
+ break;
+
+ case SnakeState::DEAD:
+ handleRestart();
+ break;
+ }
+ }
+
+ void SnakeController::reset()
+ {
+ current_snake_state = SnakeState::ALIVE;
+ current_snake_direction = default_direction;
+ elapsed_duration = 0.f;
+ restart_counter = 0.f;
+ }
+
+ void SnakeController::respawnSnake()
+ {
+ single_linked_list->removeAllNodes();
+ reset();
+ spawnSnake();
+ }
+
+ void SnakeController::handleRestart()
+ {
+ restart_counter += ServiceLocator::getInstance()->getTimeService()->getDeltaTime();
+
+ if (restart_counter >= restart_duration)
+ {
+ respawnSnake();
+ }
+ }
+
+
+ void SnakeController::delayedUpdate()
+ {
+ elapsed_duration += ServiceLocator::getInstance()->getTimeService()->getDeltaTime();
+
+ if (elapsed_duration >= movement_frame_duration)
+ {
+ elapsed_duration = 0.f;
+ updateSnakeDirection();
+ processSnakeCollision();
+ moveSnake();
+ }
+ }
+}
diff --git a/Linked-List-Snake/source/UI/GameplayUI/GameplayUIController.cpp b/Linked-List-Snake/source/UI/GameplayUI/GameplayUIController.cpp
new file mode 100644
index 000000000..1a9f88a78
--- /dev/null
+++ b/Linked-List-Snake/source/UI/GameplayUI/GameplayUIController.cpp
@@ -0,0 +1,184 @@
+#include "UI/GameplayUI/GameplayUIController.h"
+#include "Main/GameService.h"
+#include "Graphics/GraphicService.h"
+#include "Sound/SoundService.h"
+#include "Event/EventService.h"
+#include "Global/Config.h"
+#include "Level/LevelModel.h"
+#include "Player/PlayerService.h"
+
+namespace UI
+{
+ namespace GameplayUI
+ {
+ using namespace Global;
+ using namespace Event;
+ using namespace Sound;
+ using namespace Main;
+ using namespace Graphics;
+ using namespace Level;
+ using namespace Player;
+ using namespace UI::UIElement;
+
+ GameplayUIController::GameplayUIController()
+ {
+ createTexts();
+ }
+
+ GameplayUIController::~GameplayUIController()
+ {
+ destroy();
+ }
+
+ void GameplayUIController::initialize()
+ {
+ initializeTexts();
+ }
+
+ void GameplayUIController::createTexts()
+ {
+ level_number_text = new TextView();
+ score_text = new TextView();
+ time_complexity_text = new TextView();
+ operation_text = new TextView();
+ }
+
+ void GameplayUIController::initializeTexts()
+ {
+ initializeLevelNumberText();
+ initializeScoreText();
+ initializeTimeComplexityText();
+ initializeOperationText();
+ }
+
+ void GameplayUIController::initializeLevelNumberText()
+ {
+ level_number_text->initialize("Level : 1", sf::Vector2f(level_number_text_x_position, text_y_position), FontType::BUBBLE_BOBBLE, font_size, sf::Color::Black);
+ }
+
+ void GameplayUIController::initializeScoreText()
+ {
+ score_text->initialize("Score : 0", sf::Vector2f(score_text_x_position, text_y_position), FontType::BUBBLE_BOBBLE, font_size, sf::Color::Black);
+ }
+
+ void GameplayUIController::initializeTimeComplexityText()
+ {
+ time_complexity_text->initialize("Time Complexity : O(1)", sf::Vector2f(time_complexity_text_x_position, time_complexity_text_y_position), FontType::BUBBLE_BOBBLE, operations_font_size, sf::Color::Black);
+ }
+
+ void GameplayUIController::initializeOperationText()
+ {
+ operation_text->initialize("Last Operation : Insert at Middle", sf::Vector2f(operations_text_x_position, operations_text_y_position), FontType::BUBBLE_BOBBLE, operations_font_size, sf::Color::Black);
+ }
+
+ void GameplayUIController::updateLevelNumberText()
+ {
+ LevelNumber level_number = ServiceLocator::getInstance()->getLevelService()->getCurrentLevel();
+ sf::String level_number_value = std::to_string(1 + static_cast(level_number));
+
+ level_number_text->setText("Level : " + level_number_value);
+ level_number_text->update();
+ }
+
+ void GameplayUIController::updateScoreText()
+ {
+ int player_score = ServiceLocator::getInstance()->getPlayerService()->getPlayerScore();
+ sf::String score_value = std::to_string(player_score);
+
+ score_text->setText("Score : " + score_value);
+ score_text->update();
+ }
+
+ void GameplayUIController::updateTimeComplexityText()
+ {
+ TimeComplexity time_complexity = ServiceLocator::getInstance()->getPlayerService()->getTimeComplexity();
+ sf::String time_complexity_value;
+
+ switch (time_complexity)
+ {
+ case TimeComplexity::NONE:
+ time_complexity_value = "";
+ case TimeComplexity::ONE:
+ time_complexity_value = "1";
+ break;
+ case TimeComplexity::N:
+ time_complexity_value = "N";
+ break;
+ }
+ time_complexity_text->setText("Time Complexity : (" + time_complexity_value + ")");
+ time_complexity_text->update();
+ }
+
+ void GameplayUIController::updateOperationText()
+ {
+ LinkedListOperations operation = ServiceLocator::getInstance()->getPlayerService()->getLastOperation();
+ sf::String operation_value;
+
+ switch (operation)
+ {
+ case LinkedListOperations::NONE:
+ operation_value = "";
+ case LinkedListOperations::INSERT_AT_HEAD:
+ operation_value = "Insert at Head";
+ break;
+ case LinkedListOperations::INSERT_AT_TAIL:
+ operation_value = "Insert at Tail";
+ break;
+ case LinkedListOperations::INSERT_AT_MID:
+ operation_value = "Insert at Mid";
+ break;
+ case LinkedListOperations::REMOVE_AT_HEAD:
+ operation_value = "Remove at Head";
+ break;
+ case LinkedListOperations::REMOVE_AT_TAIL:
+ operation_value = "Remove at Tail";
+ break;
+ case LinkedListOperations::REMOVE_AT_MID:
+ operation_value = "Remove at Mid";
+ break;
+ case LinkedListOperations::DELETE_HALF_LIST:
+ operation_value = "Delete Half List";
+ break;
+ case LinkedListOperations::REVERSE_LIST:
+ operation_value = "Reverse List";
+ break;
+
+ }
+
+ operation_text->setText("Last Operation : " + operation_value);
+ operation_text->update();
+ }
+
+ void GameplayUIController::update()
+ {
+ updateLevelNumberText();
+ updateScoreText();
+ updateTimeComplexityText();
+ updateOperationText();
+ }
+
+ void GameplayUIController::render()
+ {
+ level_number_text->render();
+ score_text->render();
+ time_complexity_text->render();
+ operation_text->render();
+ }
+
+ void GameplayUIController::show()
+ {
+ level_number_text->show();
+ score_text->show();
+ time_complexity_text->show();
+ operation_text->show();
+ }
+
+ void GameplayUIController::destroy()
+ {
+ delete (level_number_text);
+ delete (score_text);
+ delete (time_complexity_text);
+ delete (operation_text);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/UI/LevelSelection/LevelSelectionUIController.cpp b/Linked-List-Snake/source/UI/LevelSelection/LevelSelectionUIController.cpp
new file mode 100644
index 000000000..857ef3a00
--- /dev/null
+++ b/Linked-List-Snake/source/UI/LevelSelection/LevelSelectionUIController.cpp
@@ -0,0 +1,122 @@
+#include "UI/LevelSelection/LevelSelectionUIController.h"
+#include "Main/GameService.h"
+#include "Graphics/GraphicService.h"
+#include "Sound/SoundService.h"
+#include "Event/EventService.h"
+#include "UI/UIElement/ButtonView.h"
+#include "UI/UIElement/ImageView.h"
+#include "Global/Config.h"
+
+
+namespace UI
+{
+ using namespace UIElement;
+ using namespace Global;
+ using namespace Event;
+ using namespace Sound;
+ using namespace Main;
+
+
+ namespace LevelSelection
+ {
+ LevelSelectionUIController::LevelSelectionUIController()
+ {
+ createButtons();
+ createImage();
+ }
+
+ LevelSelectionUIController::~LevelSelectionUIController()
+ {
+ destroy();
+ }
+
+ void LevelSelectionUIController::initialize()
+ {
+ initializeBackgroundImage();
+ initializeButtons();
+ registerButtonCallback();
+ }
+
+ void LevelSelectionUIController::createImage()
+ {
+ background_image = new ImageView();
+ }
+
+ void LevelSelectionUIController::createButtons()
+ {
+ level_one_button = new ButtonView();
+ level_two_button = new ButtonView();
+ menu_button = new ButtonView();
+ }
+
+ void LevelSelectionUIController::initializeBackgroundImage()
+ {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+
+ background_image->initialize(Config::background_texture_path, game_window->getSize().x, game_window->getSize().y, sf::Vector2f(0, 0));
+ background_image->setImageAlpha(background_alpha);
+ }
+
+ void LevelSelectionUIController::initializeButtons()
+ {
+ float x_position = calculateLeftOffsetForButton();
+
+ level_one_button->initialize("Level One Button", Config::level_one_button_texture_path, button_width, button_height, sf::Vector2f(x_position, level_one_button_y_position));
+ level_two_button->initialize("Level Two Button", Config::level_two_button_texture_path, button_width, button_height, sf::Vector2f(x_position, level_two_button_y_position));
+ menu_button->initialize("Menu Button", Config::menu_button_texture_path, button_width, button_height, sf::Vector2f(x_position, menu_button_y_position));
+ }
+
+ void LevelSelectionUIController::registerButtonCallback()
+ {
+ level_one_button->registerCallbackFuntion(std::bind(&LevelSelectionUIController::levelOneButtonCallback, this));
+ level_two_button->registerCallbackFuntion(std::bind(&LevelSelectionUIController::levelTwoButtonCallback, this));
+ menu_button->registerCallbackFuntion(std::bind(&LevelSelectionUIController::menuButtonCallback, this));
+ }
+
+ float LevelSelectionUIController::calculateLeftOffsetForButton()
+ {
+ sf::RenderWindow* game_window = ServiceLocator::getInstance()->getGraphicService()->getGameWindow();
+ return (static_cast(game_window->getSize().x) / 2) - button_width / 2;
+ }
+
+
+
+ void LevelSelectionUIController::menuButtonCallback()
+ {
+ ServiceLocator::getInstance()->getSoundService()->playSound(SoundType::BUTTON_CLICK);
+ GameService::setGameState(GameState::MAIN_MENU);
+ }
+
+ void LevelSelectionUIController::update()
+ {
+ background_image->update();
+ level_one_button->update();
+ level_two_button->update();
+ menu_button->update();
+ }
+
+ void LevelSelectionUIController::render()
+ {
+ background_image->render();
+ level_one_button->render();
+ level_two_button->render();
+ menu_button->render();
+ }
+
+ void LevelSelectionUIController::show()
+ {
+ background_image->show();
+ level_one_button->show();
+ level_two_button->show();
+ menu_button->show();
+ }
+
+ void LevelSelectionUIController::destroy()
+ {
+ delete (background_image);
+ delete (level_one_button);
+ delete (level_two_button);
+ delete (menu_button);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/UI/MainMenu/MainMenuUIController.cpp b/Linked-List-Snake/source/UI/MainMenu/MainMenuUIController.cpp
index 506483da7..2826b2b52 100644
--- a/Linked-List-Snake/source/UI/MainMenu/MainMenuUIController.cpp
+++ b/Linked-List-Snake/source/UI/MainMenu/MainMenuUIController.cpp
@@ -75,6 +75,7 @@ namespace UI
{
// GameState will change to gameplay state.
ServiceLocator::getInstance()->getSoundService()->playSound(SoundType::BUTTON_CLICK);
+ GameService::setGameState(GameState::LEVEL_SELECTION);
}
void MainMenuUIController::instructionsButtonCallback()
diff --git a/Linked-List-Snake/source/UI/UIElement/RectangleShapeView.cpp b/Linked-List-Snake/source/UI/UIElement/RectangleShapeView.cpp
new file mode 100644
index 000000000..d598e28b7
--- /dev/null
+++ b/Linked-List-Snake/source/UI/UIElement/RectangleShapeView.cpp
@@ -0,0 +1,63 @@
+#include "UI/UIElement/RectangleShapeView.h"
+
+namespace UI
+{
+ namespace UIElement
+ {
+ RectangleShapeView::RectangleShapeView() = default;
+
+ RectangleShapeView::~RectangleShapeView() = default;
+
+ void RectangleShapeView::initialize(sf::Vector2f rectangle_size, sf::Vector2f rectangle_position, int outline_thickness, sf::Color fill_color, sf::Color outline_color)
+ {
+ UIView::initialize();
+
+ setSize(rectangle_size);
+ setPosition(rectangle_position);
+ setOutlineThickness(outline_thickness);
+ setFillColor(fill_color);
+ setOutlineColor(outline_color);
+ }
+
+ void RectangleShapeView::update()
+ {
+ UIView::update();
+ }
+
+ void RectangleShapeView::render()
+ {
+ UIView::render();
+
+ if (ui_state == UIState::VISIBLE)
+ {
+ game_window->draw(rectangle_shape);
+ }
+ }
+
+ void RectangleShapeView::setSize(sf::Vector2f rectangle_size)
+ {
+ rectangle_shape.setSize(rectangle_size);
+ }
+
+ void RectangleShapeView::setPosition(sf::Vector2f rectangle_position)
+ {
+ rectangle_shape.setPosition(rectangle_position);
+ }
+
+ void RectangleShapeView::setFillColor(sf::Color fill_color)
+ {
+ rectangle_shape.setFillColor(fill_color);
+ }
+
+ void RectangleShapeView::setOutlineColor(sf::Color outline_color)
+ {
+ rectangle_shape.setOutlineColor(outline_color);
+ }
+
+ void RectangleShapeView::setOutlineThickness(int outline_thickness)
+ {
+ rectangle_shape.setOutlineThickness(outline_thickness);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Linked-List-Snake/source/UI/UIService.cpp b/Linked-List-Snake/source/UI/UIService.cpp
index 1abc8ab1a..7b0611e2b 100644
--- a/Linked-List-Snake/source/UI/UIService.cpp
+++ b/Linked-List-Snake/source/UI/UIService.cpp
@@ -11,6 +11,7 @@ namespace UI
using namespace Credits;
using namespace UIElement;
using namespace Interface;
+ //using namespace LevelSelection;
UIService::UIService()
{