Othello

Multithreaded Othello Project

code

A few years ago I did this project for my Data Communications class, I did all of the program logic and thread handling while my partner took care of the GUI. This program allows users to connect to a server and play games of Othello with each other. It is multithreaded  and can run multiple games at the same time. The scope was a bit limited as this was just a project for a class so this current iteration is just designed to run on one computer. I spent a lot of time on this project and am quite proud of how it turned out. I had a lot of fun making it so I think I might revisit it sometime soon. I included the report we wrote for the class as well as some screen shots down below.

Intro

We decided to do the game Othello using C-S architecture where both players connect to the

server. The server will manage the connection between two players and send game moves to

each player. This project is multithreaded so many clients can connect and many games can be

played at once. We decided to build this entire project in java as that is our most well known

language, as well as ease of handling the multi-threading, socket programming, and

input/output streams. We also create a GUI for the game itself.

The program has seven Java files total. Four of the files are code for the client and server

connections: ClientHandler.java, GameClient.java, GameServer.java, and GameHandler.java.

Two of the files are for the GUI: OthelloPanel.java and OthelloGUI.java. The last file is for game

logic: Othello.java.

The following commands are implemented:

connect: This allows the user to connect to a specified port number on the server.

create: This is from the client side. Once the client has connected to the server (which happens

automatically when the program is ran), they are able to type create in order to create a game.

join<id>: This command followed by the game number allows the user to join a specific game.

list: This command allows the user to see if there are any available games to join.

close: This terminates the program.

Program Logic

GUI Files:

There are two main files that implement the OthelloGUI that we created: OthelloGUI and

OthelloPanel. OthelloPanel has a function that we created called ButtonListener that

implements ActionListener. This makes it so that when any of the buttons are hit, there is a

signal sent out. It also has createBoard and updateBoard functions to ensure that the GUI

updates (on both of the player’s screen) whenever a player picks a spot to move. OthelloGUI is

mostly just setting up the frame and the way that the frame should look.

Game Logic Files:

Othello.java is where the core logic lies, there is a driver in GameHandler.java that uses and

runs Othello.java. Othello.java has several toString methods that convert the board state into

strings which the GameHandler sends to the client

Server and Client Flies:

There are four files for the server and client connections: GameServer.java, GameHandler.java,

GameClient.java, and ClientHandler.java. GameServer.java sets up the server that accepts

clients. Clients are passed into the ClientHandler which sets up a connection with

GameClient.java and takes in and executes the commands. When a game is created the

ClientHandler records the address of the client and adds it to the list of games, when the game

is joined the ClientHandler launches the GameHandler with the two clients addresses. Each

client starts a new connection with the GameHandler, the GameHandler connects to each client

and the game is played.

GameClient.java

This is the client class which relies on the two gui files OthelloPanel.java and OthelloGUI.java.

When the program starts the client is prompted to connect to the server, when the client

connects they are put into a while(true) loop where they can input commands into the command

line. When a game is created or joined a new GameClient class is created with the server and

port information. The client then creates a new socket and waits for the server to connect to it.

The way the port numbers are determined is based on the gameID, the client creating the game

uses 3030+(id*2) +1, which always evaluates to an odd number. The client joining a game

creates their game on port 3030 +((id+1)*2), which always evaluates to an even number. This

math is being done on the server side so that the server will always connect to the right port.

Once the game is running the client awaits connection, when this happens the server will send

the boardState to the client in the form of a string, which is parsed and converted into a 2d grid.

The client takes in grids from the server every time the board is updated. The server is also

sending an integer at the beginning that tells the client if the game is over, if the game is over

the client loop will stop and the game will end on the client side closing the gui and

disconnecting the socket. If the client receives a grid with a “P” it means that there are possible

moves which means it is the clients turn, if there is no “P” then it is not the clients turn. This was

a relatively simple way to let the client know whose turn it is. This also means that the popups

telling the client that they are making a wrong move or its not their turn are handled on the client

side.

GameServer.java

This is where the server is started on port 3030. Every time a new client connects they are

added to the ClientHandler.

ClientHandler.java

This is where the clients are handled. Whenever a client inputs a command through the

command line it is run through here. The ClientHandler sets up a data input and output stream

with the client to receive the commands.

When a client creates a new game they are added to a list of hosts, and a new entry is added to

the list of available games. The GameHandler is not started until another client joins the game

so the client is simply waiting until then. Once a client joins another game a new GameHandler

is created in the games list, The host and guest ports are determined the same way as in

GameClient.java, where the host gets an odd port and the guest gets an even port. Once the

game is started the GameHandler takes over.

When the game finishes the host will send out the “over” command when the ClientHandler

receives this it increments counter by 1. The gameID increases for every new game and does

not reset. When the client calls the list: command it looks at the available list and sends them

out.

GameHandler.java

The GameHandler takes in the address and ports of the client and guests. Both clients should

be waiting for a connection so the GameHandler will connect to both of them and start the game

by creating a new Othello(). The GameHandler will then send the initial boardstate to both

clients in the form of a string that will be parsed. The GameHandler sends the game status

“0”(game not over) along with the board state with possible moves to the host(since they go

first) and the normal board state to the guest(since its not their turn)

Then the driver() is called in a while(true) loop until the game is over. The driver reads in the line

from whoevers turn it is and parses the input. The GameHandler then places the disk in that

spot, flips the turn, and then sends out the updated board to the host and guest. The player

whose turn it is gets the board with possible moves. Once the game status is not 0 isOver is set

to true which ends the while loop and ends the game. The GameHandler then disconnects while

the clients are disconnecting and the GameHandler ends.

Problems Encountered:

On the GUI side, there weren’t many issues to account for other than remembering how to

make a GUI in java. The game logic wasn’t too bad as both of us have coded similar projects in

the past that dealt with Othello in general. We also were initially going to be doing this project

with more students, but after trying to get in touch with them for a few days and not getting

prompt responses, we decided to go ahead with this project by ourselves.

There were a few strange problems I’ve never encountered before. I had multiple instances

where the program would work fine while in debug mode, but not work while running normally. I

assume this has to do with threads and the timing of things. I was able to figure out one of the

earlier problems with this by changing the order some things connected in. But there is a

remaining bug where if you press the “X” in the gui the command line will not continue so you

have to ctrl+c out of it, I am not sure why.

I also had some problems with just getting everything to connect to the right ports and making

sure there were no overlapping ports, as you can see I ended up with a slightly complicated

looking solution of determining which port to connect to using the gameID the host connects to

port: 3030+ (gameID*2)+1, and the guest connects to port: 3030+((gameID+1)*2)), This just

ensure that the host is connecting to odd numbers and the host is connecting to even numbers

so that the ports will never overlap no matter how many games are created(until we run out of

ports of course)

Overall there were just a lot of problems trying to get everything to connect and work properly as

this is just a fairly large project. I had problems with the Othello.java class as well that I created

a Driver.java class to use for debug purposes so that I didn't have to go through the trouble of

connecting to the server every time I wanted to test things.