// AmericanRoundup.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "AmericanRoundup.h"
#include "Animals.h"
#include "Player.h"
#include "Map.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Compile as a CONSOLE application or straight DOS16/32 application

// I N C L U D E S ///////////////////////////////////////////////////////////

#include <io.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <fcntl.h>
#include <memory.h>
#include <malloc.h>
#include <math.h>
#include <string.h>
#include <ctype.h>


// D E F I N E S /////////////////////////////////////////////////////////////

// game action constants     

#define FAILED_ATTACK_FOOD_LOSS 2
#define MAX_ANIMALS             50

// language details

#define MAX_TOKENS             200
#define NUM_TOKENS             140

#define FIRST_WORD             0
#define SECOND_WORD            1
#define THIRD_WORD             2
#define FOURTH_WORD            3
#define FIFTH_WORD             4

// define actions (verbs)

#define ACTION_START			200	

#define ACTION_HELP            200
#define ACTION_EXIT            201
#define ACTION_CAPITAL         202
#define ACTION_FEED            203
#define ACTION_CHOOSE          204
#define ACTION_INVENTORY       205
#define ACTION_CAPTURE         206
#define ACTION_SCORE           207
#define ACTION_MOVE            208
#define ACTION_GO              208
#define ACTION_STATUS          209
#define ACTION_LOOK            210
#define ACTION_SAVE            211
#define ACTION_END             211

// articles

#define ART_START              300
#define ART_THE                300
#define ART_END                300

// prepositions

#define PREP_START             325

#define PREP_IN                325
#define PREP_ON                326
#define PREP_TO                327
#define PREP_NEW               328

#define PREP_END               328

// parameters

#define PARAM_START              0

#define PARAM_1                  1 
#define PARAM_2                  2 
#define PARAM_3                  3 
#define PARAM_4                  4 
#define PARAM_5                  5 
#define PARAM_6                  6 
#define PARAM_7                  7 
#define PARAM_8                  8 
#define PARAM_9                  9 
#define PARAM_10                 10
#define PARAM_11                 11
#define PARAM_12                 12
#define PARAM_13                 13
#define PARAM_14                 14
#define PARAM_15                 15
#define PARAM_16                 16
#define PARAM_17                 17
#define PARAM_18                 18
#define PARAM_19                 19

#define PARAM_END               19

// state prefixes

#define PREFIX_START           500
#define PREFIX_NORTH           500
#define PREFIX_SOUTH           501
#define PREFIX_END             501

// the phrases that add meaning to us, but not to the computer

#define PHRASE_TO              0
#define PHRASE_THE             1
#define PHRASE_TO_THE          2

// S T R U C T U R E S ///////////////////////////////////////////////////////

// this is the structure for a single token

typedef struct token_typ
        {

        char symbol[16];   // the string that represents the token
        int value;         // the integer value of the token

        } token, *token_ptr;



// P R O T O T Y P E S //////////////////////////////////////////////////////

void Introduction();

void PauseForSeconds(int SecondsToPause);

void CheckForWinner();

int Check_For_Phrase(int phrase,int index);

char *Get_Line(char *buffer);

int Get_Token(char *input,char *output,int *current_pos);

int Extract_Tokens(char *string);

void Verb_Parser(void);

int Verb_HELP(void);

int Verb_EXIT(void);

int Verb_CAPITAL(void);

int Verb_FEED(void);

int Verb_CHOOSE(void);

int Verb_INVENTORY(void);

int Verb_CAPTURE(void);

int Verb_SCORE(void);

int Verb_GO(void);

int Verb_STATUS(void);

int Verb_LOOK(void);

int Verb_SAVE(void);
// G L O B A L S //////////////////////////////////////////////////////////////

// this is the entire "language" of the language.

