Othello in Java: Part 1: Data structures
You’ve got a big problem. Someone forces encourages you to implement a complete Othello UI+AI in Java, but you don’t have any idea how to do that. If you already know how to implement the basics and you are interested in more advanced strategy concepts, you might be interested in the other parts of this series (yet to come).
In this multi-part series I will not provide any complete solution to any of the standard Othello tasks. Instead, I will provide (hopefully) helpful hints how to get your coding going and explain how your code works.
How to Edit & Compile
If you want to develop a project like Othello (it’s not really difficult, but it isn’t extremely easy either), you should have already worked out a way of editing and compiling your code. **If you edit your code in a normal text editor and execute javac to get .class files, stop right here!**Don’t even bother to do that for Othello or even larger projects. The only thing it’s going to do is to waste insane amounts of your time. Believe me, you’re gonna need the techniques described here for more complex projects anyway, so now is the time to start using them.
What you need is something called an IDE (Integrated Development Environment) - essentially that is a neat graphical user interface with an intelligent editor displaying your syntax errors in real time and a “Run”-Button that essentially calls javac where neccessary and then starts your program. IDEs have far more advanced features than this, but don’t bother about them here.
Essentially there are two major IDEs: NetBeans and Eclipse. Everything beyond that is either expensive (and not neccessarily better), or doesn’t work well for your purpose. In the end it doesn’t really matter which one you take, but I strongly encourage you to use NetBeans because of the far better integration with advanced tools like a GUI builder (a program in which you can click your graphical interface together instead of writing the code on your own) and other reasons that go far beyond the scope of this article and might be described in other posts in the future.
On the NetBeans download page, you need to download the “Java SE” version. The extra features included in the other versions are not relevant for Othello.
The Othello board
Let’s take a look at the basic game board that we are supposed to fit into a Java class. It’s a basic 8x8 board - each cell on the Board can be in three different states in any time:
- Empty (usually displayed in green, because that’s the most commonly used color for the underlying canvas)
- Occupied by the white player
- Occupied by the black player
There are numerous different ways you can express these three states in Java. For the sake of clarity, I will only describe one in this article: Enums. If your didn’t heard of them before, please take a look at the Java tutorial on Enums. Enums are a way of expressing what your want to model more clearly than alternatives like integers (e.g. your could say that 0 equals empty, 1 equals white and 2 equals black).
Cell data structures
Given only the information about the board from above, we can easily define an enum for the state of a cell:
public enum CellState {
EMPTY,
WHITE,
BLACK
}
Board data structures
Now we have a simple object type that represents a single cell - but how can we implement the 8 by 8 board of cells? Again, there are numerous different ways of doing this. I chose the most obvious one: Multi-Dimensional arrays. If you are not familiar with them, read the Java Tutorial.
In a new class that represents the board, we can now declare a 2-dimensional array of the CellState
enum type we defined before. The best way to declare the array is as instance member of the class you just created.
private CellState[][] board = new CellState[8][8];
When you’ve done that, you have a data structure that is able to represent any possible Othello board.
If we want to start a new game, we need to initialize an instance of this data structure properly. The easiest way you can do this is the constructor. The code inside the constructor should be similar to this:
//Set all cells to empty
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
board[x][y] = OthelloCellState.EMPTY;
}
}
//Set the 4 starting stones
board[4][3] = OthelloCellState.BLACK;
board[3][4] = OthelloCellState.BLACK;
board[3][3] = OthelloCellState.WHITE;
board[4][4] = OthelloCellState.WHITE;
When displaying a board initialized using this code using an appropriate GUI, it should look similar to the image above.
One important aspect to remember in the code above is the nested for loop iterating over the x and y coordinates of the board to set all cells to empty. Because array indices start at 0 (and therefore the last valid index of an 8-sized array is 7), the leftmost, topmost cell has coordinates 0,0 whereas the rightmost, bottommost cell has coordinates 7. Both loops (for x- and y-coordinates) therefore need to start at 0 and and at 7. You will definitely need the code from above in other parts of your Othello implementation.
To keep your code clear (that is, not to confuse yourself), you should stick to either indices that start at 0 OR indices that start at 1. Because in Java there is no simple approach to make arrays use indices starting at 1, I will stick to so-called 0-based-indices.
Now that we have a properly initialized board, we can define instance methods of the board class to access it more easily, for example:
/**
* @param x The x coordinate (0-based) of the cell
* @param y The y coordinate (0-based) of the cell
* @return True if the cell described by the coordinates is empty, false
* otherwise
*/
public boolean isEmpty(int x, int y) {
return board[x][y] == OthelloCellState.EMPTY;
}
As an exercise, I highly encourage you to implement the following instance methods yourself (the method shall do exactly what is described in the comment exactly above it. The format of the comment is standardized Javadoc). Trust me, it’s extremely easy given the example above:
/**
* @param x The x coordinate (0-based) of the cell
* @param y The y coordinate (0-based) of the cell
* @return True if the cell described by the coordinates contains a white
* stone, false otherwise
*/
public boolean isWhite(int x, int y) {
//Your code goes here
}
/**
* @param x The x coordinate (0-based) of the cell
* @param y The y coordinate (0-based) of the cell
* @return True if the cell described by the coordinates contains a black
* stone, false otherwise
*/
public boolean isBlack(int x, int y) {
//Your code goes here
}
After implementing these functions, you should have a working data structure for Othello. Probably you will need more methods for your player implementation, but you can add them later on demand.
**Note:**I originally planned this as a multi-part tutorial, but I never got to writing Part 2 (not yet, at least). One of the reasons for that is that writing Othello implementations is a now really unimportant part of my life.