Welcome to Tic-Tac-Toe over Sockets
Introduction
Main purpose of this porting is to demonstrate the communication between Symbian and Windows Phone devices using sockets. The application logic is implemented with Qt/C++, and the user interface is done using Qt Quick and Qt Quick components. Besides the socket communication, this project also demonstrates UI and game logic separation, utilization of C++ models in QML, and exposing enumerations, defined in C++ classes, to QML.
Additionally, the application can act both as a server and a client in the context of communication. It also demonstrates a simple discovery mechanism where the server broadcasts its IP in WLAN network and the game clients can listen to the broadcast to automatically connect to the server.
More information about differences between the Qt and WP samples can be found here.
Design and Implementation
The application is designed so that it can be used as a reference for multi-player games. The user interface is implemented in QML, and the game logic and communication is implemented in Qt/C++. The game engine and the game model are made available to QML UI by setting it to the context of QDeclarativeView. The UI uses it to start a new game, monitor game states and determine the winner when the game is over. The game engine also handles communication related to the game, using TicTacServer and TicTacClient classes.
User Interface

UI Wireframe. Click the image to view it in the original size.
The legend for the wireframe image above:
- Text element as a header, "Tic-Tac-Toe"
- Determinate progress indicator, shows the remaining time for the application to load (not implemented)
- Back button to exit the application
- Determinate progress indicator, shows the remaining time for the application to keep seeking an opponent
- Unread-item indication with 4 different colors:
- white: searching for opponent, you win, you lose, draw
- green: your turn
- yellow: opponent's turn
- red: no opponent found
- Status text, 6 different phrases:
- Searching for opponent
- No opponent found
- Your turn
- Opponent's turn
- You win
- You lose
- Draw
- 3x3 grid
- Back button, exits the appliation
- Refresh button (icon) stops the game, resets the game, arbitrary selection of which player is "X" and which is "O"
- Information button (icon), opens the info page
- "X" icon, appears after the "X" player has tapped one of the fields in the grid. The last touch area (e.g. after a pan gesture) defines the field; the winning line of icons turns green (winner) or red (loser), in case one player manages to place 3 of his/her icons in one row/column/diagonal
- "O" icon, same behavior but for the "O" player as described in 11
- Player description, 2 phrases:
- Your mark is "O"
- Your mark is "X"
- Text element as header "Tic-Tac-Toe information"
- Info page content
- Back button, moves to previous view
Application Engine
TicTacEngine is the main class which owns the game data and handles logic and communication. It owns the GameModel class instance which represents game data (Tic-Tac-Toe marks) and is inherited from QAbstractListModel. Such models can be used directly in various QML model views such as GridView, ListView, and even Repeater.

Class diagram of application Qt/C++ engine. Note that some class members, methods and signals are omitted.
WLAN Connectivity
ConnectionManager class is responsible for managing the WLAN connections. It is an easily separable utility class and as such, has no dependencies to any other classes in the application. ConnectionManager has only one public method (slot), connectToWlan(), which does exactly the thing in its name: tries to connect to a WLAN network. If a WLAN access point is already active, it is preferred when calling this method. Otherwise, a connection to an accessible and known WLAN access point is made automatically. The class notifies listeners about its state by emitting stateChanged() signals containing one of the following enumeration values: NotConnected, Connecting, Connected, Disconnecting or Failed.
Client and Server
TicTacServer uses QTcpServer to listen to incoming connections. Here's a snippet where the server starts listening, connects QTcpServer object's newConnection() signal with the establishConnection() slot and starts broadcasting server info, finally changing the server state. When the state of the server is changed, a signal, notifying about this change, is emitted.
if (mTcpServer->listen(QHostAddress::Any, SERVER_PORT))
{
connect(mTcpServer, SIGNAL(newConnection()), this, SLOT(establishConnection()), Qt::UniqueConnection);
qDebug() << "Server listening on port:" << mTcpServer->serverPort();
// Start broadcasting server IP periodically to invite clients
if (!mBdcastSocket) {
mBdcastSocket = new QUdpSocket(this);
}
broadcastServerInfo();
setState(Broadcasting);
}
One thing to note here is that the QHostAddress::Any parameter in the listen() method means listening for connections on all open network interfaces. As seen from the above code, the establishConnection() slot gets called whenever an incoming connection is detected by the server.
TicTacClient, on the other hand, connects to server by calling the QTcpSocket class's connectToHost() method. It connects to the readyReady() signal to get notified whenever new data is available to be read from the socket.
mCommSocket = new QTcpSocket(this); mCommSocket->connectToHost(address, port); connect(mCommSocket, SIGNAL(readyRead()), this, SLOT(readIncomingMessage()));
More information about differences in Qt and WP sockets is available on the porting page.
Discovering Another Device
When the game is started, the application opens network connection (WiFi) and the server starts broadcasting its address, so that nearby clients can connect to it. The client starts reading such broadcast on the WiFi network.
As soon as a client finds broadcast messages from any other host in the network, it connects to the server on such port, stops reading any further broadcasts and emits serverFound() signal, so that the local server can stop listening for connections and the engine can prepare to start the game as a client.
The server, on receiving an incoming connection stops its broadcasts, starts waiting for incoming data on that connection and changes its state to ClientConnected and emits the signal notifying about this change (see private setState() method in tictacserver.cpp) so that the client can stop reading broadcasts and the engine can prepare the game as a server.
In this way, one of the devices starts acting as a server and the other as client.
All Downloads
| ID | File | Description | Size | Uploaded | Dls | Uploader | Component | Version | Platform | Type |
|---|---|---|---|---|---|---|---|---|---|---|
|
Project source with binaries
|
||||||||||
|
Harmattan binary
|
||||||||||
|
Project source with binaries
|
||||||||||
|
Harmattan binary
|
||||||||||
|
Symbian Anna binary
|
||||||||||
|
Symbian Anna smart installer binary
|
||||||||||
|
Project source with binaries
|
||||||||||
|
MeeGo? 1.2 Harmattan binary
|
||||||||||
|
Symbian smart installer binary
|
||||||||||
|
Symbian binary
|
Attachments
-
tictactoe_on_wp_and_symbian.png
(311.3 KB) -
added by Tomi_ 8 months ago.
Tic-Tac-Toe running on Windows Phone and Symbian devices
-
tictactoe-splash-screen.png
(40.6 KB) -
added by Tomi_ 8 months ago.
Splash screen
-
tictactoe-searching.png
(15.8 KB) -
added by Tomi_ 8 months ago.
Searching for opponent
-
tictactoe-your-turn.png
(22.0 KB) -
added by Tomi_ 8 months ago.
Your turn
-
tictactoe-waiting.png
(23.5 KB) -
added by Tomi_ 8 months ago.
Waiting for opponent
-
tictactoe-win.png
(26.2 KB) -
added by Tomi_ 8 months ago.
You win
-
tictactoe-wireframe-1.png
(155.5 KB) -
added by Tomi_ 7 months ago.
Wireframe 1
-
tictactoe-class-diagram.png
(39.8 KB) -
added by Tomi_ 6 months ago.
Tic-Tac-Toe class diagram
-
tic-tac-toe-on-lumia-800-and-n9.png
(350.5 KB) -
added by Tomi_ 6 months ago.
Tic-Tac-Toe running on Lumia 800 and N9