token language[MAX_TOKENS] = {

 {"HELP",      ACTION_HELP     },
 {"EXIT",      ACTION_EXIT     },
 {"CAPITAL",   ACTION_CAPITAL  },
 {"FEED",      ACTION_FEED     },
 {"CHOOSE",    ACTION_CHOOSE   },
 {"SELECT",    ACTION_CHOOSE   },
 {"INVENTORY", ACTION_INVENTORY},
 {"ANIMALS",   ACTION_INVENTORY},
 {"CAPTURE",   ACTION_CAPTURE  },
 {"SCORE",     ACTION_SCORE    },
 {"MOVE",      ACTION_MOVE     },
 {"GO",        ACTION_GO       },
 {"STATUS",    ACTION_STATUS   },
 {"LOOK",      ACTION_LOOK     },
 {"SAVE",      ACTION_SAVE     },
 {"1",         PARAM_1         },
 {"2",         PARAM_2         },
 {"3",         PARAM_3         },
 {"4",         PARAM_4         },
 {"5",         PARAM_5         },
 {"6",         PARAM_6         },
 {"7",         PARAM_7         },
 {"8",         PARAM_8         },
 {"9",         PARAM_9         },
 {"10",        PARAM_10        },
 {"11",        PARAM_11        },
 {"12",        PARAM_12        },
 {"13",        PARAM_13        },
 {"14",        PARAM_14        },
 {"15",        PARAM_15        },
 {"16",        PARAM_16        },
 {"17",        PARAM_17        },
 {"18",        PARAM_18        },
 {"19",        PARAM_19        },
 {"THE",       ART_THE         },
 {"IN",        PREP_IN         },
 {"ON",        PREP_ON         },
 {"TO",        PREP_TO         },
 {"NEW",       PREP_NEW        },
 {"ALABAMA",   STATE_ALABAMA   },
 {"ALASKA",	   STATE_ALASKA    },
 {"ARIZONA",   STATE_ARIZONA   },   
 {"ARKANSAS",  STATE_ARKANSAS  },   
 {"CALIFORNIA",STATE_CALIFORNIA},   
 {"COLORADO",  STATE_COLORADO  },  
 {"CONNECTICUT", STATE_CONNECTICUT},  
 {"DELAWARE",  STATE_DELAWARE  },
 {"FLORIDA",   STATE_FLORIDA   },  
 {"GEORGIA",   STATE_GEORGIA   },   
 {"HAWAII",    STATE_HAWAII    },
 {"IDAHO",     STATE_IDAHO     },
 {"ILLINOIS",  STATE_ILLINOIS  },
 {"INDIANA",   STATE_INDIANA   },
 {"IOWA",      STATE_IOWA      },
 {"KANSAS",    STATE_KANSAS    },   
 {"KENTUCKY",  STATE_KENTUCKY  },
 {"LOUISIANA", STATE_LOUISIANA },
 {"MAINE",     STATE_MAINE     },
 {"MARYLAND",  STATE_MARYLAND  },
 {"MASSACHUSETTS", STATE_MASSACHUSETTS},
 {"MICHIGAN",  STATE_MICHIGAN  },  
 {"MINNESOTA", STATE_MINNESOTA },  
 {"MISSISSIPPI", STATE_MISSISSIPPI },
 {"MISSOURI",  STATE_MISSOURI  },
 {"MONTANA",   STATE_MONTANA   },
 {"NEBRASKA",  STATE_NEBRASKA  },
 {"NEVADA",    STATE_NEVADA    },
 {"HAMPSHIRE", STATE_NEW_HAMPSHIRE},
 {"JERSEY",    STATE_NEW_JERSEY},
 {"MEXICO",    STATE_NEW_MEXICO},
 {"YORK",      STATE_NEW_YORK  },
 {"NORTH",     PREFIX_NORTH    },
 {"SOUTH",     PREFIX_SOUTH    },
 {"CAROLINA",  STATE_NORTH_CAROLINA},
 {"DAKOTA",    STATE_NORTH_DAKOTA},
 {"OHIO",      STATE_OHIO      },
 {"OKLAHOMA",  STATE_OKLAHOMA  },
 {"OREGON",    STATE_OREGON    },
 {"PENNSYLVANIA", STATE_PENNSYLVANIA },
 {"RHODE",     STATE_RHODE_ISLAND},
 {"TENNESSEE", STATE_TENNESSEE },
 {"TEXAS",     STATE_TEXAS     },
 {"UTAH",      STATE_UTAH      },
 {"VERMONT",   STATE_VERMONT   },
 {"VIRGINIA",  STATE_VIRGINIA  },
 {"WASHINGTON",STATE_WASHINGTON},
 {"WEST",      STATE_WEST_VIRGINIA},
 {"WISCONSIN", STATE_WISCONSIN },
 {"WYOMING",   STATE_WYOMING   },
 {"KITTY",     ANIMAL_KITTY    },
 {"CAT",       ANIMAL_CAT      },
 {"COUGAR",    ANIMAL_COUGAR   },
 {"CUB",       ANIMAL_CUB      },
 {"BEAR",      ANIMAL_BEAR     },
 {"GRIZZLY",   ANIMAL_GRIZZLY  },
 {"CHIPMUNK",  ANIMAL_CHIPMUNK },
 {"WEASEL",    ANIMAL_WEASEL   },
 {"WOLVERINE", ANIMAL_WOLVERINE},
 {"DOG",       ANIMAL_DOG      },
 {"COYOTE",    ANIMAL_COYOTE   },
 {"WOLF",      ANIMAL_WOLF     },
 {"CHICK",     ANIMAL_CHICK    },
 {"SPARROW",   ANIMAL_SPARROW  },
 {"EAGLE",     ANIMAL_EAGLE    },
 {"GOSLING",   ANIMAL_GOSLING  },
 {"GOOSE",     ANIMAL_GOOSE    },
 {"PELICAN",   ANIMAL_PELICAN  },
 {"ROBIN",     ANIMAL_ROBIN    },
 {"OWL",       ANIMAL_OWL      },
 {"FALCON",    ANIMAL_FALCON   },
 {"PIGEON",    ANIMAL_PIGEON   },
 {"GULL",      ANIMAL_GULL     },
 {"HERON",     ANIMAL_HERON    },
 {"CALF",      ANIMAL_CALF     },
 {"BULL",      ANIMAL_BULL     },
 {"BUFFALO",   ANIMAL_BUFFALO  },
 {"KID",       ANIMAL_KID      },
 {"GOAT",      ANIMAL_GOAT     },
 {"RAM",       ANIMAL_RAM      },
 {"FOAL",      ANIMAL_FOAL     },
 {"HORSE",     ANIMAL_HORSE    },
 {"STALLION",  ANIMAL_STALLION },
 {"CHICKEN",   ANIMAL_CHICKEN  },
 {"PEACOCK",   ANIMAL_PEACOCK  },
 {"ROADRUNNER",ANIMAL_ROADRUNNER},
 {"DEER",      ANIMAL_DEER     },
 {"ELK",       ANIMAL_ELK      },
 {"MOOSE",     ANIMAL_MOOSE    },
 {"PORPOSE",   ANIMAL_PORPOISE },
 {"DOLPHIN",   ANIMAL_DOLPHIN  },
 {"WHALE",     ANIMAL_WHALE    },
 {"TUNA",      ANIMAL_TUNA     },
 {"SWORDFISH", ANIMAL_SWORDFISH},
 {"SHARK",     ANIMAL_SHARK    },
 {"NAUTILUS",  ANIMAL_NAUTILUS },
 {"OCTOPUS",   ANIMAL_OCTOPUS  },
 {"SQUID",     ANIMAL_SQUID    },
 {"HATCHLING", ANIMAL_HATCHLING},
 {"TURTLE",    ANIMAL_TURTLE   },
 {"TORTOISE",  ANIMAL_TORTOISE }
};




