I've written a game of tic-tac-toe in Java, and my current method of determining the end of the game accounts for the following possible scenarios for the game being over:
- The board is full, and no winner has yet been declared: Game is a draw.
- Cross has won.
- Circle has won.
Unfortunately, to do so, it reads through a predefined set of these scenarios from a table. This isn't necessarily bad considering that there are only 9 spaces on a board, and thus the table is somewhat small, but is there a better algorithmic way of determining if the game is over? The determination of whether someone has won or not is the meat of the problem, since checking if 9 spaces are full is trivial.
The table method might be the solution, but if not, what is? Also, what if the board were not size n=9
? What if it were a much larger board, say n=16
, n=25
, and so on, causing the number of consecutively placed items to win to be x=4
, x=5
, etc? A general algorithm to use for all n = { 9, 16, 25, 36 ... }
?
If you have boarder field 5*5 for examle, I used next method of checking:
I think, it's more clear, but probably is not the most optimal way.
Here is a solution I came up with, this stores the symbols as chars and uses the char's int value to figure out if X or O has won (look at the Referee's code)
Also here are my unit tests to validate it actually works
Full solution: https://github.com/nashjain/tictactoe/tree/master/java
Heres my solution that I wrote for a project I'm working on in javascript. If you don't mind the memory cost of a few arrays it's probably the fastest and simplest solution you'll find. It assumes you know the position of the last move.
I am late the party, but I wanted to point out one benefit that I found to using a magic square, namely that it can be used to get a reference to the square that would cause the win or loss on the next turn, rather than just being used to calculate when a game is over.
Take this magic square:
First, set up an
scores
array that is incremented every time a move is made. See this answer for details. Now if we illegally play X twice in a row at [0,0] and [0,1], then thescores
array looks like this:And the board looks like this:
Then, all we have to do in order to get a reference to which square to win/block on is:
In reality, the implementation requires a few additional tricks, like handling numbered keys (in JavaScript), but I found it pretty straightforward and enjoyed the recreational math.
I don't know Java that well, but I do know C, so I tried adk's magic square idea (along with Hardwareguy's search restriction).
It compiles and tests well.
That was fun, thanks!
Actually, thinking about it, you don't need a magic square, just a count for each row/column/diagonal. This is a little easier than generalizing a magic square to
n
×n
matrices, since you just need to count ton
.a non-loop way to determine if the point was on the anti diag: