The other day I created some teams (3 to 4 students per team) and asked them to create a program to play tic tac toe – a human player against the computer. I have asked students to create a human vs. human version of tic tac toe in the past. It’s a nice little project that requires they use a lot of concepts that they have learned. Adding an AI is a bit more though so that is why the teams. Since I have never coded a tic tac toe AI myself (how did that not happen?) I decided that I had to write a version myself.
I had a version of human vs. human tic tac toe to use as a base so the first thing I did was modify that so that it would call a module for find a computer move and incorporate that into the game. First learning – this is not as trivial as it sounds. Oh it’s not hard but one really has to think it through or you wind up with weirdness like the computer taking two moves or missing moves. It might have been easier to rewrite some key code rather than munging it up. Next time.
To test the code that allows the computer to move I made a very simple algorithm. I just randomly picked squares until I found an empty one. It worked. It allowed me to test the rest of the program but of course it didn’t play very well. Step two was to check to see if there was a square I could move in to win. A short time later I had a group of 24 if statements that checked every possible winning opportunity.
Then I made a beginner mistake. I copied and pasted that code and changed checking for “O” into checking for “X” to find a place where the computer needed to move to block a win by the human player. It took me a day away from the code to realize that this doubled the chance for me to make an error on this sort of check. I know better than that! So I broke the code out and created a single method that took as a parameter either an “X” or “O”. Much simpler code and it opens the door for me to more easily modify the program so that the computer can play as either “X” or “O”.
Since them I have done a bunch of refactoring and breaking complicated code out into individual, more simple, methods. It should make for good discussion when we talk about these programs as a class.
My students all want to try their hand against my AI.They helped me refine my program by finding things that I missed by not thinking things out enough. Students liked that of course. Now they don’t win anymore. In fact they frequently lose to the AI. That surprised me at first. I watched how they played and it became clear. They were so totally focused on what they could do to win that they missed seeing what the computer could do to win. That’s something else we’ll talk about in class. The computer doesn’t miss those opportunities.