// now for the definition of the universe and the objects within it

int sentence[8];               // this array holds the current sentence
int num_tokens;                // number of words in current sentecne


int global_exit=0;             // global exit flag

char global_input[128],        // input string
     global_output[128];       // output string


char ranks[20][30] = 
{
	"Beginner?",
	"Collector.",
	"Super Collector!",
	"Expert Collector+",
	"Biologist++",
	"Super Biologist!!",
	"Expert Biologist+++",
	"Zoo Keeper+++!!!",
	"Super Zoo Keeper!!!!",
	"Expert Zoo Keeper+++++!!!!"};

// OBJECTS ////////////////////////////////////////////////////////////////////

CPlayer  ThePlayer;
// CAnimals TheAnimals;
CMap*     Map ;

// F U N C T I O N S //////////////////////////////////////////////////////////

char *Get_Line(char *buffer)
{
// this function gets a single line of input and tolerates white space

int c,index=0;

// loop while user hasn't hit return

while((c=getch())!=13)
     {

// implement backspace

     if (c==8 && index>0)
        {

        buffer[--index] = ' ';
        printf("%c %c",8,8);

        } // end if backspace
     else
     if (c>=32 && c<=122)
        {
        buffer[index++] = c;
        printf("%c",c);

        } // end if in printable range

     } // end while

// terminate string

buffer[index] = 0;

// return pointer to buffer or NULL

if (strlen(buffer)==0)
   return(NULL);
else
return(buffer);

} // end Get_Line

////////////////////////////////////////////////////////////////////////////////

int Get_Token(char *input,char *output,int *current_pos)
{

int index,   // loop index and working index
    start,   // points to start of token
    end;     // points to end of token

// set current positions

index=start=end=*current_pos;

// eat white space

while(isspace(input[index]) || ispunct(input[index]))
     {

     index++;

     } // end while

// test if end of string found

if (input[index]==NULL)
   {
   // emit nothing

   strcpy(output,"");
   return(0);

   } // end if no more tokens

// at this point, we must have a token of some kind, so find the end of it

start = index; // mark front of it
end   = index;

// find end of Token

while(!isspace(input[end]) && !ispunct(input[end]) && input[end]!=NULL)
     {

     end++;

     } // end while

// build up output string

for (index=start; index<end; index++)
    {

    output[index-start] = toupper(input[index]);

    } // end copy string

// place terminator

output[index-start] = 0;

// update current string position

*current_pos  = end;

return(end);

} // end Get_Token

///////////////////////////////////////////////////////////////////////////////

