While I recover the Undo functionality, I will go over the background of the program's AI in the meanwhile.
Essentially, the program can use one of 3 kinds of decision making routines to simulate a proper AI. (This is in addition to the random move routine.)
The first is the basic tree graph to layout what move lead to which moves and an evaluation of that move. For this version I will only evaluate the NEXT Computer's move and the following User's move (one ply each) for the winning move.
Another is to use pattern recognition. The program can check the current positions of the playing pieces and find out if a winning move is possible.
The related routine (the third one) is to use a state machine. The program will not need to decipher the game to find the proper state, but the current state of the game will need to be stored to determine the next game state. The trade-offs are pretty much obvious, program complexity (deciphering the game to a state value) versus footprint (storing the current state and the next-state table.)
The pattern matching and the state machine routines are possible because of the limited distinct positions of the playing pieces. (At least the computer can calculate them).