© Glenn Rowe AC Lab 3 An adventure game
© Glenn Rowe Adventure games Player runs a character that explores a map can fight 'monsters' collect treasure solve puzzles Final goal defeat 'boss' character obtain final treasure, etc.
© Glenn Rowe Adventure game: requirements Single location One player character One monster (dragon) Goal: kill the dragon Actions: drink (a potion to restore health) wear (suit of armour) attack (attack the dragon) status (show current state of player) quit (quit game)
© Glenn Rowe Aims of lab (coding) Inheritance Polymorphism File access
© Glenn Rowe Class structure Player can carry items of various types potions armour All items have properties in common (e.g. description, weight, etc) Define Item base class for common properties Define derived classes for each item type Potion class Armour class
© Glenn Rowe Item class Base class for all item types Create data field for description (string) can add other fields in extended version of game Provide constructors zero-parameter one-parameter Provide interface methods (get / set) Provide ToString() method
© Glenn Rowe Potion class Inherits Item Add a 'health' data field amount of health gained when potion drunk Override ToString() to print out customized description for potion Provide constructors Provide interface methods for health
© Glenn Rowe Armour class Inherits Item Add a 'protection' data field reduction in damage when wearing armour Override ToString() to print out customized description for armour Provide constructors Provide interface methods for protection
© Glenn Rowe Derived class methods A derived class may have methods not overridden from base class e.g. Armour has getProtection() If using polymorphism, must cast the pointer to derived class in order to access such methods Item* myItem = new Armour(); ((Armour *)myItem)->getProtection();
© Glenn Rowe Creature class Define Creature class base class for all creature and player types Data fields name (string) health (int) - when reduced to zero, creature dies Use Creature class for dragon or define a Dragon class that inherits Creature Provide constructors, interface methods Write Attack() method for dealing with attacks by creature (see later)
© Glenn Rowe Player class Player class represents player's character Inherits Creature class Additional data fields: carriedItems (array of Item* pointers) wornArmour others as you see fit Initial items read from disk file (see later) Provide constructors, interface methods Override Attack() method
© Glenn Rowe Carried items - using polymorphism 00FE34D Item **carriedItems Declare carriedItems array pointer (of type Item **). [Or can use a vector from STL)
© Glenn Rowe Carried items - using polymorphism 00FE34D Item **carriedItems 00FE45700FE51900FE623[…] new Item*[numItems] Create an array of Item* pointers of the right size (size read from disk file).
© Glenn Rowe Carried items - using polymorphism 00FE34D Item **carriedItems 00FE45700FE51900FE623[…] new Item*[numItems] Each Item* pointer can point to an Item object or to object derived from Item (uses polymorphism) ItemPotion ArmourPotion
© Glenn Rowe File access in C++ Can read player's items from a text file Typical file format: First line: number of items to be read Remaining lines: details for each item E.g. potion;carrot;5 (item type);(item name);(item value[s]) Need method of reading in text… …and of 'parsing' details for each item
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; C++: Player.cpp Must include the fstream library to allow I/O to/from files.
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; C++: Player.cpp Create an ifstream for input from a file. (Use ofstream for writing to a file.)
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; C++: Player.cpp Open the file by calling the open( ) method from the ifstream object.
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; C++: Player.cpp If there is a problem opening the file (e.g. file doesn't exist), dataStream is NULL. Should always test this after opening.
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; C++: Player.cpp Once opened, an ifstream object can be used just like 'cin', so can use it to read data from file.
© Glenn Rowe Reading from a file #include ifstream dataStream; dataStream.open("ItemData.txt"); if (!dataStream) { cout << "Can't open file\n"; } dataStream >> numItems; // Code to read in data for // items C++: Player.cpp Read in the data for each of your numItems items and store in your array or vector.
© Glenn Rowe Parsing an input line Must 'parse' (interpret) an item's properties potion;carrot;5 Contains 3 separate pieces of info Would like to 'tokenize' the line - split it into 3 separate words Various methods exist look up on web write your own or use Tokenize() method provided on lab 3 web page (uses STL’s vector)
© Glenn Rowe Tokenize( ) method void Player::Tokenize(const string& str, vector & tokens, const string& delimiters) 'str' is the string to be tokenized (input line from file) 'tokens' is a vector of strings containing the separate words after tokenizing Declare ‘tokens’ before calling Tokenize() 'delimiters' is a list of symbols used to separate words (; in the input line above)
© Glenn Rowe Game class Controls play of the game Each turn: Print prompt: (e.g. "What now? >") Accept player's command Test for errors Call appropriate method to run command
© Glenn Rowe Commands: status Prints out status of Player and Dragon Call methods from Player and Dragon class to do this e.g. ToString( )
© Glenn Rowe Commands: drink Used to drink a potion Should print out a numbered list of potions being carried by player Accept number of potion to be drunk Increase player's health by value of potion Delete potion from player's carriedItems list
© Glenn Rowe Commands: wear Used to wear or swap a suit of armour Print numbered list of armours being carried Accept number of suit to be worn Set player's protection value according to value of armour (Protection value used in attacks)
© Glenn Rowe Command: quit Quit the game May print an "Are you sure?" prompt first
© Glenn Rowe Commands: attack Run one round of combat between player & dragon Use your own attack system if you like Simple version: Randomly determine who goes first For each combatant: Randomly determine if they hit the opponent If they hit, subtract damage done from opponent's health For hits on player, adjust damage because of armour Check if opponent is dead
© Glenn Rowe main( ) main( ) should do no more than create an instance of Game Then call Game's play( ) method