aspose file tools*
The moose likes Beginning Java and the fly likes tic tac toe/nought and crosses exercise Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of EJB 3 in Action this week in the EJB and other Java EE Technologies forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "tic tac toe/nought and crosses exercise" Watch "tic tac toe/nought and crosses exercise" New topic
Author

tic tac toe/nought and crosses exercise

Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
HI chaps I am trying to build a simple tic tac toe application. The exercise, taken from deitel and deitel book goes:

Create a TicTacToe that will enable you to write a program to play Tic-Tac-Toe. The class contains a private 3-by-3 2 dimensional arrays. Use an enumeration to represent the values in each square of the array. The enumeration's constants should be named X, 0 and EMPTY (for a position that doesn't contain an X or 0).
The constructor should initialize the board elements to EMPTY. Allow 2 human players. Wherever the first player moves place an X in the specified square amd place an 0 wherever the second player moves. Each move must be to an empty square. After each move, determine whether the game has been won and whether it's a draw.


So, here's the pseudocode I came up with and now I will start developing:



I have a few questions:
1) what type should the array have? I mean it will get values like "X", "O" and "EMPTY", so is it ok for it to be a string?
2)enumeration: I am meant to use an enumeration, but can I use it within a class or should it be on its own file?
thanks
Stuart A. Burkett
Ranch Hand

Joined: May 30, 2012
Posts: 679
Jason Attin wrote:I have a few questions:
1) what type should the array have? I mean it will get values like "X", "O" and "EMPTY", so is it ok for it to be a string?
2)enumeration: I am meant to use an enumeration, but can I use it within a class or should it be on its own file?

1. It should have the enumeration type
2. An enumeration is just another type of class. You use the same rules for deciding where to define it as you would for any other class.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
thanks, let's just look at a practical example, maybe that will help. So a couple of things I'd like to ask (enumerations not being my forte) say I have a file called TicTacToe.java with a class in it:


If an enumeration is another type of class I suppose I can't have something like the below in the same TicTacToe.java file:


I will need to store the enumeration in another separate file I presume?

Also you said the array should be of type enum. So is it something like
Finally should I declare the array where, inside the class or the enumeration?
thanks
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
I think you should go back a few stages. If you are asking things like where the array should go, you have not yet got any design for anything. Start by writing down how you play the game, and describing the board and ◯ (=\u25ef) ✕ (=\u2715) or similar. Obviously you would put the values into an array. You cannot use a 2D array because there is no such thing; you would use an array of arrays.
Your pseudocode is good as far as it goes, but you need to refine it a lot. Things like check for winners need much more detail before you can actually create any code.
You may wish to leave out checking whether the chosen square is empty until later. I have never seen people try to put two symbols in the same square at noughts and crosses.
Consider a few classes, Player and Game and Board spring to mind as possible classes. Consider what each of them does. As you do so, you will get ideas about where to put things like the ◯✕ or any arrays.

You are not using enumerations but enumerated types, which you can read about in lots of place, probably best starting in the Java Tutorials.

I think it is a good idea to use a three‑element enum, with EMPTY or similar as a value. Then you can fill your array with EMPTYs when you start and avoid the risk of running into nulls.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
Hi thanks for that. Well, I thought about how to play the game already, in that, the user will input 2 numbers which will be used as row and column of the array of array.
In terms of classes, I was hoping to use one, as described in my previous post because I thought it will be the easiest way.
I focussed on methods and came up with a few:


Obviously I still don't know all the nitty-gritty of how to check for victory and things like that, I thought I will look at that once I develop the code.

Finally the array: if I have an enumeration like

(Is this what you mean by
use a three‑element enum, with EMPTY or similar as a value.
?) i would have thought I will create an array of type TicTacToeEn:


