/* File: nim.c Author: Jim Mayfield This program plays the game of nim. The game has two players (a computer and a human) who take turns removing one two or three rocks from a pile of rocks. Whoever or whatever removes the last rock from the pile wins. To compile this program, use: cc -I ~mayfield/lib202 -g nim.c -L ~mayfield/lib202 -l202 -o nim */ #include #include /* This gives access to the rint function, which returns a random integer within a given range. */ #include "rint.h" /* This is the maximum number of rocks that a player may take in one turn. */ #define MAXTAKEN 3 /* This is a forward declaration of the human function. We need it here, because the call to human in computer occurs before the definition of human. If this program were broken into multiple files, this would appear in the header file. */ void human(int numrocks); /* Computer is responsible for continuing the game when it is the computer's move. Computer calls human where appropriate to continue the game after the computer moves. */ void computer(int numrocks) { int numtaken; /* Make sure that the initial conditions are ok. */ assert(numrocks > 0); printf("There are %d rocks remaining.\n", numrocks); /* If the computer can take all the remaining rocks it does so. */ if (numrocks <= MAXTAKEN) numtaken = numrocks; /* Otherwise it takes a random number of rocks. */ else numtaken = rint(1, MAXTAKEN); numrocks -= numtaken; printf("The computer takes %d rocks.\n", numtaken); /* If no rocks remain, the computer has won. */ if (numrocks == 0) printf("The grand computer wins!\n"); /* Otherwise it's the human's turn, so continue the game by calling human. */ else human(numrocks); } /* Human is responsible for continuing the game when it is the human's move. Human calls computer where appropriate to continue the game after the human moves. Since computer also calls human, the two routines are mutually recursive. */ void human(int numrocks) { int numtaken; assert(numrocks > 0); printf("There are %d rocks remaining.\n", numrocks); /* Get the number of rocks taken by the human. */ printf("How many rocks do you take? "); /* This fflush makes sure that the prompt will appear immediately. */ fflush(stdout); if (scanf("%d", &numtaken) != 1 || numtaken <= 0 || numtaken > MAXTAKEN || numtaken > numrocks) { printf("That's not a legal number of rocks to take.\n"); /* This fflush throws away anything that the user has already typed in; the last input was bad, so we need to start over. */ fflush(stdin); /* This directly recursive call gives the human another chance to enter a legal number of rocks. */ human(numrocks); } else { numrocks -= numtaken; if (numrocks == 0) printf("The lowly human wins!\n"); /* If rocks remain, then it's the computer's turn. */ else computer(numrocks); } } main() { /* Play one game. Human starts; there are 21 rocks. */ human(21); }