An Internet-based Tic-Tac-Toe: Lesson 2
3 Games using a Game Server
In many multi-user game scenarios especially when more than two players are involved, the logical complexity is reduced by adding a supervising application called game server. The game server has mainly the following duties:
- Managing the entry and exit of players in the game room
- Initializing the game state (initial condition of the game board, distibution of cards, etc.)
- Supervising the game rules, rejecting bad moves
- Transmitting move information to players
- Deciding how has the next move
- Checking if the game is over
- Distributing scores and results
In a game client/server architecture there is no direct link between the players. Players send information (data, commands) to the server and receive information from the server. Despite for the simple Tic-Tac-Toe it's somewhat an overkill to use a game server, it's worth the effort because we extend our knowledge to more complicated game scenarios.
We start modeling the reality by object-oriented design principles. Every real object of importance has a corresponding instance of a Java class. In our game the real objects are the players with their game board and the game server. The corresponding Java classes are: Player, Board, TicTacToeServer.
4 The Communication Protocol
From the technical viewpoint, the players and the game server use an internal TcpNode that connects to the TcpRelay that encapsulates the communication details. From the logical viewpoint, data are directly exchanged between the player and the game server nodes. Like in every client-server architecture the participants have to agree upon a common communication protocol. Because the players use a TcpAgent and the server a TcpBridge instance, data is echanged using integer arrays. We decide that the first array element is a coded description (a "command tag") of the message to be transferred. For a better readability of the code, we enumerate the commands using meaningful constant names. Defining the commands is an iterative process during the game development, commands are added, removed or renamed during the whole application development. We finally use the following commands:
interface Command
{
int IN_PROGRESS = 0;
int TEAMMATE_QUIT = 1;
int TEAMMATE_WAIT = 2;
int START_FIRST = 3;
int START_SECOND = 4;
int MOVE = 5;
int WON = 6;
int LOST = 7;
int TIE = 8;
int RESTART = 9;
int MARK_X = 10;
int MARK_O = 11;
}
Their meaning is explained in the table below (in brackets the data flow):
Command |
Meaning |
IN_PROGRESS |
[server->player] when the player tries to enter a game room while a game is in progress |
TEAMMATE_QUIT |
[server->player] when the teammate terminates the application |
TEAMMATE_WAIT |
[server->player] when the player is the first player entering the game room |
START_FIRST |
[server->player] to notify the game start and ask the player to make the first move |
START_SECOND |
[server->player] to notify the game start and ask the player to wait for the teammate move |
MOVE |
[player->server] to notify the move along with the location of the mark
[server->player] to inform the teammate about the move
|
WON |
[server->player] to notify the game is over and he is the winner |
LOST |
[server->player] to notify the game is over and he is the loser |
TIE |
[server->player] to notify the game is over and it is a draw |
RESTART |
[player->server] when the player requests a new game after the game is over
|
MARK_X |
[server->player] to inform the player to use the 'X' mark |
MARK_0 |
[server->player] to inform the player to use the 'O' mark |
5 The Mark and Guide Classes
Unlike in TicTacToeLight we only use one class for the X and O mark and distinguish the marks by a constructor parameter. We add the Guide class to show temporary marks (with a pale color) when the mouse passes over empty cells before the player clicks for his conclusive choice.
// Mark.java
import ch.aplu.jgamegrid.*;
public class Mark extends Actor
{
public Mark(char sign)
{
super(sign == 'X' ? "sprites/mark_X.gif" : "sprites/mark_O.gif");
}
}
// Guide.java
import ch.aplu.jgamegrid.*;
public class Guide extends Actor
{
public Guide(char sign)
{
super(sign == 'X' ? "sprites/guide_X.gif" : "sprites/guide_O.gif");
}
} |
6 The Board Class
Like in TicTacToeLight we use a GameGrid with 3 x 3 cells (each 80 pixels wide), blue grid lines, no background image and no navigation bar. The game status is shown in a attached status bar, where two lines of text are displayed. The method clear() removes all actors and refreshes the game grid. Refreshing is necessary because we don't start the simulation loop (no doRun()).
// Board.java
import ch.aplu.jgamegrid.*;
import java.awt.Color;
public class Board extends GameGrid
{
public Board()
{
super(3, 3, 80, Color.blue, null, false);
setBgColor(Color.lightGray);
addStatusBar(50);
show();
}
protected void clear()
{
removeAllActors();
refresh();
}
}
|
|
|
(continued in Tutorial 3)
|