
Новичок
Профиль
Группа: Участник
Сообщений: 1
Регистрация: 5.2.2008
Где: Мариуполь
Репутация: нет Всего: нет
|
Учусь. Делаю игрушку "Пятнадцать", все, думаю, такую знают. Вот абсолютно рабочий код: Логика: Код | package net.kiriyenko.fifteen;
import java.util.Random; import java.util.LinkedList; import java.text.NumberFormat;
/** * @author Dmitriy * Contains the board for playing "fifteen" * @version 1.0.0.0 * */ public class Board { /** * Default constructor * Creates a new game * @see net.kiriyenko.fifteen.Board#newGame() */ public Board() { newGame(); } /** * Randomly fills the board * and sets moves and tries to zero * @see net.kiriyenko.fifteen.Board#rand() */ public void newGame() { rand(); moves = 0; tries = 0; } /** * Checks whether board is sorted i.e. game finished * @return <em>true</em> if finished, <em>false</em> if not */ public boolean isFinished() { for (int i = 0; i < SIZE-1; i++) { if (squares[i] != i+1) return false; } return true; } /** * Moves particular square if applicable * @param square square to move * @return <em>true</em> on success, <em>false</em> on failure */ public boolean move(int square) { tries++; int i = 0; for (;i < SIZE; i++) { if (squares[i] == square) break; } int r = row(i); int c = column(i); if (tryLeft(r,c) || tryUp(r,c) || tryRight(r,c) || tryDown(r,c)) { moves++; return true; } return false; } /** * Overrides super.toString() method to show the board in rectangular form * It isn't too beautiful, but it helps while testing * @return string board representation in rectangular form */ public String toString() { String str = new String(); NumberFormat nf = NumberFormat.getInstance(); nf.setMinimumIntegerDigits(2); for (int i = 0; i < SIZE; i++) { str += nf.format(squares[i]) + " "; if (i % W == W-1) str += "\n"; } return str; } /** * Shows value from cell number * @param n cell number * @return value in square */ public int squareAt(int n) { return squares[n]; } /** * Shows value from r-c (row-column) number * @param r row number * @param c column number * @return value in square */ public int squareAt(int r, int c) { return squares[cell(r,c)]; } /** * Shows the height of the board * @return height of the board */ public int getHeight() { return H; } /** * Shows the width of the board * @return width of the board */ public int getWidth() { return W; } /** * Shows the size of the board * @return size of the board */ public int getSize() { return SIZE; } /** * Shows the number of successful moves * @return number of successful moves */ public int getMoves() { return moves; } /** * Shows the number of attempts to move * @return number of attempts to move */ public int getTries() { return tries; } private final int W = 4; //width private final int H = 4; //height private final int SIZE = H*W; //board size private int[] squares = new int[SIZE]; //board cell (0=empty) private int moves = 0; //number of moves since game started private int tries = 0; //number of attempts to move since game started //returns row number from cell number private int row(int n) { return n/W; } //returns column number from cell number private int column(int n) { return n%W; } //returns cell number from row-column private int cell(int r, int c) { return r*W + c; } //initializes board with random numbers private void rand() { Random r = new Random(); LinkedList<Integer> list = new LinkedList<Integer>(); for (int i = 0; i < SIZE; i++) { list.add(i); } for (int i = 0; i < SIZE; i++) { int n = r.nextInt(SIZE-i); squares[i] = list.get(n); list.remove(n); } } //tries to move r-c cell left //if applicable does it and returns true //otherwise returns false private boolean tryLeft(int r, int c) { if (c == 0) return false; if (squares[cell(r,c-1)] == 0) { squares[cell(r,c-1)] = squares[cell(r,c)]; squares[cell(r,c)] = 0; return true; } return false; }
//tries to move r-c cell up //if applicable does it and returns true //otherwise returns false private boolean tryUp(int r, int c) { if (r == 0) return false; if (squares[cell(r-1,c)] == 0) { squares[cell(r-1,c)] = squares[cell(r,c)]; squares[cell(r,c)] = 0; return true; } return false; } //tries to move r-c cell right //if applicable does it and returns true //otherwise returns false private boolean tryRight(int r, int c) { if (c == W-1) return false; if (squares[cell(r,c+1)] == 0) { squares[cell(r,c+1)] = squares[cell(r,c)]; squares[cell(r,c)] = 0; return true; } return false; } //tries to move r-c cell down //if applicable does it and returns true //otherwise returns false private boolean tryDown(int r, int c) { if (r == H-1) return false; if (squares[cell(r+1,c)] == 0) { squares[cell(r+1,c)] = squares[cell(r,c)]; squares[cell(r,c)] = 0; return true; } return false; } }
|
Сервлет Код | package net.kiriyenko.fifteen;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import net.kiriyenko.fifteen.Board;
public class MainServlet extends HttpServlet{ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { getServletContext().getRequestDispatcher("/play.jsp").forward(req, resp); } }
|
jsp Код | <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <%@page import="net.kiriyenko.fifteen.Board"%> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Play fifteen!</title> </head> <body> <% response.setContentType("text/html;charset=windows-1251"); Board board = (Board)session.getAttribute(session.getId()); if (board == null) { board = new Board(); session.setAttribute(session.getId(), board); } String move = request.getParameter("move"); if (move != null) { board.move(Integer.parseInt(move)); } String newGame = request.getParameter("newgame"); if (Boolean.parseBoolean(newGame)) { board.newGame(); } %> <h1>Let's play!</h1> <table border> <% for (int i = 0; i < board.getHeight(); i++) { %> <tr align = "center"> <% for (int j = 0; j < board.getWidth(); j++) { %> <td height = 50 width = 50 valign = "middle"> <% if (board.squareAt(i, j) != 0) { %> <a href = <%= "play?move="+board.squareAt(i, j) %>> <h1> <%= board.squareAt(i, j) %> </h1> </a> <% } else {%> <h1> </h1> <% } %> </td> <% } %> </tr> <% } %> </table> <br/> <% if (board.isFinished()) { %> <h2> Game finished. Greetings! </h2> <a href = play?newgame=true> Start a new game </a> <% } %> <br/> <table> <tr> <td> <b> Total tries made </b> </td> <td> <%= board.getTries() %> </td> </tr> <tr> <td> <b> Total moves made </b> </td> <td> <%= board.getMoves() %> </td> </tr> </table> </body> </html>
|
web.xml Код | <!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
<web-app> <servlet> <servlet-name>MainServlet</servlet-name> <servlet-class>net.kiriyenko.fifteen.MainServlet</servlet-class> </servlet>
<servlet-mapping> <servlet-name>MainServlet</servlet-name> <url-pattern>/play</url-pattern> </servlet-mapping> </web-app>
|
build.xml (for Ant) Код | <?xml version="1.0" encoding="UTF-8"?> <!-- ====================================================================== 11.06.2008 13:35:33
Fifteen Fifteen - a game to play Dima ====================================================================== --> <project name="Fifteen" default="all"> <description> Fifteen - a game to play </description>
<property environment = "env"/> <!-- ================================= target: all ================================= --> <target name="all" depends="copy" description="Fifteen - a game to play"> </target>
<!-- - - - - - - - - - - - - - - - - - target: copy - - - - - - - - - - - - - - - - - --> <target name="copy" depends="mkdirs,compile" description="Copy files to Tomcat server"> <copy todir="${env.TOMCAT_HOME}\webapps\fifteen\WEB-INF\classes\net\kiriyenko\fifteen"> <fileset dir="bin\net\kiriyenko\fifteen"> </fileset> </copy> <copy file="xml\web.xml" todir="${env.TOMCAT_HOME}\webapps\fifteen\WEB-INF" /> <copy todir="${env.TOMCAT_HOME}\webapps\fifteen"> <fileset dir="jsp"> <include name="**\*.jsp"/> </fileset> </copy> </target>
<!-- - - - - - - - - - - - - - - - - - target: mkdirs - - - - - - - - - - - - - - - - - --> <target name="mkdirs" description="Make directories in Tomcat web apps"> <mkdir dir="${env.TOMCAT_HOME}\webapps\fifteen\WEB-INF\classes\net\kiriyenko\fifteen" /> </target>
<!-- - - - - - - - - - - - - - - - - - target: compile - - - - - - - - - - - - - - - - - --> <target name="compile" depends="getlibs" description="Compile source files"> <javac srcdir="src\net\kiriyenko\fifteen" destdir="bin" classpath="lib\servlet-api.jar" /> </target>
<!-- - - - - - - - - - - - - - - - - - target: getlibs - - - - - - - - - - - - - - - - - --> <target name="getlibs"> <copy file="${env.TOMCAT_HOME}\lib\servlet-api.jar" todir="lib" /> </target>
</project>
|
Вся эта ерунда прекрасно работает, открывал 4 окна MSIE и одну Oper'у, располагал на экране мозаикой и играл во всех одновременно. До этого jsp не было вообще, весь код был в сервлете + получение сессии - тоже всё ОК. Решил разделить и передавать Bean. Прочитав Сабурова про отдел кадров - через request. Вот так (только изменённые файлы) Сервлет: Код | package net.kiriyenko.fifteen;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import net.kiriyenko.fifteen.Board;
public class MainServlet extends HttpServlet{ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(true); resp.setContentType("text/html;charset=windows-1251"); Board board = (Board)session.getAttribute(session.getId()); if (board == null) { board = new Board(); } String move = req.getParameter("move"); if (move != null) { board.move(Integer.parseInt(move)); } String newGame = req.getParameter("newgame"); if (Boolean.parseBoolean(newGame)) { board.newGame(); } req.setAttribute("board", board); getServletContext().getRequestDispatcher("/play.jsp").forward(req, resp); session.setAttribute(session.getId(), board); } }
|
jsp Код | <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <jsp:useBean id="board" scope="request" class="net.kiriyenko.fifteen.Board"/> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Play fifteen!</title> </head> <body> <h1>Let's play!</h1> <table border> <% for (int i = 0; i < board.getHeight(); i++) { %> <tr align = "center"> <% for (int j = 0; j < board.getWidth(); j++) { %> <td height = 50 width = 50 valign = "middle"> <% if (board.squareAt(i, j) != 0) { %> <a href = <%= "play?move="+board.squareAt(i, j) %>> <h1> <%= board.squareAt(i, j) %> </h1> </a> <% } else {%> <h1> </h1> <% } %> </td> <% } %> </tr> <% } %> </table> <br/> <% if (board.isFinished()) { %> <h2> Game finished. Greetings! </h2> <a href = play?newgame=true> Start a new game </a> <% } %> <br/> <table> <tr> <td> <b> Total tries made </b> </td> <td> <%= board.getTries() %> </td> </tr> <tr> <td> <b> Total moves made </b> </td> <td> <%= board.getMoves() %> </td> </tr> </table> </body> </html>
|
И что же? Одно окно - играет нормально. Два - нормально. Три - свистопляска. "Невозможно отобразить страницу", несколько раз обновляешь - появляется, и хорошо, если своя, а иногда ещё и непонятно чья (как будто из другого окна игра). Закрываю "лишнее" окно, обновляю остальные два - появляется поле. Делаю ход - ситуация на доске меняется коренным образом (опять откуда-то "чужая" игра вылезла), далее играет нормально. Впрочем, иногда сразу играет нормально. Скажите: - Неужели, дело в производительности? То есть, передача бина - такая накладная, что сервер не справляется с тремя запросами. Откуда тогда "левые" доски?
- Как правильно делать? Что-то же я делаю не так.
- Ещё интересная штука - пробовал в сессии передавать, а не в запросе. Вот так:
Код | package net.kiriyenko.fifteen;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import net.kiriyenko.fifteen.Board;
public class MainServlet extends HttpServlet{ private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(true); resp.setContentType("text/html;charset=windows-1251"); Board board = (Board)session.getAttribute("board"); if (board == null) { board = new Board(); } String move = req.getParameter("move"); if (move != null) { board.move(Integer.parseInt(move)); } String newGame = req.getParameter("newgame"); if (Boolean.parseBoolean(newGame)) { board.newGame(); } //req.setAttribute("board", board); session.setAttribute("board", board); getServletContext().getRequestDispatcher("/play.jsp").forward(req, resp); } }
|
и в jsp при юзании бина scope="session" То же самое! =(
Всё же, как по-хорошему, по mvc-шному? Если нужно, готов выложить архив проекта или результат деплоя на Tomcat - только скажите, какой именно? Это сообщение отредактировал(а) dim.kiriyenko - 12.6.2008, 16:31
|