// Original Routine from LaMothe, modified to handle state names which
// can span 2 tokens
//
int Extract_Tokens(char *string)
{
// this function breaks the input string down into tokens and fills up
// the global sentence array with the tokens so that it can be processed

int curr_pos=0,      // current position in string
    curr_token=0,    // current token number
    found,           // used to flag if the token is valid in language
    index;           // loop index

char output[16];

// reset number of tokens and clear the sentence out

num_tokens=0;

for (index=0; index<8; index++)
    sentence[index]=0;

// extract all the words in the sentence (tokens)

while(Get_Token(string,output,&curr_pos))
     {

     // test to see if this is a valid token

     for (index=0,found=0; index<NUM_TOKENS; index++)
         {

         // do we have a match?

         if (strcmp(output,language[index].symbol)==0)
            {
            // set found flag

            found=1;

			// see if token has any meaning, if not don't use it
			if (((language[index].value >= PREP_START) && (language[index].value <= PREP_END)) ||
			    ((language[index].value >= ART_START) && (language[index].value <= ART_END)))
			{
			    	break;
			}		  
			else
			{	 
				// Handle special cases of North/South Dakota/Carolina
				// if this token is Carolina or Dakota 
				//   if last token is South then 
				//      increment last token to point to South state
				//   end if
				//   disregard this token
				// else 
				// enter token into sentence
				if ((language[index].value == STATE_NORTH_CAROLINA) &&
					(sentence[curr_token-1] == PREFIX_NORTH))
				{
					sentence[curr_token-1] = STATE_NORTH_CAROLINA;
					break;
				}
				else if ((language[index].value == STATE_NORTH_DAKOTA) &&
					     (sentence[curr_token-1] == PREFIX_NORTH))
				{
					sentence[curr_token-1] = STATE_NORTH_DAKOTA;
					break;
				}
				else if ((language[index].value == STATE_NORTH_CAROLINA) &&
					     (sentence[curr_token-1] == PREFIX_SOUTH))
				{
					sentence[curr_token-1] = STATE_SOUTH_CAROLINA;
					break;
				}
				else if ((language[index].value == STATE_NORTH_DAKOTA) &&
					     (sentence[curr_token-1] == PREFIX_SOUTH))
				{
					sentence[curr_token-1] = STATE_SOUTH_DAKOTA;
					break;
				}
				else
				{
					sentence[curr_token++] = language[index].value;
					break;
				}
				//    printf("\nEntering %s, %d in sentence",
				//                               output,language[index].value);
	
			}
          } // end if

         } // end for index

         // test if token was part of language (grammar)

         if (!found)
            {
            printf("\nI don't know what \"%s\" means.",output);

            // failure

            return(0);

            } // end if not found

         // else

         num_tokens++;

     } // end while

return(1);

} // end Extract_Tokens

///////////////////////////////////////////////////////////////////////////////

void Verb_Parser(void)
{
// this function breaks down the sentence and based on the verb calls the
// appropriate "method" or function to apply that verb
// note: syntactic analysis could be done here, but I decided to place it
// in the action verb functions, so that you can see the way the errors are
// detected for each verb (even though there is a a lot of redundancy)

// what is the verb?

switch(sentence[FIRST_WORD])
      {

      case ACTION_HELP:
           {
           // call the appropriate function

           Verb_HELP();

           } break;

      case ACTION_EXIT:
           {
           // call the appropriate function

           Verb_EXIT();

           } break;

      case ACTION_CAPITAL:
           {
           // call the appropriate function

           Verb_CAPITAL();

           } break;

      case ACTION_FEED:
           {
           // call the appropriate function

           Verb_FEED();

           } break;

      case ACTION_CHOOSE:
           {
           // call the appropriate function

           Verb_CHOOSE();

           } break;

        case ACTION_INVENTORY:
           {
           // call the appropriate function

           Verb_INVENTORY();

           } break;

		case ACTION_CAPTURE:
           {
           // call the appropriate function

           Verb_CAPTURE();

           } break;

		case ACTION_SCORE:
           {
           // call the appropriate function

           Verb_SCORE();

           } break;

		case ACTION_GO:
           {
           // call the appropriate function

           Verb_GO();

           } break;

		case ACTION_STATUS:
           {
           // call the appropriate function

           Verb_STATUS();

           } break;

		case ACTION_LOOK:
           {
           // call the appropriate function

           Verb_LOOK();

           } break;
		case ACTION_SAVE:
           {
           // call the appropriate function

           Verb_SAVE();

           } break;
      default:
       {
             printf("\nYou must start a sentence with an action verb!");

             return;

             } break;

      } // end switch

} // end Verb_Parser

// THE ACTION VERBS ///////////////////////////////////////////////////////////

int Verb_HELP(void)
{
// this function will list the commands available to the player

 printf("\n");
 printf("LOOK-          Gives description of current location.\n");
 printf("CAPTURE-       Attempt to capture an animal.\n");
 printf("GO state-      Attempt to move to the specified state.\n");
 printf("FEED #-        Feed your currently selected animal # units of food.\n");
 printf("CHOOSE animal- Make animal the currently selected animal.\n");
 printf("CAPITAL-       Ask to guess the capital of the current state.\n");
 printf("SCORE-         Display current score.\n");
 printf("STATUS-        Display game status.\n");
 printf("INVENTORY-     Display animals and food you are carrying.\n");
 printf("SAVE-          Save the current game.\n");
 printf("EXIT-          Quit the current game.\n");

 return (1);
} // end Verb_HELP

////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////

int Verb_EXIT(void)
{
// this function sets the global exit and terminates the game

// Always save the game in case the user pressed
// this by accident
global_exit=1;

return(1);

} // end Verb_EXIT


