diff --git a/Yaroslav/pom.xml b/Yaroslav/pom.xml new file mode 100644 index 0000000..4d91ca8 --- /dev/null +++ b/Yaroslav/pom.xml @@ -0,0 +1,57 @@ + + 4.0.0 + ua.com.javarush.gnew + Yaroslav + war + 1.0-SNAPSHOT + Yaroslav Maven Webapp + http://maven.apache.org + + + + + + + org.junit.jupiter + junit-jupiter-api + 5.9.0 + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.9.0 + + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + org.junit.jupiter + junit-jupiter + RELEASE + test + + + + + + Yaroslav + + + org.apache.maven.plugins + maven-compiler-plugin + + 9 + 9 + + + + + diff --git a/Yaroslav/src/main/java/com/game/controller/GameServlet.java b/Yaroslav/src/main/java/com/game/controller/GameServlet.java new file mode 100644 index 0000000..ccd695d --- /dev/null +++ b/Yaroslav/src/main/java/com/game/controller/GameServlet.java @@ -0,0 +1,54 @@ +package com.game.controller; + +import com.game.model.GameState; +import com.game.model.Player; +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 javax.servlet.http.HttpSession; + +import java.io.IOException; + +@WebServlet("/game") +public class GameServlet extends HttpServlet { + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession session = request.getSession(); + + Player player = (Player) session.getAttribute("player"); + if (player == null) { + String playerName = request.getParameter("playerName"); + if (playerName == null || playerName.trim().isEmpty()) { + playerName = "Player"; + } + player = new Player(playerName); + session.setAttribute("player", player); + } + + GameState gameState = (GameState) session.getAttribute("gameState"); + if (gameState == null) { + gameState = new GameState(); + session.setAttribute("gameState", gameState); + } + + if (gameState.getCurrentText().equals("You stand at a fork in the road. Where do you go? (left/right)")) { + player.incrementGamesPlayed(); + } + + String userChoice = request.getParameter("choice"); + if (userChoice != null) { + gameState.processChoice(userChoice); + } + + if (gameState.isGameOver()) { + if (gameState.getCurrentText().contains("treasure") || gameState.getCurrentText().contains("escaped")) { + player.incrementGamesWon(); + } + request.getRequestDispatcher("result.jsp").forward(request, response); + } else { + request.getRequestDispatcher("game.jsp").forward(request, response); + } + } +} \ No newline at end of file diff --git a/Yaroslav/src/main/java/com/game/model/GameState.java b/Yaroslav/src/main/java/com/game/model/GameState.java new file mode 100644 index 0000000..bbc9f4d --- /dev/null +++ b/Yaroslav/src/main/java/com/game/model/GameState.java @@ -0,0 +1,50 @@ +package com.game.model; + +public class GameState { + private final Story story; + private String currentScene; + private boolean gameOver; + + public GameState() { + this.story = new Story(); + this.currentScene = "start"; + this.gameOver = false; + } + + public void processChoice(String choice) { + Story.Scene scene = story.getScene(currentScene); + + if (scene != null) { + System.out.println("=== PROCESSING CHOICE ==="); + System.out.println("Current scene: " + currentScene); + System.out.println("Scene text: " + scene.getText()); + System.out.println("Available choices: " + scene.getChoices().keySet()); + System.out.println("Player input: '" + choice + "' (Length: " + choice.length() + ")"); + + String normalizedChoice = choice.trim().toLowerCase(); + System.out.println("After processing: '" + normalizedChoice + "' (Length: " + normalizedChoice.length() + ")"); + + if (scene.getChoices().containsKey(normalizedChoice)) { + currentScene = scene.getChoices().get(normalizedChoice); + gameOver = story.isEndScene(currentScene); + + System.out.println("Choice accepted! New scene: " + currentScene); + System.out.println("New scene text: " + story.getScene(currentScene).getText()); + System.out.println("=== END OF PROCESSING ==="); + } else { + System.out.println("Invalid choice! Try again."); + } + } else { + System.out.println("Error: Scene not found."); + } + } + + public String getCurrentText() { + Story.Scene scene = story.getScene(currentScene); + return (scene != null) ? scene.getText() : "Error loading scene."; + } + + public boolean isGameOver() { + return gameOver; + } +} \ No newline at end of file diff --git a/Yaroslav/src/main/java/com/game/model/Player.java b/Yaroslav/src/main/java/com/game/model/Player.java new file mode 100644 index 0000000..6619c93 --- /dev/null +++ b/Yaroslav/src/main/java/com/game/model/Player.java @@ -0,0 +1,35 @@ +package com.game.model; + +import java.io.Serializable; + +public class Player implements Serializable { + private String name; + private int gamesPlayed; + private int gamesWon; + + public Player(String name) { + this.name = name; + this.gamesPlayed = 0; + this.gamesWon = 0; + } + + public String getName() { + return name; + } + + public int getGamesPlayed() { + return gamesPlayed; + } + + public int getGamesWon() { + return gamesWon; + } + + public void incrementGamesPlayed() { + gamesPlayed++; + } + + public void incrementGamesWon() { + gamesWon++; + } +} \ No newline at end of file diff --git a/Yaroslav/src/main/java/com/game/model/Story.java b/Yaroslav/src/main/java/com/game/model/Story.java new file mode 100644 index 0000000..4935d0d --- /dev/null +++ b/Yaroslav/src/main/java/com/game/model/Story.java @@ -0,0 +1,54 @@ +package com.game.model; + +import java.util.HashMap; +import java.util.Map; + +public class Story { + private final Map scenes = new HashMap<>(); + + public Story() { + scenes.put("start", new Scene("You stand at a fork in the road. Where do you go? (left/right)", + Map.of("left", "left_path", "right", "right_path"))); + + scenes.put("left_path", new Scene("You found a chest. Open it? (yes/no)", + Map.of("yes", "open", "no", "ignore"))); + + scenes.put("right_path", new Scene("You met a wolf. Run away? (yes/no)", + Map.of("yes", "run", "no", "fight"))); + + scenes.put("open", new Scene("You found a treasure! (end)", Map.of())); + scenes.put("ignore", new Scene("You walked away empty-handed. (end)", Map.of())); + scenes.put("run", new Scene("You escaped safely. (end)", Map.of())); + scenes.put("fight", new Scene("The wolf was stronger... (end)", Map.of())); + } + + public Scene getScene(String sceneKey) { + return scenes.getOrDefault(sceneKey, new Scene("Error: Unknown scene", Map.of())); + } + + public boolean isEndScene(String sceneKey) { + return !scenes.getOrDefault(sceneKey, new Scene("", Map.of())).hasChoices(); + } + + public static class Scene { + private final String text; + private final Map choices; + + public Scene(String text, Map choices) { + this.text = text; + this.choices = choices; + } + + public String getText() { + return text; + } + + public Map getChoices() { + return choices; + } + + public boolean hasChoices() { + return !choices.isEmpty(); + } + } +} \ No newline at end of file diff --git a/Yaroslav/src/main/webapp/game.jsp b/Yaroslav/src/main/webapp/game.jsp new file mode 100644 index 0000000..da30a52 --- /dev/null +++ b/Yaroslav/src/main/webapp/game.jsp @@ -0,0 +1,20 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ page import="com.game.model.GameState" %> +<% + GameState gameState = (GameState) session.getAttribute("gameState"); +%> + + + Text Adventure + + + +

