From 5cc362add035526a294ef826fe4125c2a1ce9921 Mon Sep 17 00:00:00 2001 From: Vadim_dubovskiy Date: Fri, 1 Mar 2024 19:18:40 +0300 Subject: [PATCH 1/2] Project on topic: JSP and servlets --- pom.xml | 8 + src/main/java/com/tictactoe/InitServlet.java | 35 ++++ src/main/webapp/index.jsp | 52 +++++- src/main/webapp/static/main.css | 180 +++++++++++++++++++ 4 files changed, 272 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/tictactoe/InitServlet.java diff --git a/pom.xml b/pom.xml index cb226e88..1366b4c8 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,14 @@ tic-tac-toe war + + + Vadim Dubovskiy + Vadim_milo.net@mail.ru + https://github.com/Vadim23232323?tab=repositories + + + UTF-8 18 diff --git a/src/main/java/com/tictactoe/InitServlet.java b/src/main/java/com/tictactoe/InitServlet.java new file mode 100644 index 00000000..34c7d614 --- /dev/null +++ b/src/main/java/com/tictactoe/InitServlet.java @@ -0,0 +1,35 @@ +package com.tictactoe; + +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; +import java.util.List; +import java.util.Map; + +@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(); + Map fieldData = field.getField(); + + // Получение списка значений поля + List data = field.getFieldData(); + + // Добавление в сессию параметров поля (нужно будет для хранения состояния между запросами) + currentSession.setAttribute("field", field); + // и значений поля, отсортированных по индексу (нужно для отрисовки крестиков и ноликов) + currentSession.setAttribute("data", data); + + // Перенаправление запроса на страницу index.jsp через сервер + getServletContext().getRequestDispatcher("/index.jsp").forward(req, resp); + } +} \ No newline at end of file diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 964cc071..48ac1e0f 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -1,16 +1,62 @@ +<%@ page import="com.tictactoe.Sign" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> - +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + + 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 WIN!

+ +
+ +

NOUGHTS WIN!

+ +
+ +

IT'S A DRAW