int Verb_CAPITAL(void)
{
// this function asks the player the name of the capital for
// the state they are in.  If they are right, they are 
// awarded the state's energy                     
//                 

	char buffer[80];
	CState* CurrentState;
	CFood FoodPrize;

	// Get Current State and put in Current_State
	CurrentState = Map->GetCurrentState();

    // if CurrentState has already had energy awarded then
	//   print error message and exit
	if (!CurrentState->HasFood())
	{
		printf("You have already won %s's food prize.\n",CurrentState->GetName());
		return (0);
	}
	// else
	//   prompt user to enter the name of the captial
	//   store the user answer in CapitalName
	//   convert CapitalName to upper case
	//   compare CapitalName to CurrentState->GetCapital
	else
	{
		gets(buffer);
		printf("What is the capital of %s? ",CurrentState->GetName());
		gets(buffer);
		CString CapitalName(buffer);
		CapitalName.MakeUpper();

		//   if they match then
		//     Get food energy from Current_State
		//     Add food to the player
		//     remove food from the Current_State
		//   else
		//     print Capital_Name is not the capital of Current_State->GetName
		//   endif
		if (CString(CapitalName) == CurrentState->GetCapital())
		{
			FoodPrize = CurrentState->GetFood();
			ThePlayer.AddFood(FoodPrize);
			CurrentState->RemoveFood();
			printf("Correct!  You win %d servings of %s food!\n", FoodPrize.GetQuantity(), FoodPrize.GetName()); 
		}
		else
		{
			printf("Sorry, %s.  %s is not the capital of %s.\n", 
				     ThePlayer.GetName(), CapitalName,
					 CurrentState->GetName());
		}  // end if CapitalName == CurrentState->GetCapital
	}  // end if CurrentState->HasFood

	return(1);

} // end Verb_CAPITAL

int Verb_FEED(void)
{
	int AmountFed;

// this function allows the player to feed their currently  
// selected animal the specified amount of food.  The second
// token should be the amount of food.           
//                 
	// Verify the second parameter is a valid number
	if ((sentence[SECOND_WORD] < PARAM_START) ||
		(sentence[SECOND_WORD] > PARAM_END))
	{
	 printf("You must feed a number of servings.\n");
	}
    else
	{
 		 // Call the player feed animal functions
		AmountFed = ThePlayer.FeedAnimal(sentence[SECOND_WORD]);
		if (AmountFed >= 0)
		{
			printf("You feed your animal %d servings of food.\n",AmountFed);
			printf("Your selected animal is ");
			ThePlayer.GetAnimal()->Display();
			printf(".\n");
		}
		else
		{
			printf("You do not have that much food to give your animal.\n");
		}

    }


return(1);

} // end Verb_FEED

int Verb_CHOOSE(void)
{
// this function allows the player to set the currently selected
// animal.  The second token should be an animal that the player
// currently posses.           
//                 
	// If the second token is not an animal, then
	//   display the message, "You must choose an animal you have."
	// Call the player Choose Animal function
	// If the Choose Animal function returns a 0, then
	//   display the message, "You must choose an animal you have."

	if ((sentence[SECOND_WORD] < ANIMAL_START) ||
		(sentence[SECOND_WORD] > ANIMAL_END))
	{
	 printf("You must choose an animal you have.\n");
	}
    else
	{
		// Call the player Choose animal function
		if(ThePlayer.ChooseAnimal(TheAnimals.GetAnimal(AnimalNames(sentence[SECOND_WORD]))) != 0)
		{
			printf("Your selected animal is ");
			ThePlayer.GetAnimal()->Display();
			printf(".\n");
		}
		else
		{
			printf("You must choose an animal you have.\n");
		}
	}

return(1);

} // end Verb_CHOOSE

int Verb_INVENTORY(void)
{
// this function displays the list of items the player is
// holding.
//                 
	// display the message, "You are carrying...."
	// Call the player inventory function
	printf("You are carrying...\n");
    ThePlayer.PrintInventory();
 
	return(1);

} // end Verb_INVENTORY


int Verb_CAPTURE(void)
{
// this function attempts to capture the state's animal with
// the players's currently selected animal. If successful
// then the player is awarded the state's animal.
//                 
// If not successful, then the player's currently selected
// animal loses energy

	CAnimal* Attacker;
	CAnimal* Defender;
	CString  EvolvesFrom;

    // If the current state does not have an animal then 
	//   display the message "You have already captured the animal in state"
	//   return 
	// end if
	if (!Map->GetCurrentState()->HasAnimal())
	{
		printf("You have already captured the animal in %s\n",Map->GetCurrentState()->GetName());
		return(0);
	}

	// Get the currently selected animal from the player and assign it to 
	// Attacker.
	// Get the currently selected animal from the state and assign it to 
	// Defender.
	Attacker = ThePlayer.GetAnimal();
	Defender = Map->GetCurrentState()->GetAnimal();

    // if the Defender is an evolved animal and the player does not have
	//    the un-evolved stage, then
	//    determine the name of the un-evolved animal
	//    display the message "You must capture un-evolved animal before you can try to capture evolved animal"
	//    return
	// end if
	if (Defender->GetEvolvesFrom() != NULL)
	{
		if(!ThePlayer.HasAnimal(Defender->GetEvolvesFrom()))
		{
			printf("You must capture %s before you can try to capture %s.\n",Defender->GetEvolvesFrom()->GetName(),Defender->GetName());
			return (0);
		}
	}

	//
	// Display the message "You attempt to capture animal name with energy level n using animal name with energy level n"
	printf("You attempt to capture ");
	Defender->Display();
	printf(" with ");
	Attacker->Display();
	printf("\n%s",Defender->GetPhrase());
	PauseForSeconds(2);
	printf("...%s",Attacker->GetPhrase());
	PauseForSeconds(2);
	printf(".");
	PauseForSeconds(2);
	printf("\n");

	// Assign the effective energy level of the defender to defenders_energy
    // If the attackers energy is greater than the defenders_energy then
    //     Decrement the attackers energy by 1
    //     Remove the defender from the state
	//     Add the defender to the player
	//     Display the message "You have captured animal name!"
	//     Display the message "Your currently selected animal is animal name with n energy."
	// else
	//     Decrease the attacker’s energy by FAILED_ATTACK_FOOD_LOSS  
	//     Display the message "You failed.  Animal name has n energy against energy name animals."
	//     Display the message "Your currently selected animal only has n energy"
	// end if
	if (Attacker->GetFoodLevel() > Defender->GetEffectiveFoodLevel(Attacker))
	{
		Attacker->DecrementFoodLevel(1);
		Map->GetCurrentState()->ReleaseAnimal();
		ThePlayer.AddAnimal(Defender);
		printf("You have captured %s!  %s used up some energy in the capture.\n",
		         Defender->GetName(),Attacker->GetName());
		printf("Your currently selected animal, %s, has energy level %d.",
		         Attacker->GetName(), Attacker->GetFoodLevel());
		CheckForWinner();
	}
    else   // Capture failed
	{
		Attacker->DecrementFoodLevel(FAILED_ATTACK_FOOD_LOSS);
	    printf("You failed.  %s  has %d energy against %s animals.\n",
                    Defender->GetName(), Defender->GetEffectiveFoodLevel(Attacker),
					Attacker->GetTypeString());
		printf("%s has energy level %d after the capture attempt.\n",
		         Attacker->GetName(), Attacker->GetFoodLevel());
	}

return(1);

} // end Verb_CAPTURE

