diff --git a/pom.xml b/pom.xml
index cb226e88..14b962dc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,27 +6,53 @@
com.javarush
tic-tac-toe
- 1.0
+ 1.0-SNAPSHOT
tic-tac-toe
war
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 3.2.2
+ pom
+ import
+
+
+
+
UTF-8
- 18
- 18
+ 21
+ 21
+ 5.9.2
- javax.servlet
- javax.servlet-api
- 4.0.1
+ jakarta.servlet
+ jakarta.servlet-api
provided
- javax.servlet
- jstl
- 1.2
+ jakarta.servlet.jsp.jstl
+ jakarta.servlet.jsp.jstl-api
+
+
+ org.glassfish.web
+ jakarta.servlet.jsp.jstl
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
diff --git a/src/main/java/com/tictactoe/InitServlet.java b/src/main/java/com/tictactoe/InitServlet.java
new file mode 100644
index 00000000..fbcc8e7a
--- /dev/null
+++ b/src/main/java/com/tictactoe/InitServlet.java
@@ -0,0 +1,27 @@
+package com.tictactoe;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+
+import java.io.IOException;
+import java.util.List;
+
+@WebServlet(name = "InitServlet", value = "/start")
+public class InitServlet extends HttpServlet {
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ HttpSession currentSession = req.getSession(true);
+ Field field = new Field();
+
+ List data = field.getFieldData();
+
+ currentSession.setAttribute("field", field);
+ currentSession.setAttribute("data", data);
+
+ getServletContext().getRequestDispatcher("/index.jsp").forward(req, resp);
+ }
+}
diff --git a/src/main/java/com/tictactoe/LogicServlet.java b/src/main/java/com/tictactoe/LogicServlet.java
new file mode 100644
index 00000000..494eeda8
--- /dev/null
+++ b/src/main/java/com/tictactoe/LogicServlet.java
@@ -0,0 +1,81 @@
+package com.tictactoe;
+
+import jakarta.servlet.RequestDispatcher;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+
+import java.io.IOException;
+import java.util.List;
+
+@WebServlet(name = "LogicServlet", value = "/logic")
+public class LogicServlet extends HttpServlet {
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
+ HttpSession currentSession = req.getSession();
+ int index = getSelectedIndex(req);
+ Field field = extractSession(currentSession);
+
+ Sign sign = field.getFieldData().get(index);
+ if (sign != Sign.EMPTY){
+ RequestDispatcher requestDispatcher = getServletContext().getRequestDispatcher("/index.jsp");
+ requestDispatcher.forward(req,resp);
+ return;
+ }
+ field.getField().put(index, Sign.CROSS);
+ if (checkWin(resp, currentSession, field)){
+ return;
+ }
+
+ int emptyFieldIndex = field.getEmptyFieldIndex();
+ if (emptyFieldIndex >= 0){
+ field.getField().put(emptyFieldIndex,Sign.NOUGHT);
+ if (checkWin(resp, currentSession, field)){
+ return;
+ }
+ }else{
+ currentSession.setAttribute("draw", true);
+ List data = field.getFieldData();
+ currentSession.setAttribute("data", data);
+ resp.sendRedirect("/index.jsp");
+ return;
+ }
+
+ List data = field.getFieldData();
+
+ currentSession.setAttribute("data", data);
+ currentSession.setAttribute("field", field);
+
+ resp.sendRedirect("index.jsp");
+ }
+
+ private Field extractSession(HttpSession currentSession) {
+ Object field = currentSession.getAttribute("field");
+ if (field.getClass() != Field.class){
+ currentSession.invalidate();
+ throw new RuntimeException("Session is broken, try one more time");
+ }
+ return (Field) field;
+ }
+
+ private int getSelectedIndex(HttpServletRequest req) {
+ String click = req.getParameter("click");
+ boolean isNumeric = click.chars().allMatch(Character::isDigit);
+ return isNumeric ? Integer.parseInt(click) : 0;
+ }
+
+ private boolean checkWin(HttpServletResponse response, HttpSession currentSession, Field field) throws IOException {
+ Sign winner = field.checkWin();
+ if (winner == Sign.CROSS || winner == Sign.NOUGHT){
+ currentSession.setAttribute("winner", winner);
+ List data = field.getFieldData();
+ currentSession.setAttribute("data", data);
+ response.sendRedirect("/index.jsp");
+ return true;
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/tictactoe/RestartServlet.java b/src/main/java/com/tictactoe/RestartServlet.java
new file mode 100644
index 00000000..9a008456
--- /dev/null
+++ b/src/main/java/com/tictactoe/RestartServlet.java
@@ -0,0 +1,17 @@
+package com.tictactoe;
+
+import jakarta.servlet.annotation.WebServlet;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import java.io.IOException;
+
+@WebServlet(name = "RestartServlet", value = "/restart")
+public class RestartServlet extends HttpServlet {
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ req.getSession().invalidate();
+ resp.sendRedirect("/start");
+ }
+}
diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp
index 964cc071..78469eb4 100644
--- a/src/main/webapp/index.jsp
+++ b/src/main/webapp/index.jsp
@@ -1,15 +1,66 @@
+<%@ page import="com.tictactoe.Sign" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-
+<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
+ ">
+
Tic-Tac-Toe
Tic-Tac-Toe
+
+
+ | ${data.get(0).getSign()} |
+ ${data.get(1).getSign()} |
+ ${data.get(2).getSign()} |
+
+
+ | ${data.get(3).getSign()} |
+ ${data.get(4).getSign()} |
+ ${data.get(5).getSign()} |
+
+
+ | ${data.get(6).getSign()} |
+ ${data.get(7).getSign()} |
+ ${data.get(8).getSign()} |
+
+
+
+
+
+
+
+
+ CROSSES CHEMPION
+
+
+
+
+ NOGHTS CHEMPION
+
+
+
+
+ It's draw
+
+
+
diff --git a/src/main/webapp/static/main.css b/src/main/webapp/static/main.css
index e69de29b..86156554 100644
--- a/src/main/webapp/static/main.css
+++ b/src/main/webapp/static/main.css
@@ -0,0 +1,11 @@
+td {
+ border: 3px solid #0b27dc;
+ padding: 10px;
+ border-collapse: separate;
+ margin: 10px;
+ width: 100px;
+ height: 100px;
+ font-size: 50px;
+ text-align: center;
+ empty-cells: show;
+}
\ No newline at end of file