Text Adventure

+

<%= gameState.getCurrentText() %>

+ +
+ + +
+ + \ No newline at end of file diff --git a/Yaroslav/src/main/webapp/index.jsp b/Yaroslav/src/main/webapp/index.jsp new file mode 100644 index 0000000..dfe5d39 --- /dev/null +++ b/Yaroslav/src/main/webapp/index.jsp @@ -0,0 +1,15 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Start Game + + + +

Welcome to the Text Adventure!

+
+ + + +
+ + \ No newline at end of file diff --git a/Yaroslav/src/main/webapp/result.jsp b/Yaroslav/src/main/webapp/result.jsp new file mode 100644 index 0000000..fea0cad --- /dev/null +++ b/Yaroslav/src/main/webapp/result.jsp @@ -0,0 +1,21 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ page import="com.game.model.Player" %> +<% + Player player = (Player) session.getAttribute("player"); +%> + + + Game Over + + + +

Game Over!

+

Player Name: <%= player.getName() %>

+

Games Played: <%= player.getGamesPlayed() %>

+

Games Won: <%= player.getGamesWon() %>

+ +
+ +
+ + \ No newline at end of file diff --git a/Yaroslav/src/test/java/com/game/model/GameStateTest.java b/Yaroslav/src/test/java/com/game/model/GameStateTest.java new file mode 100644 index 0000000..5d97349 --- /dev/null +++ b/Yaroslav/src/test/java/com/game/model/GameStateTest.java @@ -0,0 +1,57 @@ +package com.game.model; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class GameStateTest { + private GameState gameState; + + @BeforeEach + void setUp() { + gameState = new GameState(); + } + + @Test + void testInitialState() { + assertEquals("You stand at a fork in the road. Where do you go? (left/right)", gameState.getCurrentText()); + assertFalse(gameState.isGameOver(), "Game should not be over at the start"); + } + + @Test + void testProcessChoice_ValidPath_Left() { + gameState.processChoice("left"); + assertEquals("You found a chest. Open it? (yes/no)", gameState.getCurrentText()); + assertFalse(gameState.isGameOver()); + } + + @Test + void testProcessChoice_ValidPath_Right() { + gameState.processChoice("right"); + assertEquals("You met a wolf. Run away? (yes/no)", gameState.getCurrentText()); + assertFalse(gameState.isGameOver()); + } + + @Test + void testProcessChoice_Ending_Open() { + gameState.processChoice("left"); + gameState.processChoice("yes"); // Opens the chest + assertEquals("You found a treasure! (end)", gameState.getCurrentText()); + assertTrue(gameState.isGameOver(), "Game should be over after finding the treasure"); + } + + @Test + void testProcessChoice_Ending_Run() { + gameState.processChoice("right"); + gameState.processChoice("yes"); // Runs away from wolf + assertEquals("You escaped safely. (end)", gameState.getCurrentText()); + assertTrue(gameState.isGameOver(), "Game should be over after escaping"); + } + + @Test + void testProcessChoice_InvalidInput() { + gameState.processChoice("unknown"); + assertEquals("You stand at a fork in the road. Where do you go? (left/right)", gameState.getCurrentText()); + assertFalse(gameState.isGameOver(), "Game should not be over after an invalid input"); + } +} \ No newline at end of file diff --git a/Yaroslav/src/test/java/com/game/model/StoryTest.java b/Yaroslav/src/test/java/com/game/model/StoryTest.java new file mode 100644 index 0000000..4513f66 --- /dev/null +++ b/Yaroslav/src/test/java/com/game/model/StoryTest.java @@ -0,0 +1,57 @@ +package com.game.model; + + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +import java.util.Map; + +class StoryTest { + private Story story; + + @BeforeEach + void setUp() { + story = new Story(); + } + + @Test + void testGetScene_ValidScene() { + Story.Scene scene = story.getScene("start"); + assertNotNull(scene, "Scene should not be null"); + assertEquals("You stand at a fork in the road. Where do you go? (left/right)", scene.getText()); + assertEquals(Map.of("left", "left_path", "right", "right_path"), scene.getChoices()); + } + + @Test + void testGetScene_InvalidScene() { + Story.Scene scene = story.getScene("invalid_key"); + assertNotNull(scene, "Scene should not be null"); + assertEquals("Error: Unknown scene", scene.getText()); + assertTrue(scene.getChoices().isEmpty(), "Unknown scene should have no choices"); + } + + @Test + void testIsEndScene_True() { + assertTrue(story.isEndScene("open"), "Scene 'open' should be an end scene"); + assertTrue(story.isEndScene("ignore"), "Scene 'ignore' should be an end scene"); + assertTrue(story.isEndScene("run"), "Scene 'run' should be an end scene"); + assertTrue(story.isEndScene("fight"), "Scene 'fight' should be an end scene"); + } + + @Test + void testIsEndScene_False() { + assertFalse(story.isEndScene("start"), "Scene 'start' should not be an end scene"); + assertFalse(story.isEndScene("left_path"), "Scene 'left_path' should not be an end scene"); + assertFalse(story.isEndScene("right_path"), "Scene 'right_path' should not be an end scene"); + } + + @Test + void testSceneChoices() { + Story.Scene scene = story.getScene("left_path"); + assertEquals(Map.of("yes", "open", "no", "ignore"), scene.getChoices()); + + scene = story.getScene("right_path"); + assertEquals(Map.of("yes", "run", "no", "fight"), scene.getChoices()); + } +} \ No newline at end of file