int Verb_SCORE(void)
{
	// Display the message
	printf("You have captured %d out of %d animals.\n",ThePlayer.GetNumberOfAnimals()-1, MAX_ANIMALS);
	printf("Your rank is %s.\n",ThePlayer.GetRank());

	return(1);

} // end Verb_SCORE  

int Verb_GO(void)
{
// Move to a neighboring state
// If current state still has its animal, then the player may only move (retreat) to the previous state
// Test if State adjoins current state.

	CState* DesiredState;
	bool    SuccessfulMove = false;
	// If the second token is not a state then
	//   display the message, "You did not choose a valid state."

	if ((sentence[SECOND_WORD] < STATE_START) ||
		(sentence[SECOND_WORD] > STATE_END))
	{
	 printf("You did not choose a valid state.\n");
	 return(0);
	}

	// Get state object for where player wants to go
	DesiredState = Map->GetState(StateNames(sentence[SECOND_WORD]));

	// If current state still has its animal, then player may only move (retreat) to the previous state
	if ((Map->GetCurrentState()->HasAnimal()) && 
		(DesiredState != Map->GetPreviousState()))
	{
		// Display error message that can only retreat
		printf("You have not captured the animal in this state so, \n");
		printf("you can either stay here or GO to the state of %s.\n",Map->GetPreviousState()->GetName());
		return (0);
	}
	else if ((Map->GetCurrentState()->HasAnimal()) && 
		     (DesiredState == Map->GetPreviousState()))
	{
		// successful move
		Map->SetCurrentState(DesiredState);
		ThePlayer.SetLocation(DesiredState);
		// printf("You move to the state of %s.\n",DesiredState->GetName());
		SuccessfulMove = true;
	}

	// if here, then the player can move to any adjoining
	// state
	// verify DesiredState is a neighbor of current state
	else if (Map->IsNeighborOfCurrentState(DesiredState))
	{
		// successful move
		Map->SetCurrentState(DesiredState);
		ThePlayer.SetLocation(DesiredState);
		// printf("You move to the state of %s.\n",DesiredState->GetName());
		SuccessfulMove = true;
	}
	else
	{
		// not a neighboring state
		printf("The state of %s is not next to %s.\n",DesiredState->GetName(),Map->GetCurrentState()->GetName());
		return (0);
	}

	// if the move was successful then
	//   display the status of the state
	//   if the player has not won the food prize then
	//     ask player for the capital of the state
	//   end if
	// end if
	if (SuccessfulMove)
	{
		Verb_LOOK();
		if (DesiredState->HasFood())
		{
			Verb_CAPITAL();
		}
		return(1);
	}
} // end Verb_GO  

int Verb_STATUS(void)
{
// this function displays information about the states including:
// States that still have animals or food
//                 
	// display the message, "State (Animal-Food)..."
	// 
	printf("States with animals and food left are...\n");
    Map->PrintStatus();
 
	return(1);

} // end Verb_STATUS

int Verb_LOOK(void)
{
// this function displays information about the current state 
// including the name, text description, and animals and food
// yet to capture
// Also display the neighboring states

	CState* CurrentState;

	// display the message, "State (Animal-Food)..."
	// 
	CurrentState = Map->GetCurrentState();
	printf("You are in the state of %s.\n",CurrentState->GetName());
	printf("%s\n",CurrentState->GetDescription());
    CurrentState->PrintStatus();

	printf("\nAround you see the state(s) of:...\n");
	Map->DisplayNeighboringStatesOf(CurrentState);
 
	return(1);

} // end Verb_STATUS

