diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..13566b81 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 00000000..aa00ffab --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..f3e06697 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..b16964c9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/sonarlint/issuestore/index.pb b/.idea/sonarlint/issuestore/index.pb new file mode 100644 index 00000000..e69de29b diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..35eb1ddf --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/tictactoe/InitServlet.java b/src/main/java/com/tictactoe/InitServlet.java new file mode 100644 index 00000000..9ee7757b --- /dev/null +++ b/src/main/java/com/tictactoe/InitServlet.java @@ -0,0 +1,22 @@ +package com.tictactoe; + +import javax.servlet.*; +import javax.servlet.http.*; +import javax.servlet.annotation.*; +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 request, HttpServletResponse response) throws ServletException, IOException { + HttpSession currentSession = request.getSession(true); + Field field = new Field(); + Map fieldData = field.getField(); + List data = field.getFieldData(); + currentSession.setAttribute("field", field); + currentSession.setAttribute("data", data); + getServletContext().getRequestDispatcher("/index.jsp").forward(request, response); + } +} diff --git a/src/main/java/com/tictactoe/LogicServlet.java b/src/main/java/com/tictactoe/LogicServlet.java new file mode 100644 index 00000000..559996f1 --- /dev/null +++ b/src/main/java/com/tictactoe/LogicServlet.java @@ -0,0 +1,72 @@ +package com.tictactoe; + +import javax.servlet.*; +import javax.servlet.http.*; +import javax.servlet.annotation.*; +import java.io.IOException; +import java.util.List; + +@WebServlet(name = "LogicServlet", value = "/logic") +public class LogicServlet extends HttpServlet { + + 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; + } + + 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; + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + HttpSession currentSession = request.getSession(); + Field field = extractField(currentSession); + int index = getSelectedIndex(request); + Sign currentSign = field.getField().get(index); + if (Sign.EMPTY != currentSign) { + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp"); + dispatcher.forward(request, response); + return; + } + field.getField().put(index, Sign.CROSS); + if (checkWin(response, currentSession, field)) { + return; + } + int emptyFieldIndex = field.getEmptyFieldIndex(); + if (emptyFieldIndex >= 0) { + field.getField().put(emptyFieldIndex, Sign.NOUGHT); + if (checkWin(response, currentSession, field)) { + return; + } + } else { + currentSession.setAttribute("draw", true); + List data = field.getFieldData(); + currentSession.setAttribute("data", data); + response.sendRedirect("/index.jsp"); + return; + } + List data = field.getFieldData(); + currentSession.setAttribute("data", data); + currentSession.setAttribute("field", field); + response.sendRedirect("/index.jsp"); + } +} diff --git a/src/main/java/com/tictactoe/RestartServlet.java b/src/main/java/com/tictactoe/RestartServlet.java new file mode 100644 index 00000000..d875a2bb --- /dev/null +++ b/src/main/java/com/tictactoe/RestartServlet.java @@ -0,0 +1,15 @@ +package com.tictactoe; + +import javax.servlet.*; +import javax.servlet.http.*; +import javax.servlet.annotation.*; +import java.io.IOException; + +@WebServlet(name = "RestartServlet", value = "/restart") +public class RestartServlet extends HttpServlet { + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + request.getSession().invalidate(); + response.sendRedirect("/start"); + } +} diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 964cc071..348d3225 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -1,16 +1,63 @@ +<%@ 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..b2debc92 100644 --- a/src/main/webapp/static/main.css +++ b/src/main/webapp/static/main.css @@ -0,0 +1,11 @@ +td { + border: 3px solid black; + padding: 10px; + border-collapse: separate; + margin: 10px; + width: 100px; + height: 100px; + font-size: 50px; + text-align: center; + empty-cells: show; +}