My initial pseudocode I thought was a bit too descriptive (see below), that's why I sort of reduced it to what I posted here:

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
I think you are not yet at a stage advanced enough to be writing pseudocode. Draw some diagrams of boards, like this
┼┼
┼┼
and decide how you decide whether nought or cross has won. Work out how you can go through the numbers and work out whether there is a win or not.

I think things like full board or double use of the same square are minor problems which you can ignore for the time being. I have never seen anybody try to put two symbols in the same square at noughts and crosses.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
Ok, I will follow your advice, let's scrapt eh pseudo code for now.
I have drawn a few boards and had a go.
So, the idea is that I will have a 3x3 array of array, so as said something like
and the user will input the rows and columns to determine the position where the
X or O will go.
When a X or O is inserted in the square, depending of the position, I have to check the
horizontal, vertical and diagonal row to see whether the tree-in-a-row is achieved.

The user input has to be between 1 and 3 to which I will subtract 1 to get the correct index array:
for example if the user inputs 2 for row and 1 for column I will have 2 and 0 (incidentally
I could have a function that subtracts 1 to the user input) will be the
square where a X or O is positioned.

To check whether somebody has won I have to run a series of checks: horizontally (forward
and back), vertically (top to bottom and bottom to top) and diagonally (top to bottom , bottom to top)


for I will check horizontally (assuming also has the same symbol)
adding 1 to the column so . If has the same symbol as the other 2
and then the game is won.
If not we continue our checks.
Vertical check: again assuming has the same symbol then I will check
and if it has the same symbol the game is won.
If not, diagonal check:
assuming has the same symbol I will check, if that has the same symbol
then the game is won, if not we continue playing.

So in essence if row = 0 I need to:
- add/subtract 1 to the column for horizontal check
- add 1 to the row for vertical check
- add/subtract 1 to row and column for diagonal check

I think I could use a double for loop and check all the squares

To check whether the game is draw, I will determine if all the squares are full and either the X's are 1 more than the O's or the other way around it
How about that?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
To determine whether the game is over, you only need to count the goes: when you get to 9 you stop.
Remember you alternate o/x.
I haven’t been through all your checks, but they look all right. You appear to be using the indices in the order column→row. Most people would use row→column. The logic would be the same. Remember you only need to check three lines for the most recently filled square.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
cool, so what now, should I start coding or redo the pseudocode?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
Pseudocode. Remember it is usually easy to go from pseudocode to real code.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
ok perfect, so I will add to what I have already and try to expand a bit more on it. The thing is I don't want my pseudocode to look like code if you know what I mean, I am not sure how much I should expand, and how deep into details I should go. ANyway, I will amend the pseudocode and post back the result
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
Start by describing in plain English how you play it. Things like alternating turns, 9 squares, etc.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
Ok, so I did write down what I want to achieve and then I have elaborate a bit more, went into more details till I produced the following (I added manycomments for the sake of clarity).
I described the variables I think will be useful to create and what they should be used for. Same for functions.
I'd like to make a few observations if I may.
1)I know you said a few times that I shouldn't bother checking that the square is empty before I assign a X or O to it, but the exercise specifically says that
I have to assign to an empty square, so I assume the safest way is to check whether the square is empty before assigning a value to it.

2)I had a change of heart about how to check for victory. My approach was flawed in that adding and removing 1 to calculate which square I had
to check is not feasible and prone to errors. After looking around here and there and thinking I resolved that it is better to check squares 1 by 1 using all
the possible combinations. If it wasn't a 3-by-3 board then this will be a problem but since it is a simple application I thought it will be ok,hence this code:



3)checking a draw game and end of game: providing nobody wins, a draw and an end of game are effectively the same thing, they occur when all
the squares are full, so if I check for a draw I check for end of game, hence I used only isDraw(). This means that really I don't need any counter


What do you reckon?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
You do not need to check for victory. You need to check whether the most recent symbol completes a line of three.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
Hi Campbell Ritchie,
sorry I am not sure I understand that...there is a function that checks for victory which is . Maybe do you mean that I have to check for victory from within assignSymbol, so something like