int Verb_SAVE(void)
{
	// Save the current game

	char* pFileName = "save.dat";

	CFile f( pFileName, CFile::modeCreate | CFile::modeWrite );

	CArchive archive(&f, CArchive::store);
	ThePlayer.Serialize(archive);
	Map->Serialize(archive);
	archive.Close();
	f.Close();

		return(0);
} // end Verb_SAVE


////////////////////////////////////////////////////////////////////////////////

int Check_For_Phrase(int phrase,int index)
{
// this function is used to test for small phrases that when extracted don't
// change the measning of a sentence for example:"look to the west" and
// "loo west" and "look to west" all mean the same thing.

// test which phrase is to be checked

switch(phrase)
      {
      case PHRASE_TO: // have we found the prep. "to"
           {

           if (sentence[index]==PREP_TO)
              return(1);

           } break;

      case PHRASE_THE: // have we found the article "the"
           {

           if (sentence[index]==ART_THE)
              return(1);

           } break;

      case PHRASE_TO_THE: // have we found the prep. phrase "to the"
           {

           if (sentence[index]==PREP_TO)
              {
              if (sentence[index+1]==ART_THE)
                  return(1);
              else
                  return(0);
              } // end if got "to the"
           } break;

      default:break; // there is a serious problem!

      } // end switch

// we have failed

return(0);

} // end Check_For_Phrase

///////////////////////////////////////////////////////////////////////////////

void Introduction(void)
{

int index;

for (index=0; index<50; index++,printf("\n"));

// make the screen blue with white characters
// only works with ansi driver

printf("%c%c37;44m",27,91);

printf("\n                                                                  ");
printf("\n                                                                  ");
printf("\n    AAAAA   M     M  EEEEEEE  RRRRR    IIIIIII  CCCCCCC   AAAAA   N     N");
printf("\n   A     A  MM   MM  E        R    R      I     C        A     A  NN    N");
printf("\n   A     A  M M M M  E        R     R     I     C        A     A  N N   N");
printf("\n   A     A  M  M  M  E        R     R     I     C        A     A  N  N  N");
printf("\n   A     A  M     M  E        R    R      I     C        A     A  N   N N");
printf("\n   AAAAAAA  M     M  EEEEE    RRRRR       I     C        AAAAAAA  N    NN");
printf("\n   A     A  M     M  E        R  R        I     C        A     A  N     N");
printf("\n   A     A  M     M  E        R   R       I     C        A     A  N     N");
printf("\n   A     A  M     M  E        R    R      I     C        A     A  N     N");
printf("\n   A     A  M     M  EEEEEEE  R     R  IIIIIII  CCCCCCC  A     A  N     N");
printf("\n                                                                  ");
printf("\n   RRRRR    OOOOOOO  U     U  N     N  DDDD     U     U  PPPPP    !!!    ");
printf("\n   R    R   O     O  U     U  NN    N  D   D    U     U  P    P   !!!    ");
printf("\n   R     R  O     O  U     U  N N   N  D    D   U     U  P     P  !!!    ");
printf("\n   R     R  O     O  U     U  N  N  N  D     D  U     U  P     P  !!!    ");
printf("\n   R    R   O     O  U     U  N   N N  D     D  U     U  P    P   !!!    ");
printf("\n   RRRRR    O     O  U     U  N    NN  D     D  U     U  PPPPP    !!!    ");
printf("\n   R  R     O     O  U     U  N     N  D     D  U     U  P        !!!    ");
printf("\n   R   R    O     O  U     U  N     N  D    D   U     U  P               ");
printf("\n   R    R   O     O  U     U  N     N  D   D    U     U  P        !!!    ");
printf("\n   R     R  OOOOOOO  UUUUUUU  N     N  DDDD     UUUUUUU  P        !!!    ");
printf("\n                                                                  ");
printf("\n                                                                  ");
printf("\n    V1.1 By Greg Turgeon (c) 2000.   Language Parser from A. LaMothe.    ");


while(!kbhit());

for (index=0; index<50; index++,printf("\n"));

} // end Introduction


///////////////////////////////////////////////////////////////////////////////

