Saul's Tic Tac Toe


Day 1:

To start coding Tic Tac Toe, I had to sit down and think about all the things that I would need if I were playing it for real (i.e. on paper). So I came up with a small list:

I realized that the simulation of a board game is mostly about the RULES of the game. I need to code in a way for the understood rules of the game to be understood and maintained by the computer simulation. For Tic Tac Toe, that is the alternation of turns between players, the decision of when the game is over, and making sure that no player goes two turns in a row.

Having these things in mind - I decided to tackle the problem in code. The first thing I did was get overambitious so in my applet originally there were instance variables for GUI's and different kinds of players, but then I saw that that would take away from the integrity and spirit of the game. I wanted a red-blooded American, simple way that two people can play tic tac toe on a computer screen. So I threw away all thoughts of GUI's and computer players. I decided that the most important things were an Applet, so that we could see the program, a board, where the game would go on, and the actual squares that we would click for the program to work.

To see my code for each class, click on the appropriate link:

Problem 1

So I coded in an applet that makes a board and passes itself as a parameter for graphical reasons. But, after making a nested for-loop in the Board class to fill in the array, I could not get the squares to show up in the right place. So I hiked up my trousers, bore down into the mud of the sun-lab, and put on my Debugging shoes. It was actually good to have a bug in a program that I considered relatively simple because it allowed me to have the same exasperation that new students have when they code. I thought i knew what was going on but things did not work as they should have. I put in System.out.println's that told me where things were in the array, what their GP.Attributes.Positions were, and where they were when I clicked on them. My squares were moving without me doing anything to them!!! Frustrated, I went and ate some food thinking that 20 minutes away from the program would both allow me time to breathe and think about what on earth I could have been doing to make this not work.

I returned, 1 Ocean spinach pie later (and a glass of water), and sat back down to fix this problem. I reviewed the Flow Of Control of the program by hand simulating what each line was doing and nothing seemed to be wrong. Finally, I found my problem and I think it is one that many students can run into with GP: I was setting my geometry managers incorrectly!!! I have been a cs15 TA for an entire semester and i took the course with GP, and when asked, I still say "I don't know what they do but they make everything work!". Needless to say, I had a column or something incorrect and it was moving everything where I did not want it. I fell victim to the just keep changing code until it works method of debugging and it finally did.

Day 1 continued

That bug past me, I came to the point where some design decisions had to be made. I am a staunch believer in Object Oriented principles, but some of them would have been complete overkill and a waste of time for the project at hand. For example, I could have made a state for whose turn it was or for each of the squares on the board, but it would not nearly have been as time efficient as modular arithmetic between 0 and 9 for the nine turns in Tic Tac Toe. I also decided that checking for end game did not need an elegant solution as much as it needed two quick searches through the array. These decisions were time and problem specific - I did not think it was worth the time of the programmer to find elegant solutions for such miniscule problems when a simple case would solve the problem easily. Generic and extensible is important, but for me, the time was more important than the polymorphic opportunities available to me.

Therefore, when it came down to the react() method of the square class and the checkGameOver() method of the Board class, I was much more interested in keeping it simple than in being elegant in my attack of the problem. I solved the problem of whether there was a game over (i.e. somebody won) by a rather lengthy process. I did it for two reasons:

This allowed me to easily figure out the endgame algorithm in my head and see how simple it really is.

Problem 2

Problem 2 was the fact that my endgame was not telling me the correct answer. It would say that the game was over and that someone had won when they hadn't. I reviewed the code and saw that I had an error in the order in which I instantiated the local variable that was my "win counter". I originally had a case where if (count == 3) { count == 0} which would reset the counter for each column, but it would not work. Instead, I instantiated this local variable in between the two forloops (an unconventional action I believe) which allowed me to have a new counter for each round of the external for loop which was exactly what I wanted and I did not even need to use a case statement. Here, the use of a simpler piece of code, in the correct place enabled me to do what I wanted much easier than a more difficult case statement.

Day 2

Day 2 was much more about writing this journal than about coding. After I roughly had the end product, I communicated with Matt Amdur (see his Tic Tac Toe journal at this link) about what he had done and I realized I needed a Tie situation. I added that on and then the program was complete. There were many little bugs like compile errors for lost semi-colons or for misplaced brackets, but all in all, it was those two main bugs that got me.

Commenting as I went along allowed me to leave notes for myself about why I had done things in a specific way and when I went back into the code it was very helpful. For example, in the board class when I went back I saw that I had left a note that I would need access to the array positions of the squares within the squares so it was very easy to add that to the constructor of the squares and they would have that information. I also found that having relatively "smart squares" was very good because if they knew a lot of their own data (such as state, indices, etc) I did not have to go fishing in the array for their information and the accessor/mutator methods (set and get) made it very easy to work with the classes at hand.

Designing the program was not that difficult although I feel that there were some things that I could have had as classes but did not (such as a player class or a piece class) These objects were not needed to be their own classes because of the small nature of the game. It was, however, necessary to change my ideas about what I wanted my squares and board to do and how they would communicate. I could have used holders and other such objects to minimize the board's and the squares' interaction with each other, but I felt that that was integral to the program. Overall, I would say the design was more as I thought it at the beginning than usual - partly because TAing cs15 has helped me learn how to design much better, and partially because Tic Tac Toe is not an exceptionally difficult program.

Any questions? Send me some mail..... Saul N.