getAll() {
+ return questions;
+ }
+}
diff --git a/Oleksandr-JR-Example/src/main/webapp/WEB-INF/web.xml b/Denys/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from Oleksandr-JR-Example/src/main/webapp/WEB-INF/web.xml
rename to Denys/src/main/webapp/WEB-INF/web.xml
diff --git a/Denys/src/main/webapp/css/style.css b/Denys/src/main/webapp/css/style.css
new file mode 100644
index 0000000..606735f
--- /dev/null
+++ b/Denys/src/main/webapp/css/style.css
@@ -0,0 +1,49 @@
+body {
+ margin: 0;
+ font-family: 'Segoe UI', sans-serif;
+ background: radial-gradient(circle, #0f2027, #203a43, #2c5364);
+ color: #fff;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 100vh;
+}
+
+h1, h2 {
+ font-size: 3em;
+ margin-bottom: 10px;
+ text-align: center;
+ text-shadow: 0 0 10px #00ffff;
+}
+
+p {
+ font-size: 1.5em;
+ text-align: center;
+ margin-bottom: 30px;
+}
+
+a.button, button {
+ background: #00ffff;
+ color: #000;
+ padding: 12px 25px;
+ border-radius: 10px;
+ font-weight: bold;
+ font-size: 1.2em;
+ border: none;
+ cursor: pointer;
+ transition: 0.3s;
+}
+
+a.button:hover, button:hover {
+ background: #00cccc;
+ box-shadow: 0 0 10px #00ffff;
+}
+
+form {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 15px;
+ margin-top: 30px;
+}
diff --git a/Denys/src/main/webapp/index.jsp b/Denys/src/main/webapp/index.jsp
new file mode 100644
index 0000000..bc7fe2e
--- /dev/null
+++ b/Denys/src/main/webapp/index.jsp
@@ -0,0 +1,14 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+
+
+ Коллайдер
+
+
+
+Коллайдер
+Вітаємо в інтерактивному квесті!
Почни своє проходження прямо зараз!
+Почати гру
+
+
diff --git a/Denys/src/main/webapp/quiz.jsp b/Denys/src/main/webapp/quiz.jsp
new file mode 100644
index 0000000..e8c28c2
--- /dev/null
+++ b/Denys/src/main/webapp/quiz.jsp
@@ -0,0 +1,47 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ page import="model.Question" %>
+<%@ page import="java.util.*" %>
+<%
+ Question question = (Question) request.getAttribute("question");
+ int qIndex = (Integer) request.getAttribute("qIndex");
+ Integer gamesPlayed = (Integer) session.getAttribute("gamesPlayed");
+ if (gamesPlayed == null) gamesPlayed = 0;
+
+ String text = question.getText().toLowerCase();
+ boolean isEnding = text.contains("поразка") || text.contains("перемога");
+%>
+
+
+
+
+ Квест
+
+
+
+
+<%= question.getText() %>
+
+Кількість пройдених ігор: <%= gamesPlayed %>
+
+<% if (isEnding) { %>
+Почати заново
+<% } else { %>
+
+<% } %>
+
+
+
+
+
diff --git a/Denys/src/main/webapp/result.jsp b/Denys/src/main/webapp/result.jsp
new file mode 100644
index 0000000..2f6d7d0
--- /dev/null
+++ b/Denys/src/main/webapp/result.jsp
@@ -0,0 +1,19 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+
+
+ Результат
+
+
+
+
+Гра завершена!
+
+Дякуємо за гру!
+Ви вже зіграли <%= session.getAttribute("gamesPlayed") != null ? session.getAttribute("gamesPlayed") : 1 %> раз(ів).
+
+Почати заново
+
+
+
diff --git a/Denys/src/test/java/controller/QuizServletTest.java b/Denys/src/test/java/controller/QuizServletTest.java
new file mode 100644
index 0000000..a14f766
--- /dev/null
+++ b/Denys/src/test/java/controller/QuizServletTest.java
@@ -0,0 +1,88 @@
+package controller;
+
+import model.Question;
+import repository.QuestionRepository;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.*;
+
+public class QuizServletTest {
+
+ @InjectMocks
+ private QuizServlet realServlet;
+
+ private QuizServlet servlet;
+
+ @Mock
+ private HttpServletRequest request;
+
+ @Mock
+ private HttpServletResponse response;
+
+ @Mock
+ private HttpSession session;
+
+ @Mock
+ private ServletContext servletContext;
+
+ @Mock
+ private RequestDispatcher dispatcher;
+
+ @BeforeEach
+ public void setup() {
+ MockitoAnnotations.openMocks(this);
+
+ servlet = spy(realServlet);
+ when(request.getSession()).thenReturn(session);
+ when(request.getServletContext()).thenReturn(servletContext);
+ doReturn(servletContext).when(servlet).getServletContext();
+ }
+
+ @Test
+ public void testDoGet_NewGame_ShouldStartAtIndexZero() throws Exception {
+ when(session.getAttribute("currentIndex")).thenReturn(null);
+ when(servletContext.getRequestDispatcher("/quiz.jsp")).thenReturn(dispatcher);
+
+ servlet.doGet(request, response);
+
+ verify(session).setAttribute("currentIndex", 0);
+ verify(dispatcher).forward(request, response);
+ }
+
+ @Test
+ public void testDoPost_ValidAnswer_RedirectsToNextQuestion() throws Exception {
+ QuestionRepository repo = QuestionRepository.getInstance();
+ repo.getAll().clear();
+ repo.getAll().add(
+ Question.builder()
+ .text("Test?")
+ .answers(new ArrayList<>(List.of("Yes", "No")))
+ .nextQuestions(new ArrayList<>(List.of(1, 2)))
+ .build()
+ );
+
+ when(request.getParameter("qIndex")).thenReturn("0");
+ when(request.getParameter("answerIndex")).thenReturn("1");
+ when(request.getSession()).thenReturn(session);
+
+ servlet.doPost(request, response);
+
+ verify(session).setAttribute("currentIndex", 2);
+ verify(response).sendRedirect("quiz");
+ }
+}
+
diff --git a/Denys/src/test/java/model/QuestionRepositoryTest.java b/Denys/src/test/java/model/QuestionRepositoryTest.java
new file mode 100644
index 0000000..2a12719
--- /dev/null
+++ b/Denys/src/test/java/model/QuestionRepositoryTest.java
@@ -0,0 +1,74 @@
+package model;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import repository.QuestionRepository;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+public class QuestionRepositoryTest {
+
+ private QuestionRepository repository;
+
+ @BeforeEach
+ public void setup() {
+ repository = QuestionRepository.getInstance();
+ repository.getAll().clear();
+
+ repository.getAll().add(
+ Question.builder()
+ .text("Question 0?")
+ .answers(new ArrayList<>(List.of("Answer 1", "Answer 2")))
+ .nextQuestions(new ArrayList<>(List.of(1, 2)))
+ .build()
+ );
+
+ repository.getAll().add(
+ Question.builder()
+ .text("Question 1?")
+ .answers(new ArrayList<>())
+ .nextQuestions(new ArrayList<>())
+ .build()
+ );
+
+ repository.getAll().add(
+ Question.builder()
+ .text("Question 2?")
+ .answers(new ArrayList<>())
+ .nextQuestions(new ArrayList<>())
+ .build()
+ );
+ }
+
+ @Test
+ public void testQuestionsAreLoaded() {
+ ArrayList questions = repository.getAll();
+ assertFalse(questions.isEmpty(), "Questions should be loaded");
+ }
+
+ @Test
+ public void testTwoAnswers() {
+ Question q0 = repository.getAll().get(0);
+ assertEquals(2, q0.getAnswers().size(), "First question should have two answers");
+ }
+
+ @Test
+ public void testNavigation() {
+ Question q0 = repository.getAll().get(0);
+ int next = q0.getNextQuestions().get(0);
+ Question q1 = repository.getAll().get(next);
+ assertNotNull(q1, "Should navigate to next question");
+ }
+
+ @Test
+ public void testHaveNoNext() {
+ for (Question q : repository.getAll()) {
+ if (q.getAnswers().isEmpty()) {
+ assertTrue(q.getNextQuestions().isEmpty(), "Terminal questions should not have next steps");
+ }
+ }
+ }
+}
diff --git a/Oleksandr-JR-Example/src/main/java/controller/QuizServlet.java b/Oleksandr-JR-Example/src/main/java/controller/QuizServlet.java
deleted file mode 100644
index ae63a3d..0000000
--- a/Oleksandr-JR-Example/src/main/java/controller/QuizServlet.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package controller;
-
-import model.Question;
-import repository.QuestionRepository;
-
-import javax.servlet.ServletException;
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.ArrayList;
-
-@WebServlet(name = "QuizServlet", value = "/quiz")
-public class QuizServlet extends HttpServlet {
- private static final QuestionRepository questionRepository = QuestionRepository.getInstance();
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
-
- ArrayList questions = questionRepository.getAll();
-
-
- req.getSession().setAttribute("questions", questions);
-
- // Forwarding to the JSP page
- getServletContext().getRequestDispatcher("/quiz.jsp").forward(req, resp);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- // Placeholder for POST handling logic
- resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "POST method is not supported.");
- }
-}
diff --git a/Oleksandr-JR-Example/src/main/java/repository/QuestionRepository.java b/Oleksandr-JR-Example/src/main/java/repository/QuestionRepository.java
deleted file mode 100644
index c64ac92..0000000
--- a/Oleksandr-JR-Example/src/main/java/repository/QuestionRepository.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package repository;
-
-import model.Question;
-
-import java.util.ArrayList;
-
-public class QuestionRepository {
- private static QuestionRepository INSTANCE;
-
- private final ArrayList questions = new ArrayList<>();
-
-
- private QuestionRepository() {
- ArrayList answers = new ArrayList<>();
- answers.add("A");
- answers.add("B");
- answers.add("C");
- answers.add("Programming language");
-
- questions.add(Question.builder()
- .text("What is java")
- .answers(answers)
- .correctAnswer(3)
- .build());
- }
-
- public static QuestionRepository getInstance() {
- if (INSTANCE == null) {
- INSTANCE = new QuestionRepository();
- }
-
- return INSTANCE;
-
- }
-
-
- public ArrayList getAll() {
- return questions;
- }
-
-
-}
diff --git a/Oleksandr-JR-Example/src/main/webapp/index.jsp b/Oleksandr-JR-Example/src/main/webapp/index.jsp
deleted file mode 100644
index c38169b..0000000
--- a/Oleksandr-JR-Example/src/main/webapp/index.jsp
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Hello World!
-
-
diff --git a/Oleksandr-JR-Example/src/main/webapp/quiz.jsp b/Oleksandr-JR-Example/src/main/webapp/quiz.jsp
deleted file mode 100644
index 95a7681..0000000
--- a/Oleksandr-JR-Example/src/main/webapp/quiz.jsp
+++ /dev/null
@@ -1,31 +0,0 @@
-<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-<%@ page contentType="text/html;charset=UTF-8" %>
-
-
-
-
-
-
-
- FQ HTML
-
-
-
-
-
-
-
-
-
-<%= request.getSession().getAttribute("questions") %>
-
-
-
-
-
diff --git a/README.md b/README.md
index d8f5056..dd0326b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,37 @@
-# M3-Quest-NEW
+# QuestGame
-Do not edit this file, please create a readme file in your module
\ No newline at end of file
+## Overview
+
+QuestGame is an interactive web-based quiz game implemented as a Java web application.
+Players answer a series of questions, branching the story depending on their choices.
+
+---
+
+## Technologies Used
+
+- **Java 17** — main programming language
+- **Servlet API 4.0** — to handle HTTP requests and sessions
+- **JSP** — for server-side page rendering
+- **JUnit 5** — unit testing framework
+- **Mockito** — for mocking in tests
+- **Maven** — build and dependency management
+- **Apache Tomcat 9** — servlet container to deploy the web application
+
+---
+
+## Project Structure
+
+- `src/main/java` — Java servlet controllers and business logic
+- `src/main/webapp` — JSP pages, static resources (CSS)
+- `src/test/java` — unit tests
+- `pom.xml` — Maven configuration
+
+---
+
+## How to Build and Run
+
+### Prerequisites
+
+- Java 17 installed
+- Maven installed
+- Docker installed (optional, for containerized run)
\ No newline at end of file