Tuesday, February 1, 2011

Sudoku Game with JSF

This game has table containing 9 * 9 cells. There are some cells with digits between 1 to 9 and other is left with blank space. Player should guess the digit of blank cells. The game rule is the digits should be unique in table row and column and in smaller rectangle. There is a sample here:

And the answer is:


In this post we are going to make an application to solve any Sudoku table in any levels. You can enter some digits of table and application tells you the answer.
This application is based on JSF technology. Java Server Faces is a framework in presentation layer and make you some tags and server side facilities. There are some technologies on top of JSF like Rich Faces and so on. JSF lifecycle has six major phases which any requests and responses should pass them.
Phase 1: Restore View
In the first phase of the JSF lifecycle — restore view — a request comes through the FacesServlet controller. The controller examines the request and extracts the view ID, which is determined by the name of the JSP page.
The JSF framework controller uses the view ID to look up the components for the current view. If the view doesn’t already exist, the JSF controller creates it. If the view already exists, the JSF controller uses it. The view contains all the GUI components.
This phase of the lifecycle presents three view instances: new view, initial view, and postback, with each one being handled differently. In the case of a new view, JSF builds the view of the Faces page and wires the event handlers and validators to the components. The view is saved in a FacesContext object.
The FacesContext object contains all the state information JSF needs to manage the GUI component’s state for the current request in the current session. The FacesContext stores the view in its viewRoot property; viewRoot contains all the JSF components for the current view ID.
In the case of an initial view (the first time a page is loaded), JSF creates an empty view. The empty view will be populated as the user causes events to occur. From an initial view, JSF advances directly to the render response phase.
In the case of a postback (the user returns to a page she has previously accessed), the view corresponding to the page already exists, so it needs only to be restored. In this case, JSF uses the existing view’s state information to reconstruct its state. The next phase after a postback is apply request values.
Phase 2: Apply Request Values
The purpose of the apply request values phase is for each component to retrieve its current state. The components must first be retrieved or created from the FacesContext object, followed by their values. Component values are typically retrieved from the request parameters, although they can also be retrieved from cookies or headers.
If a component’s immediate event handling property is not set to true, the values are just converted. So if the field is bound to an Integer property, the value is converted to an Integer. If the value conversion fails, an error message is generated and queued in the FacesContext, where it will be displayed during the render response phase, along with any validation errors.
If a component’s immediate event handling property is set to true, the values are converted to the proper type and validated. The converted value is then stored in the component. If the value conversion or value validation fails, an error message is generated and queued in the FacesContext, where it will be displayed during the render response phase, along with any other validation errors.
Immediate event handling
The immediate event handling property of JSF is used to handle events that normally don’t necessitate validating the entire form. For example, say an employee form has a radio button denoting whether an employee is a manager. When the employee selects the Manager option, the application populates a list of perks for managers. Because the radio button is used only to populate the list and does not require the user to fill out the entire form, you do not need to validate the form in its entirety. In this case, you would use immediate event handling. See Immediate event handling for further details on this subject.
Phase 3: Process Validation
The first event handling of the lifecycle takes place after the apply request values phase. At this stage, each component will have its values validated against the application’s validation rules. The validation rules can be pre-defined (shipped with JSF) or defined by the developer. Values entered by the user are compared to the validation rules. If an entered value is invalid, an error message is added to FacesContext, and the component is marked invalid. If a component is marked invalid, JSF advances to the render response phase, which will display the current view with the validation error messages. If there are no validation errors, JSF advances to the update model values phase.
Phase 4: Update Model Values
The fourth phase of the JSF application lifecycle — update model values — updates the actual values of the server-side model — namely, by updating the properties of your backing beans (also known as managed beans). Only bean properties that are bound to a component’s value will be updated. Notice that this phase happens after validation, so you can be sure that the values copied to your bean’s properties are valid (at least at the form-field level; they may still be invalid at the business-rule level).
Phase 5: Invoke application
At the fifth phase of the lifecycle — invoke application — the JSF controller invokes the application to handle Form submissions. The component values will have been converted, validated, and applied to the model objects, so you can now use them to execute the application’s business logic.
At this phase, you also get to specify the next logical view for a given sequence or number of possible sequences. You do this by defining a specific outcome for a successful form submission and returning that outcome. For example: on successful outcome, move the user to the next page. For this navigation to work, you will have to create a mapping to the successful outcome as a navigation rule in the faces-config.xml file. Once the navigation occurs, you move to the final phase of the lifecycle.
Phase 6: Render Response
In the sixth phase of the lifecycle — render response — you display the view with all of its components in their current state.
To configure the project by JSF, you should use FacesServlet as a servlet in your project. So the web.xml is like this:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>
</web-app>
This configuration maps all URL patterns of *.jsf to FacesServlet. This servlet needs a file with “faces-config.xml” name nearby web.xml. This is JSF configuration file. You can define all your formbean classes and even map all actions which are returned from formbean to specific jsp page. Even you can define your own phase listener to track which phases of JSF are you in. A sample of faces-config.xml is:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
              version="1.2">
    <managed-bean>
        <managed-bean-name>sudokoForm</managed-bean-name>
        <managed-bean-class>com.sudoko.SudokoForm</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
