Other games are symmetrical, or very nearly so. Chess, Go, Tic-tac-toe, Dots and Boxes, Battleship, and Cribbage are examples of games in which both players are faced with a nearly identical challenge.
For your final project, you will write a program that plays a game. Your goal, however, is not necessarily to make the game fun to play, but rather to make the computer play it well. The heart of your project will be the computer's strategy for playing the game you choose. For example, you could program the computer to play Tic-Tac-Toe by picking a random open square, but you would end up with a program that never wins and almost always loses to an experienced player. On the other hand, if you understand Tic-Tac-Toe, you can program a computer to play it perfectly (always tying when playing a perfect opponent, and winning whenever the opponent makes a mistake).
You can write your program to play against a human player. In this case, you should pay enough attention to the user interface to make sure a new user will be able to figure out how to play. The user will also need to be able to see the current state of the game at any time.
On the other hand, you could write your program so that it plays against itself, and collects statistics on how many games are won by which strategy. For example, it might be interesting to know how many wins, ties, and losses a "play in a random square" Tic-tac-toe strategy would achieve against a "block my opponent if I can, and otherwise play in a random square" strategy. If you take this approach to your program, make sure the program prints out the collected data in an intelligible way, and also make sure to discuss the results of your investigations in the documentation you hand in with your program (see below).
Either way, you should try to program modularly. Again considering Tic-tac-toe, you will probably want to write the following routines, (among others) or something similar:
{================================================= GameOver returns true if the game is over, and false otherwise. If the game is over, the identity of the winner is stored in the variable parameter "winner". =================================================} function GameOver( theBoard : BoardType; var winner : integer ) : boolean; {================================================= CanIBlock returns true if the given player has a move that will block a win by the other player, and false otherwise. If a block is available, the square in which the player should play is stored in the variable parameter "where". =================================================} function CanIBlock( me : integer; theBoard : BoardType; var where : integer ) : boolean;Both of these functions assume player identities are stored in integer variables, and CanIBlock assumes the squares on the board are numbered by integers. If you have a different scheme for identifying players or squares, modify this accordingly. The point is that well-designed functions can simplify the code dramatically. I recommend that you start with a piece of paper and no computer, and think about what sorts of functions and procedures you want to write, before you write them.
Have a careful plan of the small steps you will take in travelling from no program to the final program. Design your program modularly, so you can make the modules work one at a time.
Don't go to sleep without a program that compiles and runs without crashing. It doesn't have do anything--just don't try to do so much at once that you can't wrap up the day's work into a running, partially complete, program.
Make copies of your program before making changes.
Due 5:00 Friday, November 22 (via HSP)
Talk to me. I can help. I will hold regular office hours during reading and exam days. I will post my hours on my office door.
Start early, keep in touch, and have fun.