TcpJLib
 
 

 

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.

Reality:

tictactoe4

Software:

tictactoe5

tictactoe6

 

 

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(3380Color.blue, nullfalse);
    setBgColor(Color.lightGray);
    addStatusBar(50);
    show();
  }

  protected void clear()
  {
    removeAllActors();
    refresh();
  }
}

tictactoe7

(continued in Tutorial 3)