Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Чем три сессии настолько хуже двух? Может, в производительности дело? 
:(
    Опции темы
dim.kiriyenko
  Дата 12.6.2008, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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-шному? smile 

Если нужно, готов выложить архив проекта или результат деплоя на Tomcat - только скажите, какой именно?

Это сообщение отредактировал(а) dim.kiriyenko - 12.6.2008, 16:31
PM MAIL WWW ICQ GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0790 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.