thanks
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
I am not checking the whole of your pseudocode/algorithm/rules or whatever. You should be doing little bits at a time. For the winning board method, you only need to check whether the most recent symbol completes a line. Let’s make some suggestions. I quite like the way you are calling the victory method, but that can be refined and simplified quite a bit.
Let us imagine that you already have a method of putting Os and Xs onto the board. Let us imagine that you have already got a way of displaying the board, which you can do simply with a combination of System.out.printf(...) calls and |--- symbols. Or even symbols like what I showed you yesterday; you can find them in this Unicode charts; you can write \u2534 or similar in a String.

Now what you do is, whenever you take your turn, you put O or X in a particular square, and then check that square for a winning row. Once you have put the O/X there, you simply need the square number. If it is the middle square, you need to check four directions round it, and if you find the same symbol twice, you know which direction to check next in. If it is a side square, you need to check two directions. Corner squares need three directions checking. So, if you play…you have to check for X in two squares and that can only be a winning move if you find an X. If you don’t find that X, you can stop checking. If the top left square is blank or O, there is no need to look at the bottom left square.
I would suggest you create isInWinningRow() and isInWinningDiagonal() methods, etc, which you can call from inside the victory method. The more and the smaller parts you can divide the task into, the easier each part will become.

If you add the array indices, you will find something different between corner squares and side squares.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
thanks. I am finding a few problem with your suggestion
create isInWinningRow() and isInWinningDiagonal() methods,
because I don't seem to be able to come up with a way to get the square number without an awful amount of code. If I 'number' the squares with numbers from 1 to 9 it seems really complicated to associate a number to the position, eg suqare 1 being boards[0][0], so I think, for now, I will stick to one method and see how it goes, I will post back as soon as I complete the code
thanks
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
It should be really easy to get the square numbers into row and column in a 3×3 array‑of‑arrays, particularly if they run from 0 to 8. That involves you using the % and / operators. All you need to do is work out the right‑hand operand, and Bob’s your uncle.

Hint: you can divide by the number of rows, so the RH operand should be easy to guess .
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
Remember 0 to 8, not 1 to 9, so you might need (square - 1) /?? and (square - 1) %??
The () are essential.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
right, I finally have a working program, yay : - )!
ABout checking victory, I did try to do it your way, but I must admit I found an easier way (I fully appreciate that easier doesn't necessarily mean better) to do it and I went for it.
Here are the two files (I thought it would be better to use an online compiler rather than paste the whole thing here):
http://ideone.com/wIk4mu
http://ideone.com/zZlIVa

I eventually used one method checkVictory rather than checking the input as it is inserted.
It works ok so not bad in the end ;-). The only thing I haven't done is validation, so really users can input whatever they want and break everything.
what do you reckon?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 36478
    
  16
You ought to have posted the code here. Beware of these online compiler sites; I have found some serious errors in their operations before now.
Your lines and methods are too long.
You have used if (b) return true; else return false; and similar poor style. Don’t use \n, least of all when you know how to use printf.
I still do not like your method far calculating whether the game has been won.
Why are you not using the % operator (or even better the bitwise & operator) to determine whether it is O/X? You can even use a method of the enumerated type to set O/X from 0/1.
Jason Attin
Greenhorn

Joined: Feb 02, 2013
Posts: 22
thanks, sorry I thought online compiler were good, becasue I don't need to post all the code. ANyway, I appreciate your method was better than mine, I don't want to give you the impression that I don't like being advices or follow them, on the contrary, grateful for the guidance, but, in all honesty I couldn't implement that. I tried but I got completely lost, and I thought this would be easier : - )!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: tic tac toe/nought and crosses exercise
 
Similar Threads
TicTacToe game
Game Tutorials -->> TicTacToe
TicTacToe Game..
TicTacToe in Java
TicTacToe user vs computer