void Init(void)
{
	CAnimal* StartingAnimal;
	char buffer[20];

	StartingAnimal = TheAnimals.GetAnimal(ANIMAL_KITTY);
	ThePlayer.AddAnimal(StartingAnimal);
	ThePlayer.ChooseAnimal(StartingAnimal);
	ThePlayer.AddFood(CFood(PET,5));
	ThePlayer.SetRank(ranks[0]);

	Map = new CMap();

	// Give the story line
	printf("The President of the United States has decided to create a nature\n");
	printf("park that contains 50 native US animals.  The park is a lush, green,\n");
	printf("and beautiful natural setting where wild animals can roam free and \n");
	printf("visitors can see these animals in their natural setting.   The park is\n");
	printf("almost complete, except it has no animals.\n\n");

    printf("The President has asked for the bravest and smartest young Americans\n");
	printf("to create this park of the future.  Your mission is to travel to each \n");
	printf("of the 50 states and capture the prized animal from each state.\n\n");  

	printf("You have been given a  plane ticket to the state of Maine in the \n");
	printf("northeastern corner of the United States.  The President also gives \n");
	printf("you a black and white kitty named Tiger and a healthy supply of pet food.\n");
	printf("Use your pet food to keep your kitty full of energy to help you roundup \n");
	printf("the 50 prized animals.\n\n");

	printf("\n\n\nPress any key to continue\n");

	getch();
	getch();
	
	for (int i = 0;i < 25; i++)
	{
		printf("\n");
	}

	printf("To capture an animal from a state, you must select a more powerful animal\n");
	printf("from the ones you have already captured.  You may make an animal more powerful\n");
	printf("by feeding it.\n\n");

	printf("The four types of animals that are categorized by what they eat: pet food, \n");
	printf("bird seed, grass, and water.  There are 4 or 5 basic animals in each category.\n");
	printf("A basic animal may evolve into a stronger animal if you capture it in a state.\n\n");

	printf("You can move from a state to any adjacent state.  You may not pass through \n");
	printf("a state until you have captured the animal from that state.  After you \n");
	printf("capture the animal from that state, you can move freely to any another \n");
	printf("adjoining state.  \n\n");

	printf("Choose your path wisely to avoid trying to capture animals that are \n");
	printf("too powerful.  Every time you try to capture an animal that is too powerful,\n");
	printf("your currently selected animal looses power.   You can gain food in each\n");
	printf("state by correctly identifying the capital of that state. \n\n\n");

	printf("What is your name?");
	gets(buffer);
	ThePlayer.SetName(CString(buffer));

	// See if a saved game exists
	// if it does, ask the player if they wish to 
	// load it

	char* pFileName = "save.dat";
	TRY
	{
		CFile f( pFileName, CFile::modeRead);
		// if here, then the file exists
		printf("Do you want to restore the saved game? (Y/N) ");
		gets(buffer);

		if ((buffer[0] == 'y') ||
			(buffer[0] == 'Y'))
		{
			// Create an archive to read in the file 
			CArchive ReadArchive(&f, CArchive::load);
			ThePlayer.Serialize(ReadArchive);
			Map->Serialize(ReadArchive);
		}
	
		// Close the file 
		f.Close();
	}
	CATCH ( CFileException, e )

	{
		return;
	}
	END_CATCH


} // end Init

void PauseForSeconds(int SecondsToPause)
{
	CTime StartingTime;
	CTime CurrentTime;
	int SecondsCounter = 0;

	// Read the clock as a starting time
	StartingTime = StartingTime.GetCurrentTime();
	CurrentTime  = CurrentTime.GetCurrentTime();

	while (SecondsCounter < SecondsToPause)
	{
		// Wait for the seconds to change
		while (CurrentTime.GetSecond() == StartingTime.GetSecond())
		{
			CurrentTime = CurrentTime.GetCurrentTime();
		}

		SecondsCounter++;
		StartingTime = CurrentTime;
	}
}


///////////////////////////////////////////////////////////////////////////////

void CheckForWinner(void)
{
	// Checks for the player ranking
	// and if the player has won

	int     Rank;
	CString RankTitle;

	// First check for a win
	//
	if (ThePlayer.GetNumberOfAnimals() == 51)
	{
		printf("YEEEE HAWW PARTNER!!!!!!!!!!!!\n\n");
		printf("YOU HAVE CAPTURED ALL 50 ANIMALS!\n\n");

		printf("Do you hear something...\n");
		PauseForSeconds(5);

		printf("It's the telephone ringing...\n");
		PauseForSeconds(3);

		printf("ITS THE PRESIDENT!!!\n");
		PauseForSeconds(3);

		printf("CONGRATULATIONS %s!\n",ThePlayer.GetName());
		PauseForSeconds(3);

		printf("YOU ARE A BRAVE AND TALENTED YOUTH.\n");
		PauseForSeconds(3);

		printf("BECAUSE OF YOUR HARD WORK,  OUR NATURE PARK WILL BE A SUCCESS.\n");

		printf("\n\n\n\n\n");
		printf("Press any key to quit.\n");

		while(!kbhit())
		{}

		Verb_EXIT();
	}  // End of Winner message block        

	// No test for rank increase
	// Rank is number of animals captured divided by 5
	Rank = ThePlayer.GetNumberOfAnimals() / 5;

	RankTitle = CString(ranks[Rank]);

	// Check for a promotion
	if (RankTitle != ThePlayer.GetRank())
	{
		printf("\nCongratulations %s!! \n", ThePlayer.GetName());
		printf("You have been promoted to %s!\n",RankTitle);
		ThePlayer.SetRank(ranks[Rank]);
	}
} // end CheckForWinner

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
// call up intro

Introduction();

printf("\n\nWelcome to AMERICAN ROUNDUP...\n\n\n");

// obtain users name to make game more personal

// Initialize the game variables
Init();

// main event loop,note: it is NOT real-time

while(!global_exit)
     {
     // put up an input notice to user

     printf("\n\nWhat do you want to do,%s? ",ThePlayer.GetName());

     // get the line of text

     Get_Line(global_input);

     printf("\n");

     // break the text down into tokens and build up a sentence

     Extract_Tokens(global_input);

     // parse the verb and execute the command

     Verb_Parser();

     } // end main event loop

printf("\n\nExiting the AMERIAN ROUNDUP...see you later.\n");

	}

	return nRetCode;
}


