Code:
#include <stdio.h>
#include <time.h>
// Constants used in the program.
#define NUM_PEGS 4
#define NUM_COLORS 6
#define MAX_TURNS 10
#define MARKED_BOARD -1
#define MARKED_ANSWER -2
// Functions used.
void fillBoard(int board[]);
int numPerfectMatches(int board[], int answer[]);
void getUserGuess(int board[]);
void copyArray(int dest[], int source[], int length);
void markOutCorrect(int board[], int answer[]);
int numWrongPlaceMatches(int board[], int answer[]);
void greeting();
void printArray(int array[], int length);
void printWinner(int num_turns, int num_seconds);
void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name);
int main() {
int multi, leader_minutes, leader_seconds, leader_time, leader_turns, answer[NUM_PEGS], board[NUM_PEGS];
char leader_name[20];
// Seed the random number generator.
srand(time(0));
// Set everything up.
int num_turns = 0;
fillBoard(answer);
int start = time(0);
// ask if they are playing multiplayer or not
printf("Are you wanting to play (type the number and press <ENTER>):\n");
printf("1. Single Player\n2. Multiplayer\n");
scanf("%d", &multi);
if(multi != 1 && multi != 2) {
// tell them they made an invalid choice
printf("Invalid choice. Choose either 1 or 2 next time!\nGoodbye!\n");
system("PAUSE");
exit(0);
}
// do things based on their choice
if(multi == 1) {
// initialize leader variables
int leader_minutes = 100, leader_seconds = 100, leader_time = 100, leader_turns = 100;
char leader_name[20];
// open leader file
FILE *ifp;
ifp = fopen("leader.txt", "r");
// read in leader time and turns
fscanf(ifp, "%d", &leader_minutes);
fscanf(ifp, "%d", &leader_seconds);
fscanf(ifp, "%d", &leader_turns);
fscanf(ifp, "%s", leader_name);
// convert time to seconds
leader_time = (leader_minutes*60) + leader_seconds;
// close file
fclose(ifp);
// Stores the real answer and the user's board, respectively.
int answer[NUM_PEGS];
int board[NUM_PEGS];
// Set everything up.
greeting();
} else if(multi == 2) {
// ask them on how to play online
printf("To play multiplayer you must have someone else playing with you. Please read the following carefully:\n");
printf("1. You must have an internet connection\n2. You must have someone else who is going to play");
printf("3. You can choose from 2 modes:");
printf("\t A. Digit chooser (you pick four numbers for the guesser to have to play with)\n\t B. Guesser (the one that tries to guess the four numbers)\n");
printf("So which will it be??? Type 1 for \"Digit Chooser\" or 2 for \"Guesser\"\n");
scanf("%d", &multi);
if(multi == 1) {
int a = 0, b = 0, c = 0, d = 0;
// tell them how to choose
printf("You must choose from 4 numbers from 0-5. If you choose a number outside that range, the game will shut down!\n");
printf("Which four will it be partner??\n");
scanf("%d%d%d%d", &a, &b, &c, &d);
// if any numbers are out of the 0-5 range, then exit out
if(a < 0 || b < 0 || c < 0 || d < 0 || a > 5 || b > 5 || c > 5 || d > 5) {
printf("You chose a number outside the 0-5 range.\nGoodbye!\n");
system("PAUSE");
exit(0);
}
// if all of their numbers are correct, then encrypt them and upload them
a = a*5+38;
b = b*7+25;
c = c*3+12;
d = d*9+14;
// open file for writing and add the numbers
FILE *ifp;
ifp = fopen("chooser.txt", "w+");
fprintf(ifp, "%d %d %d %d", c, b, a, d);
// close file
fclose(ifp);
// execute batch file
system("up.bat");
// tell the user it's done, and they may exit
printf("If you followed all of the rules, your numbers should be in our database for a guesser to play!\n");
system("PAUSE");
exit(0);
} else if(multi == 2) {
int a, b, c, d;
// download the file
system("down.bat");
// open leader file
FILE *ifp;
ifp = fopen("chooser.txt", "r");
// read in leader time and turns
fscanf(ifp, "%d", &c);
fscanf(ifp, "%d", &b);
fscanf(ifp, "%d", &a);
fscanf(ifp, "%d", &d);
// close file
fclose(ifp);
// decrypt the numbers
if(a-38 == 0)
a = 0;
if(b-25 == 0)
b = 0;
if(c-12 == 0)
c = 0;
if(d-14 == 0)
d = 0;
if(a != 0)
a = a - 38 / 5;
if(b != 0)
b = b - 25 / 7;
if(c != 0)
c = c - 12 / 3;
if(d != 0)
d = d - 14 / 9;
// Stores the real answer and the user's board, respectively.
int answer[NUM_PEGS];
int board[NUM_PEGS];
// Set everything up.
answer[0] = a;
answer[1] = b;
answer[2] = c;
answer[3] = d;
greeting();
} else {
// print invalid entry
printf("Your choice was not valid. Next time choose either 1 or 2.\nGoodbye!\n");
system("PAUSE");
exit(0);
}
}
// Loop through each turn, ending at 10 moves or a win.
do {
// Read in the user's guess.
getUserGuess(board);
// Figure out the number of matches.
int num_perfect = numPerfectMatches(board, answer);
int num_imperfect = numWrongPlaceMatches(board, answer);
// Update for this turn.
printf("You have %d perfect matches and %d imperfect matches.\n", num_perfect, num_imperfect);
num_turns++;
} while (num_turns < MAX_TURNS && numPerfectMatches(board, answer) < NUM_PEGS);
// Winning case.
if (numPerfectMatches(board, answer) == NUM_PEGS) {
int end = time(0);
newLeader(leader_time, leader_turns, num_turns, end-start, leader_name);
printWinner(num_turns, end-start);
}
// Losing case.
else {
printf("Sorry, you have exceeded the maximum number of turns. You lose.\n");
printf("Here is the winning board: ");
printArray(answer, NUM_PEGS);
printf("\n");
}
system("PAUSE");
return 0;
}
// Pre-conditions: board is uninitialized and of size NUM_PEGS.
// Post-conditions: board will be filled in randomly with values ranging from
// 0 to NUM_COLORS-1.
void fillBoard(int board[]) {
// initialize the variable
int i;
// fill board with random numbers from 0 to num_colors-1
for(i=0; i<NUM_PEGS; i++)
board[i] = rand()%NUM_COLORS;
}
// Pre-conditions: board and answer are of length NUM_PEGS and store the player's
// guess and the correct board, respectively.
// Post-conditions: returns the number of pegs that match at the correct spots.
int numPerfectMatches(int board[], int answer[]) {
// initialize the variables
int i, matches = 0;
// if what the user guessed matches the answer exactly, add one to amount of matches
for(i=0; i<NUM_PEGS; i++) {
if(board[i] == answer[i])
matches++;
}
return matches;
}
// Pre-conditions: None.
// Post-conditions: Prints out a greeting for the beginning of the game.
void greeting() {
// print the whole greeting
printf("At each turn, you will enter your guess for the playing board.\n");
printf("A valid guess has 4 values in between 0 and 5.\n");
printf("Each guess will have each number within the guess separated by a space.\n");
printf("When you are ready, enter your first guess.\n");
printf("From that point on, you will be told how many perfect and imperfect matches you have.\n");
printf("After this message, you should guess again. You have 10 chances, good luck!\n");
}
// Pre-conditions: board is of length NUM_PEGS
// Post-conditions: NUM_PEGS integers are read in from the user and stored in
// board in the natural order.
void getUserGuess(int board[]) {
// initialize the variable
int i;
// keep scanning for intigers for as many numbers as the array is long
for(i=0; i<NUM_PEGS; i++){
scanf("%d", &board[i]);
}
}
// Pre-conditions: board and answer are of length NUM_PEGS and store the player's
// guess and the correct board, respectively.
// Post-conditions: returns the number of pegs that match at INCORRECT spots
// after "erasing" those pegs that match at correct spots.
int numWrongPlaceMatches(int board[], int answer[]) {
// initialize the variables
int tempboard[NUM_PEGS], tempanswer[NUM_PEGS], i, x, matches = 0, matching[NUM_COLORS];
// Create temporary copies of both boards, since we'll need to make changes
// to each during this process and we don't want to ruin the original
// state of either board.
copyArray(tempboard, board, NUM_PEGS);
copyArray(tempanswer, answer, NUM_PEGS);
// Mark out the spots on the board and answer that match up perfectly.
markOutCorrect(tempboard, tempanswer);
// Go through the board and try to match each peg on the board to
// a spot on the answer. Hint: A double loop is needed.
// Note: Remember to "mark" an answer when a match is found.
// loop for each board and answer array integer
for(i=0; i<NUM_PEGS; i++) {
for(x=0; x<NUM_PEGS; x++) {
// if the answers match and they are not marked, add one to matches and mark them
if(tempboard[i] == tempanswer[x] && tempboard[i] >= 0){
matches++;
tempboard[i] = MARKED_BOARD;
tempanswer[x] = MARKED_ANSWER;
}
}
}
return matches;
}
// Pre-conditions: dest and source are both have the given length.
// Post-conditions: All values from source are copied into the corresponding
// locations in dest.
void copyArray(int dest[], int source[], int length) {
// initialize the variable
int i;
// for the length of the array, copy each number from source to dest
for(i=0; i<length; i++) {
dest[i] = source[i];
}
}
// Pre-conditions: board and answer are of length NUM_PEGS.
// Post-conditions: For each corresponding slot that matches in both boards,
// the slots are changed to equal each board's appropriate
// marker.
void markOutCorrect(int board[], int answer[]) {
// initialize the variable
int i;
// where the board number is same as the answer number, change both to their appropriate marker
for(i=0; i<NUM_PEGS; i++) {
if(board[i] == answer[i]) {
board[i] = MARKED_BOARD;
answer[i] = MARKED_ANSWER;
}
}
}
// Pre-conditions: array has the given length.
// Post-conditions: each value of array is printed, separated by a space.
void printArray(int array[], int length) {
// initialize the variable
int i;
// print each number in the array with a space after it
for(i=0; i<length; i++){
printf("%d ", array[i]);
}
}
// Pre-conditions: num_turns is the number of turns it took the winner to win,
// and num_seconds is the total amount of time they took to
// win in seconds.
// Post-conditions: A winning message is printed stating the number of moves
// and amount of time taken to win in M:SS format.
void printWinner(int num_turns, int num_seconds) {
// initialize the variable
int num_minutes;
// calculate number of minutes and seconds
num_minutes = num_seconds/60;
num_seconds = num_seconds%60;
// print out the congrats line
printf("You have won the game in %d turns, and in %d:%02d!!!\n", num_turns, num_minutes, num_seconds);
}
// Pre-conditions: leader_time and leader_turns are passed along with num_turns and end-start
// Post-conditions: leader_time and end-start are compared to see which is bigger (if a new leader was set)
// and if end-start is less, then the file is written to make that the new leader
void newLeader(int leader_time, int leader_turns, int num_turns, int time, char* leader_name) {
int name;
if(leader_turns > num_turns) {
char name[30];
// print the congrats letter
printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
printf("What is your name? (up to 30 characters long)\n");
scanf("%s", name);
// open file for writing and change times to new times
FILE *ifp;
ifp = fopen("leader.txt", "w+");
fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
// close file
fclose(ifp);
} else if(leader_turns == num_turns && leader_time > time) {
char name[30];
// print the congrats letter
printf("Congrats! You beat the old leader (%s) who won in %d turns and had a time of %d:%02d!\nYou are now the new leader!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
printf("What is your name? (up to 30 characters long)\n");
scanf("%s", name);
// open file for writing and change times to new times
FILE *ifp;
ifp = fopen("leader.txt", "w+");
fprintf(ifp, "%d %d %d %s", time/60, time%60, num_turns, name);
// close file
fclose(ifp);
} else {
printf("The leader (%s) won the game in %d turns, and in %d:%02d!!!\n", leader_name, leader_turns, leader_time/60, leader_time%60);
}
}