This is an application created as an exercise in using CSS to control the look and feel of iPhone applications.
Note that the CSS was written for old iPhone models with 320x480 screens. Adoption to diffrent screen dimensions will require rewriting the project's theme.css file. Currently, the app uses only part of the smart phone's screen.
Its model was created to match a relatively straightforward design (see below), but as a result its performance is a bit problematic. A real life backgammon application should include some additional shortcuts to improve performance.
The "Game Model" is a data structure Game representing the game's status. While it is closely related to its representation on the screen, it is GUI independent (for the GUI implementation, see the Game View section below).
This is what we do when a new game is started:
The application is designed for an iPhone device is landscape mode (height 320 pixels, width 480 pixels).
Board contains an Init process that initializes the CSS styles of the 24 points in the board (but not yet the game model, which is initialized each time the new Game button is pressed):
Similarly, points 0 and 25 are initialized by Init processes within Top Out and Bottom Out respectively:
For the usage of style classes to customize the look and feel of the application, see the "CSS Customization" section below.
The New Game button contains two processes - Create New Game (initializing the game model) and Redraw Game (displaying the current game status on screen).
Create New Game simply initializes the Game data structure as described in the Game Initialization section above.
Redraw Game is a reusable process to update the display on screen whenever a change is made. It creates the display of the control row (by calling Redraw Contol Row), the 26 board points (by calling Redraw Point If Changed 26 times), and the dice (by calling Redraw Dice).
The redrawing processes use several reusable models:
Get Point Data - Returns the current status of a point.
In Turn? - Returns the status of the current turn: Before Move - the player should select the source point for the next move; In Move - the player should select the target point after already selecting the source point; or No - no die result is left.
Create Pawn - Creates the display of a white or a black pawn.
Set Point Style - Changes the display of a point according to its role in the current move - surrounded by a yellow line if selected as the source point of the move, by a turquoise line if selected as the target point, or with no line if not involved in the current move.
As explained above, rolling the dice is the first action in each turn.
Roll Dice starts with In Turn? (described above). Only if it returns No, the rest of the processes are executed (this is an extra check, because the Roll Dice button appears only when a new game starts or after the end of a previous turn).
We the perform Get Die Results, which creates two random number between 1 and 6, and if they are equal, duplicates them (e.g. 3-3 will become 3-3-3-3).
We then perform Redraw Game, which will display the images of the dice results (2 or 4 dice).
Roll Dice concludes with Switch Player If No Possible Move. This is important for the (rare) case where there is no possible move for the player given the dice rolled. In this case, the turn passes to the other player. Switch Player If No Possible Move also uses Redraw Game, which displays in the control row the color of the player whose tuen it is to play now (a white pawn indicating it is the white's turn, a black pawn indicating it is the black's).
By clicking a point the user selects it as the source of a move or the target of each move.
The <On Click> process within the Point model starts with In Turn?. If it returns Before Move, we invoke Immediate Marking as Source (surrounding the clicked point by a yellow line) and then Set Source If Legal (if the selected point is a legal source given the dice results, setting it as the source of the current move and setting all possible target points accordingly). If In Turn? returns In Move, we invoke Make Move if Legal (if the selected point is one of the possible target points, making the move).
Immediate Marking as Source does not check whether the clicked point is a legal source, and it doesn't even verify the point has pawns of the current player. Its purpose is only to give an immediate feedback to the user that the click was detected. This is also the reason why Set Source If Legal is implemented as a Background Action - we want to immediately see the marking made by Immediate Marking as Source, without waiting for Set Source If Legal to finish its calculations.
Make Move if Legal implements the process described in the "Making a Move" section above. It starts with a special treatment of "eating" a pawn of the opponent, and then continues with the regular process of moving one of the player's pawns. Both processes reuse two basic actions Reduce Pawn (decreasing by 1 the number of pawns in a point) and Add Pawn (increasing by 1 the number of pawns in a point). Make Move if Legal concludes with Recalculate & Refresh, which calculates the new states of each of the payers, redraws the game, and invokes Switch Player If No Possible Move.
Note that the Recalculate State action (used by Recalculate & Refresh) is also responsible for announcing victory. When a player's state is changed to 'Victory', we also add to the control row a message announcing the victory.
The way this area is split, as well as the look and feel of each GUI component, are controlled through CSS. We define a style class for each GUI component we need, and set the display models in the application to use them in one of two ways:
Here is the project's CSS file (web/theme.css), including comments:
/** The whole screen (320x480 pixels) **/.backgammon /** Used by "<iPhone View>/Body" **/{margin:3px;background:transparent url(bg.png) repeat scroll; /** Brown wood-like image, 320x480 pixels **/height:314px; /** As we have a margin of 3 pixels, we are left with net height 314 **/width:474px; /** As we have a margin of 3 pixels, we are left with net width 474 **/}/** The board itself **/.backgammon_board /** Used by "<iPhone View>/Body/Board" **/{margin-top:6px;height:264px;}/** The control row above the board itself **/.game_control_row /** Used by "<iPhone View>/Body/Control Row" **/{display:inline;}/** A container for a single pawn to indicate the color of the current player **/.player_indication /** Used by "<iPhone View>/Body/Control Row/Player" **/{margin-right:11px;vertical-align:top;margin-top:4px;display:inline-block;}/** A status message (e.g. victory announcement) **/.message /** Used by "<iPhone View>/Body/Control Row/Message" **/{color:White;font-size: 14px;vertical-align:middle;}/** Each of the "out" areas at the leftmost part of the board **/.out_area /** Used by Used by "<iPhone View>/Body/Board/Top/Top Out" and "<iPhone View>/Body/Board/Bottom/Bottom Out" **/{height:102px; /** Same height as "quarter" (see below) **/display:inline-block;}/** Point 0 - the black's "out" point (inside the top out area) **/.out_top /** Used by "<iPhone View>/Body/Board/Top/Top Out/Point 0" **/{background:transparent url(Points/brown-rectangle-up.png) no-repeat scroll;height:102px; /** The full height of "out_area" **/width:40px;display:inline-block;position:relative;padding-left:3px;}/** Point 25 - the white's "out" point (inside the bottom out area) **/.out_bottom /** Used by "<iPhone View>/Body/Board/Bottom/Bottom Out/Point 25" **/{background:transparent url(Points/brown-rectangle-down.png) no-repeat scroll;height:102px; /** The full height of "out_area" **/width:40px;display:inline-block;position:relative;padding-left:3px;}/** A quarter of the board (6 consecutive points) **/.quarter /** Used by each of the "Top Left", "Top Right", "Bottom Left" and "Bottom Right" panes **/{height:102px;display:inline-block;margin-left:22px; /** Separation between "out" area and first 6 points, and between first 6 point and next 6 points **/ }/** Container for dice images (a horizontal area between the top half of the board and the bottom half of the board) **/.dice_pane /** Used by "<iPhone View>/Body/Board/Dice" **/{height:60px;margin-left:auto;margin-right:auto;display:table;}/** A single die image **/.die /** Used by "<iPhone View>/Body/Board/Dice/Die" **/{width:50px;margin-top:5px;}/** A point at the top half of the board whose background is a white triangle **/.white_triangle_pointing_down /** Used by top points with even numbers */{background:transparent url(Points/white.png) no-repeat scroll;height:100px;width:32px;display:inline-block;position:relative;}/** A point at the top half of the board whose background is a brown triangle **/.brown_triangle_pointing_down /** Used by top points with odd numbers */{background:transparent url(Points/brown.png) no-repeat scroll;height:100px;width:32px;display:inline-block;position:relative;}/** A point at the bottom half of the board whose background is a white triangle **/.white_triangle /** Used by bottom points with even numbers */{background:transparent url(Points/white-up.png) no-repeat scroll;height:100px;width:32px;display:inline-block;position:relative;}/** A point at the bottom half of the board whose background is a brown triangle **/.brown_triangle /** Used by bottom points with odd numbers */{background:transparent url(Points/brown-up.png) no-repeat scroll;height:100px;width:32px;display:inline-block;position:relative;}/** Container for pawn images in a top point **/.pawn_container /** Used by "Pawns" within top points **/{position:absolute;top:0px;}/** Container for pawn images in a bottom point **/.pawn_container_growing_up /** Used by "Pawns" within bottom points **/{position:absolute;display:inline-block;bottom:0px;}/** A single pawn image **/.pawn /** Use by "Point" for points 1 through 24 **/{display:block;margin-left:6px;}
Note: In addition to setting an element's style class, we have one place where CSS style is dynamically changed by setting the value of the <Style> sub-element of a display element (see the model Set Point Style).
If you want to modify the styles used by the application, you can directly edit the web/theme.css file, or alternatively use the Theme Editor tool.
The Theme Editor includes a real time preview of the influence on your application of any change you make, so it is very useful when you want to make a change and immediately see its effect.
Launch the Theme Editor from the main menu of the Tersus Studio, and select iPhone Mode. You get a preview of the application in its initial state. You can now switch between Edit and View modes:
Edit - When you click a GUI element, you see its details and can edit them.
View - The application is executed regularly. You can use the application till you get to an interesting view and then switch to Edit mode when you want to change the application's look and feel.
To better understand these two modes, see the detailed documentation of the Theme Editor.
Here is a how the Theme Editor looks like after playing a little (in View mode), switching back to Edit mode, and clicking a pwan:
We use images as the background of display elements and to present "objects" (dice, pawns).
All Images are saved in the web folder of the project:
Currently the dice are rolled by clicking the Role Dice button. This is useful both when using the application from the desktop and when using it from an iPhone device.
A possible extension of the application can be to use the iPhone's accelerometer to roll the dice - the user shakes the device, which starts the rolling, and when the shaking stops, the dice results are displayed to the user. This will be available, of course, only for a native iPhone application.
See the Watch Accelerometer action in the iPhone section of the palette (version 1.3.59). To respond to shaking, create <On Shake> actions.
Currently the application is built for a single client - both the white and the black play from the same computer or iPhone device.
A possible extension of the application can be to manage the game status in a server, where each player plays from a different compute/device. When it is the turn of the white to play, the black in "wait mode" (cannot roll the dice or make a move), and when it is the turn of the black to play, the white in "wait mode".
Note that the initial implementation of the application takes this extension into account by separating the game model (the Game data structure) from the game's GUI:
To use the full functionality of this web site, JavaScript needs to be turned on.
For best results, use the Firefox browser..
Copyright © 2003-2017 - Tersus Software Ltd., All rights reserved. Terms of Use License Graphic design by EmaraDesign