Code:
#include <stdio.h>
#include <time.h>
#include <math.h>
const int GUESSING_GAME = 1;
const int SQUARE_GAME = 2;
const int SEE_SCORE = 3;
const int QUIT = 4;
const int SIZE = 3;
const int MAX_SQUARE_VALUE = 20;
const int DEFAULT_MAX_GUESS = 100;
const int MAX_RAND_VALUE = 32767;
const int INVALID = -1;
int menu();
int getGuessScore(int max, int numguesses);
int guessGame(int max);
int winningSquare(int square[][SIZE]);
void fillSquare(int square[][SIZE]);
void printSquare(int square[][SIZE]);
int checkRows(int square[][SIZE]);
int checkCols(int square[][SIZE]);
int getSum(int square[][SIZE]);
int validRowCol(int row, int col);
int getSquareScore(int square[][SIZE], int first_sum, int num_turns);
int playSquareGame();
int main(void)
{
srand(time(0));
int total = 0, choice;
choice = menu();
// Loop until the user quits.
while (choice != QUIT)
{
// Execute the guessing game.
if (choice == GUESSING_GAME)
{
int max;
printf("What do you want the maximum value in the guessing game to be?\n");
scanf("%d", &max);
// If the user chooses an invalid max, reset the game to 100.
if (max < 2 || max > MAX_RAND_VALUE) {
printf("Sorry, you chose an invalid maximum, you'll play with a maximum of 100.\n");
max = DEFAULT_MAX_GUESS;
}
total += guessGame(max);
}
// Play the square game.
else if (choice == SQUARE_GAME)
{
total += playSquareGame();
}
// Just print out the user's score.
else if (choice == SEE_SCORE)
{
printf("Your current score is %d.\n", total);
}
// Get the user's next choice.
choice = menu();
}
// Print out the final score.
printf("Your final score is %d.\n", total);
return 0;
}
// Precondition(s): None
// Postcondition(s): Prompts the user with the menu and continues to read in their choice until they
// enter a valid choice in between 1 and 4, which then gets returned.
int menu()
{
int pick;
printf("Please enter your choice from one of the following options.\n");
printf("1. Play the guessing game.\n");
printf("2. Play the square game.\n");
printf("3. View your current score.\n");
printf("4. Quit.\n");
while(1)
{
int choice = 0;
scanf("%d", &choice);
if(choice < 1 || choice > 4) //If the user-inputted choice is not a correct value on the menu, return an error message.
{
printf("Sorry, that is not a valid choice. Please try again.\n");
}
else
{
return choice;
break; //If the user-inputted choice is a correct value on the menu, break out of the loop.
}
}
}
// Precondition(s): 1 < max < 32767
// Postcondition(s): Generates a random number in the range 1 to max, inclusive, and allows the
// user to guess the number. After each guess, the user is told to guess lower or
// higher, until they guess the correct number. At this point, their score is
// returned, which is based upon the number of guesses it took them to guess the
// secret number.
int guessGame(int max)
{
int guess, secret_num, num_guesses;
num_guesses = 0;
secret_num = 1 + rand()%max;
while (guess != secret_num) //While the user-inputted guess does not equal the secret number...
{
printf("Please enter your guess (1 - %d).\n", max); //Asks the user for a new guess within the range of numbers each time it is wrong.
scanf("%d", &guess);
if (guess > secret_num) //If the guess is larger than the secret number...
{
printf("Sorry your guess is too high.\n");
}
else if (guess < secret_num) //If the guess is lower than the secret number...
{
printf("Sorry your guess is too low.\n");
}
num_guesses = num_guesses++; //Keeps track of the total number of guesses made.
}
printf("You got the number in %d turns.\n", num_guesses);
int score = getGuessScore(max, num_guesses); //Calculates the score by calling the function "getGuessScore"
printf("You scored %d points for the guessing game this time!\n", score);
return score; //Returns the value of score so it can be added to the total for the session.
}
// Precondition(s): 1 < max < 32767, represents the maximum possible number in the guessing game, and
// numguesses represents the number of guesses needed for a guessing game with the
// range of choices from 1 to max, inclusive.
// Postcondition(s): Returns the score for the instance of the guessing game described.
int getGuessScore(int max, int num_guesses)
{
// Best we can guarantee in a game, using binary search.
int best = (int)ceil(log(max+1)/log(2));
// The score is better, the fewer guesses you make.
int score = 2*best - num_guesses;
// This is so we can avoid giving out negative scores.
if (score < 0)
{
score = 0;
}
return score;
}
// Precondition(s): square has dimensions SIZE x SIZE
// Postcondition(s): square is randomly filled with numbers in between 1 and MAX.
void fillSquare(int square[][SIZE])
{
int row, col;
square[SIZE][SIZE];
for(row = 0; row < SIZE; row++)
{
for(col = 0; col < SIZE; col++)
{
square[row][col] = rand()% MAX_SQUARE_VALUE + 1; //Assigns a random value to every element in the array.
}
}
}
// Precondition(s): square has dimensions SIZE x SIZE
// Postcondition(s): prints out the square in SIZE rows,
// in a format with 4 spaces per entry, right justified.
void printSquare(int square[][SIZE])
{
int row, col;
square[SIZE][SIZE];
for(row = 0; row < SIZE; row++)
{
for(col = 0; col < SIZE; col++)
{
printf("%4d", square[row][col]); //Prints out the elements of the arrays and 4 spaces after each element, right justified.
}
printf("\n");
}
}
// Precondition(s): square has dimensions SIZE x SIZE
// Postconditions(s): If all SIZE rows add up to the same value, this value is returned.
// Otherwise, -1 is returned to indicate at least 2 different row sums.
int checkRows(int square[][SIZE])
{
int row1, row2, row3;
row1 = (square[0][0] + square[0][1] + square[0][2]);
row2 = (square[1][0] + square[1][1] + square [1][2]);
row3 = (square[2][0] + square[2][1] + square [2][2]);
if((row1 == row2) && (row1 == row3) && (row2 == row3))
{
return row1;
}
else
{
return INVALID;
}
}
// Precondition(s): square has dimensions SIZE x SIZE.
// Postconditions(s): Returns 1 if all the rows and columns of square add to the same value.
// Returns 0 otherwise.
int winningSquare(int square[][SIZE])
{
int sum_rows = checkRows(square[SIZE][SIZE]);
int sum_cols = checkCols(square[SIZE][SIZE]);
if(sum_rows == sum_cols && sum_rows + sum_cols != -2)
{
return 1;
}
else
{
return 0;
}
}
// Precondition(s): square has dimensions SIZE x SIZE.
// Postconditions(s): If all SIZE columns add up to the same value, this value is returned.
// Otherwise, -1 is returned to indicate at least 2 different column sums.
int checkCols(int square[][SIZE])
{
int col1, col2, col3;
col1 = (square[0][0] + square[1][0] + square[2][0]);
col2 = (square[0][1] + square[1][1] + square [2][1]);
col3 = (square[0][2] + square[1][2] + square [2][2]);
if((col1 == col2) && (col1 == col3) && (col2 == col3))
{
return col1;
}
else
{
return INVALID;
}
}
// Precondition(s): square has dimensions SIZE x SIZE.
// Postconditions(s): Returns the sum of all the integers stored in square.
int getSum(int square[][SIZE])
{
}
// Precondition(s): None
// Postcondition(s): Executes the square game and returns the user's score.
int playSquareGame()
{
int score = 0;
int square[SIZE][SIZE];
fillSquare(square); //Fills the square with random values between 1 and 20.
printSquare(square); //Prints out the square with the assigned random values.
int row_choice, col_choice, value;
int win = 0, num_turns = 0;
while(win != 1)
{
win = winningSquare(square);
value = 0;
while(value != 1) //While the choice for row and column is not a valid value, return an error message and prompt user for new input.
{
printf("Enter the row (0-2) and column (0-2) of the square you want to change.\n");
scanf("%d%d", &row_choice, &col_choice);
value = validRowCol(row_choice, col_choice); //Calls the validRowCol function to check if user-inputted choice for row and column is a valid value.
if(value == 1) //If the row and column choice is a valid value, break out of the loop.
{
break;
}
else
{
printf("Sorry, those values are not in between 0 and 2.\n");
}
}
int new_value;
while(1)
{
printf("What is the new value?\n");
scanf("%d", &new_value);
if(new_value > 20 || new_value < 1) //If the user-inputted new value is not between 1 and 20, return an error message and scan new user input.
{
printf("Sorry, that value is not between 1 and 20.\n");
}
else
{
square[row_choice][col_choice] = new_value;
printSquare(square);
break;
num_turns++;
}
}
}
}
// Precondition(s): none
// Postcondition(s): Returns 1 if 0 <= row < SIZE and 0 <= col < SIZE. Returns 0 otherwise.
int validRowCol(int row, int col)
{
if((row < 0 || row > 2) || (col < 0 || col > 2)) //If the row and column are not valid values, return the value of 0.
{
return 0;
}
else //If the row and column ARE valid values, return the value of 1.
{
return 1;
}
}
// Precondition(s): square is the end result of the square game, first_sum is the
// original sum of the values in the square at the starting of that
// instance of the square game and num_turns is the number of turns
// taken in that instance of the square game.
// Postcondition(s): The score of the given instance of the square game is returned.
int getSquareScore(int square[][SIZE], int first_sum, int num_turns)
{
// Calculate the difference in sum between the original and winning square.
int new_sum = getSum(square);
int diff = abs(new_sum - first_sum);
// Calculate the number of squares that didn't have to be changed, assuming that each
// square was changed only once.
int turn_diff = SIZE*SIZE - num_turns;
// Don't let this fall below 0.
if (turn_diff < 0)
turn_diff = 0;
// This is the turn difference plus a weighted value that ranges from 0 to SIZE x SIZE.
// The weighting is based on what percentage the difference of the sum of the square is
// from the original sum of the square. The lower the percentage, the closer your score
// is to SIZE x SIZE.
return turn_diff + SIZE*SIZE*(first_sum - diff)/first_sum;
}