Code:
#include <stdio.h>
#include <string.h>
#include <time.h>
/*
* List of animals that the user can select for the game.
* Below the animal names are characteristics for each animal listed in the same order.
* Each entry should be separated by a space and spelled in all lowercase.
*/
#define ANIMALS_LIST "giraffe trout tiger elephant jellyfish eagle piranha hummingbird parrot dolphin terns zebra chipmunk bass bluejay skunk wolf bear reindeer leopard ladybug robin outter caribou boar polarbear snowyowl rockptarimigan dalmation housecat"
#define LIGHT_ANIMALS "0 1 0 0 1 1 1 1 1 0 1 0 1 1 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1"
#define CARNIVORES "0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 1 0 1 1"
#define HERBIVORES "1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0"
#define SWIMMING_ANIMALS "0 1 0 0 1 0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0"
#define FLYING_ANIMALS "0 0 0 0 0 1 0 1 1 0 1 0 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0"
#define FOREST_ANIMALS "0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 0"
#define JUNGLE_ANIMALS "0 1 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0"
#define STRIPED_ANIMALS "0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1"
#define SPOTTED_ANIMALS "1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 1 0"
#define TUNDRA_ANIMALS "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 0 0"
/*
* Each entry in the list is separated by a space.
*/
#define ANIMAL_DELIMITER " "
/*
* The total number of animals determines the amount of memory used by the program.
*/
#define TOTAL_ANIMALS 30
/*
* Wait for user to type this before continuing with the game.
*/
#define CONTINUE_KEY "g"
/*
* The user must type this to indicate a yes answer.
*/
#define YES_KEY "y"
/*
* The user should type this to indicate a no answer.
* But, any answer other than yes could be considered to be a no answer.
*/
#define NO_KEY "n"
/*
*The user should type this to indicate they want to quit
*/
#define EXIT_KEY "q"
/*
* Amount of characters for the user to type their answers.
*/
#define BUFFER_SIZE 32
/*
* Turn off debugging output by setting this to zero.
* Any non-zero value will turn debugging on.
*/
#define DEBUG_STATUS 1
/*
* Global array to store all the animals in the list.
*/
char* animals_list[ TOTAL_ANIMALS ] = { NULL };
/*
* Global array to store animals which live in the jungle (using the same index order).
*/
int jungle_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which are herbivores (using the same index order).
*/
int herbivores[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which swim (using the same index order).
*/
int swimming_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which fly (using the same index order).
*/
int flying_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which are light in weight (using the same index order).
*/
int light_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which are carnivores (using the same index order).
*/
int carnivores[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which are striped (using the same index order).
*/
int striped_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which live in forest areas (using the same index order).
*/
int forest_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which live in tundra areas (using the same index order).
*/
int tundra_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Global array to store animals which are spotted (using the same index order).
*/
int spotted_animals[ TOTAL_ANIMALS ] = { 0 };
/*
* Please see function definitions for description of function prototypes.
*/
void setupGameData();
void startGame();
void askUserQuestion( int, char*, int* );
void displayRemainingAnimals();
int countRemainingAnimals();
char* findLastAnimal();
/*
* Start of the program.
*/
int main( void )
{
/* Variable to indicate that the game should continue */
int continue_game = 1;
/* Initialize the number of attempts to zero */
int guesses = 0;
char buffer[ BUFFER_SIZE ];
time_t start_time, end_time;
setupGameData();
startGame();
/* Start timing the game session */
start_time = time( NULL );
printf( "\nGame started at %s\n", ctime( &start_time ) );
/* Start the main loop to play the game */
do
{
/* Increment the attempts counter by 1 */
guesses++;
switch ( guesses )
{
case 1:
askUserQuestion( guesses, "\nAttempt %d: Can you pic up your animal? ", light_animals );
break;
case 2:
askUserQuestion( guesses, "\nAttempt %d: Is your animal a carivore? ", carnivores );
break;
case 3:
askUserQuestion( guesses, "\nAttempt %d: Does your animal eat only plants? ", herbivores );
break;
case 4:
askUserQuestion( guesses, "\nAttempt %d: Can your animal swim? ", swimming_animals );
break;
case 5:
askUserQuestion( guesses, "\nAttempt %d: Does your animal fly? ", flying_animals );
break;
case 6:
askUserQuestion( guesses, "\nAttempt %d: Does your animal live in forest areas? ", forest_animals );
break;
case 7:
askUserQuestion( guesses, "\nAttempt %d: Does your animal live in jungle areas? ", jungle_animals );
break;
case 8:
askUserQuestion( guesses, "\nAttempt %d: Does your animal have stripes? ", striped_animals );
break;
case 9:
askUserQuestion( guesses, "\nAttempt %d: Does your animal have spots? ", spotted_animals );
break;
case 10:
askUserQuestion( guesses, "\nAttempt %d: Does your animal live in tundra areas? ", tundra_animals );
break;
default :
/* Losing end of game condition */
printf( "\nYou win, I'm out of ideas!\n" );
/* Stop the game */
continue_game = 0;
break;
}
if ( DEBUG_STATUS )
displayRemainingAnimals();
/* Winning end of game condition */
if ( countRemainingAnimals() == 1 )
{
printf( "\nIt took %d attempts to guess your animal, %s!\n", guesses, findLastAnimal() );
/* Stop the game */
continue_game = 0;
}
} while ( continue_game );
/* Stop timing the game session */
end_time = time( NULL );
printf( "\nGame ended at %s\n", ctime( &end_time ) );
/* Unix convention is to return zero from main for normal program exit */
return 0;
}
/*
* setupGameData : Parses the list of animals and characteristics.
*/
void setupGameData()
{
char* animal;
int index;
/* Start the process to parse the list of animals and characteristics */
animal = strtok( strdup( ANIMALS_LIST ), ANIMAL_DELIMITER );
/* Go through the list of animals until the end of the list is found, indicated by a NULL value */
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
/* Assign the individual animal into the appropriate index */
animals_list[ index ] = animal;
/* Continue to the next animal */
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that are light in weight */
animal = strtok( strdup( LIGHT_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
light_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that are carnivores */
animal = strtok( strdup( CARNIVORES ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
carnivores[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for herbivores */
animal = strtok( strdup( HERBIVORES ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
herbivores[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update charactertistic for swimming animals */
animal = strtok( strdup( SWIMMING_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
swimming_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for flying animals */
animal = strtok( strdup( FLYING_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
flying_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that live in the forest */
animal = strtok( strdup( FOREST_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
forest_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that live in the jungle */
animal = strtok( strdup( JUNGLE_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
jungle_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that are striped */
animal = strtok( strdup( STRIPED_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
striped_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that are spotted */
animal = strtok( strdup( SPOTTED_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
spotted_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
/* Update characteristic for animals that live in the tundra */
animal = strtok( strdup( TUNDRA_ANIMALS ), ANIMAL_DELIMITER );
for ( index = 0; ( index < TOTAL_ANIMALS ) && ( animal != NULL ); index++ )
{
tundra_animals[ index ] = atoi( animal );
animal = strtok( NULL, ANIMAL_DELIMITER );
}
}
/*
* startGame : Display game instructions and list of available animals for the user to select.
* If debug is on, also display the list of animals and characteristics.
*/
void startGame()
{
char buffer[ BUFFER_SIZE ];
int index;
do
{
printf( "\nPick one of the following animals:\n\n" );
for ( index = 0; index < TOTAL_ANIMALS; index++ )
printf( "%s ", animals_list[ index ] );
printf( "\n\nPress '%s' when you're ready and I will try to guess the animal: ", CONTINUE_KEY );
scanf( "%s", buffer );
} while ( strncmp( buffer, CONTINUE_KEY, 1 ) != 0 );
if ( DEBUG_STATUS )
{
/* Go through and display the list of animals and characteristics */
for ( index = 0; index < TOTAL_ANIMALS; index++ )
printf( "%s: %d %d %d %d \n", animals_list[ index ], jungle_animals[ index ], herbivores[ index ], swimming_animals[ index ], flying_animals[ index ] );
}
}
/*
* askUserQuestion : Ask the user questions about the animal
*
* Parameters : Number of current attempt
* Text of the question
* Array of data for that question
*/
void askUserQuestion( int guessNumber, char* question, int* animalData )
{
char buffer[ BUFFER_SIZE ];
int index;
printf( question, guessNumber );
printf( "Type '%s' if yes '%s' if no : ", YES_KEY, NO_KEY );
/* Wait for the user answer */
scanf( "%s", buffer );
/* Go through the list of remaining animals and take action based on the user answer */
for ( index = 0; index < TOTAL_ANIMALS; index++ )
{
/* Only process if there is an animal at that location in the array */
if ( animals_list[ index ] != NULL )
{
if ( strncmp( buffer, YES_KEY, 1 ) == 0 )
{
/* If the user answer is yes, then remove animals do not match */
if ( animalData[ index ] != 1 )
animals_list[ index ] = NULL;
}
else
{
/* If the user answer is no, then remove animals which match */
if ( animalData[ index ] == 1 )
animals_list[ index ] = NULL;
}
}
}
}
/*
* displayRemainingAnimals : Display the list of possible animals remaining.
*/
void displayRemainingAnimals()
{
int index;
printf( "\nAnimals remaining: " );
for ( index = 0; index < TOTAL_ANIMALS; index++ )
{
if ( animals_list[ index ] != NULL )
printf( "%s ", animals_list[ index ] );
}
printf( "\n" );
}
/*
* countRemainingAnimals : Count the list of possible animals remaining.
*
* Returns the number counted.
*/
int countRemainingAnimals()
{
int animals_remaining = 0;
int index;
for ( index = 0; index < TOTAL_ANIMALS; index++ )
{
if ( animals_list[ index ] != NULL )
animals_remaining++;
}
return animals_remaining;
}
/*
* findLastAnimal : Find the last animal on the list.
*
* Returns the animal found.
*/
char* findLastAnimal()
{
int index;
for ( index = 0; index < TOTAL_ANIMALS; index++ )
{
if ( animals_list[ index ] != NULL )
return animals_list[ index ];
}
return NULL;
}