+
+ +
+
diff --git a/src/main/webapp/static/main.css b/src/main/webapp/static/main.css index e69de29b..4ea58a46 100644 --- a/src/main/webapp/static/main.css +++ b/src/main/webapp/static/main.css @@ -0,0 +1,180 @@ +body { + background-color: #383838; +} + +h1 { + font-family: "Arial Black"; + color: white; + +} + +table { + + margin-left: auto; + margin-right: auto; + background-color: #ec6b14; + border-radius: 14px; + border-collapse: collapse; + +} + + + +td { + font-family: "Arial Black"; + color: white; + border-spacing: 40px; + border: 5px solid #383838; + padding: 14px; + margin: 14px; + width: 150px; + height: 150px; + font-size: 50px; + text-align: center; + empty-cells: show; +} + +tr:first-child td { + border-top: none; +} + +tr:last-child td { + border-bottom: none; +} + +tr td:first-child { + border-left: none; +} + +tr td:last-child { + border-right: none; +} + + +.bottom-fixed { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + padding: 20px; + text-align: center; +} + +.btn-new { + text-align: center; + font-family: "Arial Black"; + border: none; + padding: 12px 18px; + transition: 0.5s; + font-size: 30px; + background-size: 300% auto; + color: white; + border-radius: 6px; + background-image: linear-gradient(to right, #003CC5 0%, #0B63F6 51%, #003CC5 100%); + opacity: 0; + animation: fadeInAnimation 1s ease-in forwards; +} + +@keyframes fadeInAnimation { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.btn-new:hover { + background-position: right center; +} + +body { + background-color: #383838; +} + +h1 { + font-family: "Arial Black"; + color: white; + +} + +table { + + margin-left: auto; + margin-right: auto; + background-color: #ec6b14; + border-radius: 14px; + border-collapse: collapse; + +} + + + +td { + font-family: "Arial Black"; + color: white; + border-spacing: 40px; + border: 5px solid #383838; + padding: 14px; + margin: 14px; + width: 150px; + height: 150px; + font-size: 50px; + text-align: center; + empty-cells: show; +} + +tr:first-child td { + border-top: none; +} + +tr:last-child td { + border-bottom: none; +} + +tr td:first-child { + border-left: none; +} + +tr td:last-child { + border-right: none; +} + + +.bottom-fixed { + position: fixed; + bottom: 0; + left: 0; + width: 100%; + padding: 20px; + text-align: center; +} + +.btn-new { + text-align: center; + font-family: "Arial Black"; + border: none; + padding: 12px 18px; + transition: 0.5s; + font-size: 30px; + background-size: 300% auto; + color: white; + border-radius: 6px; + background-image: linear-gradient(to right, #003CC5 0%, #0B63F6 51%, #003CC5 100%); + opacity: 0; + animation: fadeInAnimation 1s ease-in forwards; +} + +@keyframes fadeInAnimation { + from { + opacity: 0; + } + to { + opacity: 1; + } +} + +.btn-new:hover { + background-position: right center; +} + From 43ece36950113ef868547510099ed18d95a30b23 Mon Sep 17 00:00:00 2001 From: Vadim_dubovskiy Date: Fri, 1 Mar 2024 19:21:23 +0300 Subject: [PATCH 2/2] Project on topic: JSP and servlets --- src/main/java/com/tictactoe/LogicServlet.java | 121 ++++++++++++++++++ .../java/com/tictactoe/RestartServlet.java | 16 +++ 2 files changed, 137 insertions(+) create mode 100644 src/main/java/com/tictactoe/LogicServlet.java create mode 100644 src/main/java/com/tictactoe/RestartServlet.java diff --git a/src/main/java/com/tictactoe/LogicServlet.java b/src/main/java/com/tictactoe/LogicServlet.java new file mode 100644 index 00000000..0687fbe5 --- /dev/null +++ b/src/main/java/com/tictactoe/LogicServlet.java @@ -0,0 +1,121 @@ +package com.tictactoe; + +import javax.servlet.RequestDispatcher; +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; +import java.util.List; + + +@WebServlet(name = "LogicServlet", value = "/logic") +public class LogicServlet extends HttpServlet { + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + // Получаем текущую сессию + HttpSession currentSession = req.getSession(); + + // Получаем объект игрового поля из сессии + Field field = extractField(currentSession); + + // получаем индекс ячейки, по которой произошел клик + int index = getSelectedIndex(req); + Sign currentSign = field.getField().get(index); + + // Проверяем, что ячейка, по которой был клик пустая. + // Иначе ничего не делаем и отправляем пользователя на ту же страницу без изменений + // параметров в сессии + if (Sign.EMPTY != currentSign) { + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp"); + dispatcher.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 int getSelectedIndex(HttpServletRequest request) { + String click = request.getParameter("click"); + boolean isNumeric = click.chars().allMatch(Character::isDigit); + return isNumeric ? Integer.parseInt(click) : 0; + } + + private Field extractField(HttpSession currentSession) { + Object fieldAttribute = currentSession.getAttribute("field"); + if (Field.class != fieldAttribute.getClass()) { + currentSession.invalidate(); + throw new RuntimeException("Session is broken, try one more time"); + } + return (Field) fieldAttribute; + } + + /** + * Метод проверяет, нет ли трех крестиков/ноликов в ряд. + * Возвращает true/false + */ + private boolean checkWin(HttpServletResponse response, HttpSession currentSession, Field field) throws IOException { + Sign winner = field.checkWin(); + if (Sign.CROSS == winner || Sign.NOUGHT == winner) { + // Добавляем флаг, который показывает что кто-то победил + 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..3ebfb6fe --- /dev/null +++ b/src/main/java/com/tictactoe/RestartServlet.java @@ -0,0 +1,16 @@ +package com.tictactoe; + +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.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"); + } +} \ No newline at end of file