</faces-config>
This JSF configuration tells that the bean class is “com.sudoko.SudokoForm”. This bean is called “sudokoForm” for use it in our pages. We can have more bean classes. I explain JSF features in detail more, in my future posts.
We have jsp in view mod. Our jsp page is a simple jsp. But if we want to have jsf tags we should define their taglibs:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://myfaces.apache.org/tomahawk" prefix="t" %>

All JSF tags should be appended to
<f:view>
</f:view>
This is the tag which is used to create component tree in restore view phase. There are several useful html tags in h, t prefix like:
1.       <h:form>
2.       <h:inputHidden>
3.       <t:div>
4.       ….
I will explain more in my future posts.
The value bindings are on this way: it looks like EL but the difference is #{} not ${}. First you should determine your form bean then any fields of it in any levels. A sample is:
<t:inputText maxlength="1" value="#{sudokoForm.digits[0][0].digit}"/>
sudokoForm is our form bean and digits is its field and so on. When your request is:
http://localhost:8080/sudoku/index.jsf
it is sent to index.jsp
To handle action events in server side you should create a method in your form bean with this prototype:
public String methodName() {}
The tag is:
<t:commandButton action="#{sudokoForm. methodName}" value="="/>
Now return to our game.
In our game we have these classes:


SudokoCell is a bean class that handles any cells of Sudoku table. It has two fields. Its value and a boolean field which determines if the cell value is set by user (as initial data of Sudoku table) or not.

SudokoForm is a form bean to handle page value and actions.
SudokoUtils is a utility class which has practical method to solve Sudoku problems. The methods are:    getRange(x, y): returns the top left position of small rectangle. For example the top left of 4, 2 is 3, 0.
  • isUnique(SudokoCell[][] cells, Integer inpx, Integer inpy, Integer input): checks if the input is unique in its whole row and column and small rectangle.
  • isSolved(SudokoCell[][] cells): checks if Sudoku table is solved or not.
  • setFix(SudokoCell[][] cells): initiates fix field of cells to true if they have had value.
SudokoService is the major class of this game. It has 3 methods:
  • solve: it is an init method. First it calls SudokoUtils.setFix to determine initial value of Sudoku table. Then it calls recSolve.
  • recSolve(SudokoCell[][] digits, Integer x, Integer y): it is a recursive method. First it checks if the current cell is fix or not. if yes it calls setNextVal method. If not it checks any 1 to 9 values in a loop for this cell. In loop first we check if this value is unique or not by SudokoUtils.isUnique method then we suppose this value and continue or solution to the next cell by calling setNextVal and if our problem is solved(we do it via SudokoUtils.isSolved method), the table should be returned if not it means that we should not assume this value for this cell and we if we do that we will have incompatibility so we should continue our loop to the next value.
  • setNextVal(SudokoCell[][] temp, Integer x, Integer y): determines the next cell which should be investigated. For example if the current is 4, 2 the next cell is 4, 3 and if the current is 4, 8 the next cell is 5, 0. Then it calls recSolve by this cell. 
You can source code from here. The start page is: http://[your host]:[your port]/sudoku/index.jsf for example: http://localhost:8080/sudoku/index.jsf.


all rights reserved by Mostafa Rastgar and prgassist weblog

3 comments:

Anonymous said...

hi buddy.great work,thank u so much.seems u r a java pro;) good luck.

Narges said...

mobarak bashe! Omidvaram ke webloget har rooz por bar tar az dirooz bashe! Hamisheh to ro tahsin kardam va har movafaghiyate to baaese eftekhare mane! Pas hatman be neveshtan edameh bede!

omidp said...

Hi,
I really like sudoku, i heard it's usefull for improving intelligence and i've played sudoku from now on with your program
MOVE ON DUDE