Advertisement

C++ Workshop - Project 1

Started by August 16, 2006 05:41 PM
193 comments, last by me_minus 15 years, 3 months ago
That is what you win with multi compiler/platform development.

every compiler find different things.
Going back to page 1 of this thread, about clearing the screen:
Quote:
Original post by Deyja
That's unnecesarily complex. And also it's C.

This does it fine.
char buffer[50*80] = { ' ' };WriteConsole( GetStdHandle(STD_OUTPUT_HANDLE), buffer, 50*80, 0, 0 );


Of course, it assumes your window is 80 * 50. (Unless you change it, it is.)


This formula (the 2nd line) causes the following error, though strangely only when I run in debugging mode (using dev-cpp):

"An Access violation (Segmentation fault) raised in your program"
Advertisement
Unfortunatly I can't test my code with DevCPP. It works fine in MSVC, however.

It's possible that when running the DevCPP debugger, std::cout is redirected to a window in the IDE. If that's the case, I wouldn't expect it to work.
I know im late, but I think it looks neat so ill post my project1.

NOTE: Since I #define _WIN32_WINNT 0x0501 to be able to set console buffer size, my version is XP compatible only.

headers.hpp (i took a shortcut of putting all headers in one file... just today)
///////////////////////////////////////////////////////////////////////////////////////////////////////// all headers, prototypes, and declarations here///////////////////////////////////////////////////////////////////////////////////////////////////////// headers#define _WIN32_WINNT 0x0501  // this game is XP compatible only. this definition allows for console manipulation (size etc.)#include <iostream>#include <sstream>#include <time.h>#include <windows.h>#include <cstring>#include <conio.h>           // needed for getch()typedef unsigned short int USHORT;using std::cin;using std::cout;using std::endl;using std::string;using std::istringstream;enum COLOR {DARKBLUE = 1, DARKGREEN, TEAL, BURGUNDY, VIOLET, GOLD, SILVER,           GRAY, BLUE, GREEN, CYAN, RED, PURPLE, YELLOW, WHITE};////////////////////////// class declarations //////////////////////////class ConsoleManip         // console manipulator. all console sizing and output options are done from this manipulator{      public:             ConsoleManip();             ~ConsoleManip();                          void setupConsole(USHORT width, USHORT height, bool fullScreenStat); //initialize console to specific attributes             void positionOutput(USHORT column, USHORT row);             void setOutputColor(COLOR whichColor);             void printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, string txt); // for text             void printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, USHORT number); // for USHORT             void printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, float number); // for float             void clearScreen();                   private:             const HANDLE hConsole;             COORD screenSize;         // needed for screen size manipulation             DWORD fullScreen;         // needed for full screen attribute manipulation             COORD sPos;               // needed for positioning text output};class Equipment{      public:             Equipment(string name = "Unidentified", float price = 0.0);  // these are default values             ~Equipment();             string getItsName() const { return *itsName; }             float getItsPrice() const { return *itsPrice; }      protected:              string * itsName;              float * itsPrice;};class Armor : public Equipment{      public:             Armor(string name, float price, USHORT armorValue, USHORT maxDex);             Armor(){}             Armor(const Armor &);             ~Armor();             USHORT getItsAV() const { return *itsArmorValue; }             USHORT getItsMaxDex() const { return *itsMaxDex; }      private:              USHORT * itsArmorValue;              USHORT * itsMaxDex;};class Weapon : public Equipment{      public:             Weapon(string name, float price, USHORT weaponPowerMin, USHORT weaponPowerMax,                    USHORT criticalMin, USHORT criticalMax, USHORT criticalMultip);             Weapon(const Weapon &);             ~Weapon();                          // accessors             USHORT getItsDice() const { return *itsNumberDice; }             USHORT getItsMax() const { return *itsWeaponPowerMax; }             USHORT getItsCriticalMin() const { return *itsCriticalMin; }             USHORT getItsCriticalMax() const { return *itsCriticalMax; }             USHORT getItsCriticalMultip() const { return *itsCriticalMultip; }                   private:              USHORT * itsNumberDice;              USHORT * itsWeaponPowerMax;              USHORT * itsCriticalMin;              USHORT * itsCriticalMax;              USHORT * itsCriticalMultip;};class Character{      public:             //constructors             Character();             Character(ConsoleManip & rTheConManip);             Character(string name, USHORT level, USHORT strength, USHORT dexterity, USHORT constitution,                        ConsoleManip & rTheConManip);             //Character(const Character &);             ~Character();                          // accessor methods             void setItsName(const string name);             void setItsLevel(const USHORT level);             void setItsStrength(const USHORT strength);             void setItsDexterity(const USHORT dexterity);             void setItsConstitution(const USHORT constitution);             void setItsHitPoints(const USHORT hitPoints);             void setItsExperience(const signed long experience);             void levelUpTest();             void increaseItsGold(const float gold);             void setCreatedStatus(const bool status);             void buyWeapon(Weapon & theWeapon);             void buyArmor(Armor & theArmor);             void setInitiative();             void setDamaging();             void beDamaged(USHORT howMuchDamage);             void increaseLevelsFought(USHORT enemysLevel) {if (enemysLevel>*levelsFought) *levelsFought = enemysLevel;}                          string getItsName() const;             USHORT getItsLevel() const;             USHORT getItsStrength() const;             USHORT getItsDexterity() const;             USHORT getItsConstitution() const;             USHORT getItsHitPoints() const;             signed long getItsExperience() const;             float getItsGold() const;             bool getItsCreatedStatus() const;             USHORT getItsLevelsFought() const { return *levelsFought; }             Weapon& accessItsWeapon() {return *itsWeapon;}             Armor& accessItsArmor() {return *itsArmor;}             USHORT modifier(USHORT theAttrubute);             USHORT getInitiative();             USHORT getDamaging() { return * itsDamaging; }             USHORT setGetAttackRoll(USHORT randomForAttackRole);                          USHORT getArmorCheck();                          void resetStats();             void displayAllStats();         // needed in 2 scopes (-submenus), therefore i "percolated" the task to this class                   private:              string * itsName;              USHORT * itsLevel;              USHORT * itsStrength;              USHORT * itsDexterity;              USHORT * itsConstitution;              USHORT * itsHitPoints;              signed long * itsExperience;              float * itsGold;              bool * alreadyCreated;              USHORT * levelsFought;              Armor * itsArmor;              Weapon * itsWeapon;              ConsoleManip ConManip;              // needed for different text printouts              USHORT * itsInitiative;              USHORT * itsDamaging;};class Menu{      public:           Menu();           Menu(Character & rThePlayer, ConsoleManip & rTheConManip); // every sub-class will take these 2 param to manipulate           virtual ~Menu();           virtual void doMenu();           virtual void drawMenu() {cout << "\nBase Menu interface\n"; userReady(); }           virtual void testChoice() {cout << "\nBase Menu choice decision\n"; userReady(); }           void userReady();                   protected:           string * pItsChoice;           bool * pItsExit;           Character & rPlayer;           ConsoleManip & rConManip;};class MainMenu : public Menu{      public:            // passing in the 2 parameters to base constructor            MainMenu(Character & rThePlayer, ConsoleManip & rTheConManip) : Menu(rThePlayer, rTheConManip) {}            virtual ~MainMenu() {}            virtual void drawMenu();            virtual void testChoice();                        bool testIfCreate();};class CCMenu : public Menu{      public:             // passing in the 2 parameters to base constructor             CCMenu(Character & rThePlayer, ConsoleManip & rTheConManip) : Menu(rThePlayer, rTheConManip) {}             virtual ~CCMenu() {}             virtual void drawMenu();             virtual void testChoice();                                       void nameCharacter();             void rollForStats();};class PurchaseMenu : public Menu{      public:             // passing in the 2 parameters to base constructor             PurchaseMenu(Character & rThePlayer, ConsoleManip & rTheConManip) : Menu(rThePlayer, rTheConManip) {}             virtual ~PurchaseMenu() {}             virtual void drawMenu();             virtual void testChoice();                   private:                                             // just attempting at nested types.....              class ArmorStore : public Menu              {                    public:                           // passing in the 2 parameters to base constructor                           ArmorStore(Character & rThePlayer, ConsoleManip & rTheConManip) : Menu(rThePlayer, rTheConManip){}                           virtual ~ArmorStore() {}                           virtual void drawMenu();                           virtual void testChoice();                           bool buyerHasEnoughGold(float price);              };                            class WeaponStore : public Menu              {                    public:                           // passing in the 2 parameters to base constructor                           WeaponStore(Character & rThePlayer, ConsoleManip & rTheConManip): Menu(rThePlayer, rTheConManip){}                           virtual ~WeaponStore() {}                           virtual void drawMenu();                           virtual void testChoice();                           bool buyerHasEnoughGold(float price);              };                    };class CombatControl{     public:            CombatControl(Character & thePlayer, ConsoleManip & theConManip);            ~CombatControl();            void setEnemyLevel();            void setupPlayers(USHORT theEnemyLevel);            void attack(USHORT randomFromAttackRoll, Character & attacker, Character & opponent);            void miss(Character & attacker, Character & opponent);            void combat();            bool arePlayersAlive();            void aftermath();            USHORT winExperience();            float winGold();     private:             Character & rPlayer;             Character * pEnemy;             ConsoleManip & rConManip;};// global functionsvoid title(ConsoleManip & rConManip);USHORT getRandomNumber(USHORT min, USHORT max);
Menu.cpp
#include "headers.hpp"//////////////////////////////////// implementation of Menu class ////////////////////////////////////Menu::Menu(Character & rThePlayer, ConsoleManip & rTheConManip):pItsChoice(new string),pItsExit(new bool(false)),rPlayer(rThePlayer),rConManip(rTheConManip){}void Menu::doMenu(){     while (*pItsExit == false)     {           drawMenu();           cin >> *pItsChoice;           if ( pItsChoice->length() != 1 )           *pItsChoice = "! Too Many Characters Entered, so First Character, !, will default in all switch statments";                   testChoice();           }}void Menu::userReady(){     rConManip.printAtPositionAndColor ( 0, 49, WHITE, "Press any key to continue..." );     getch();                                      rConManip.printAtPositionAndColor ( 0, 49, WHITE, "                            " ); // cleaning up}Menu::~Menu(){     delete pItsChoice;     pItsChoice = 0;     delete pItsExit;     pItsExit = 0;}
main.cpp
#include "headers.hpp"int main(){    srand( (unsigned)time( NULL ) );              // seed random number generator (cant this be done somwhere else?)        ConsoleManip * pConManip = new ConsoleManip;  // create the console manipulator    pConManip->setupConsole(80, 50, true);        // setup our console to 80x50 text limit, fullscreen        title(*pConManip);                            // title screen will need text manipulation, passes ConManip to do this                                                  // smae is with all that pass ConManip, they need text manipulations    Character * pPlayer = new Character(*pConManip);       // character is created here, to be passed throughout the menus        Menu * pDoMenus = new MainMenu(*pPlayer, *pConManip);  // create the main menu    pDoMenus->doMenu();                                    // enter the main menu, which will create sub-menus respectively        // done playing?    pConManip->clearScreen();    pConManip->printAtPositionAndColor (26, 24, WHITE, "Thank you for playing!!!" );    pConManip->positionOutput(0, 49);    cout << "Press any key to continue...";    getch();    return EXIT_SUCCESS;}// title screen when start gamevoid title(ConsoleManip & rConManip){     rConManip.printAtPositionAndColor( 32, 13, RED, "Challenge Power\n\n" );     rConManip.printAtPositionAndColor( 23, 15, DARKGREEN, "Programmed by Yisroel Goldstein 2006\n" );     rConManip.positionOutput(79,49);     Sleep(4000);}// random number generatorUSHORT getRandomNumber(USHORT min, USHORT max){     USHORT range = (max - min) + 1;                    // + 1 is to adjust zero offset     USHORT theRand = min + ( rand() % range );         // generates random number within desired range     return theRand;          // note:     // The desired random number is: minimum + (randmoize the DIFFERENCE between min and max)     // But not: minimum + (randomize max)}
ConsoleManip.cpp
////////////////////////////////////////////////////////////////// implementation of Console Manipulator (ConsoleManip) class //////////////////////////////////////////////////////////////////#include "headers.hpp"// default constructorConsoleManip::ConsoleManip():                                                      // initializing...hConsole( (HANDLE)GetStdHandle( STD_OUTPUT_HANDLE ) ),  // hConsole will allow us to manipulate console by holding the HandlefullScreen(true){   screenSize.X = 80;   screenSize.Y = 50;   SetConsoleScreenBufferSize(hConsole, screenSize); // to set the text limit   COORD * pScnSize = &screenSize;                 // this pointer is needed for SetConsoleDisplayMode(HANDLE,DWORD,PCOORD)            SetConsoleDisplayMode(hConsole, fullScreen, pScnSize);                 }// destructorConsoleManip::~ConsoleManip(){}void ConsoleManip::setupConsole(USHORT width, USHORT height, bool fullScreenStat){    screenSize.X = height;                         screenSize.Y = width;                                        SetConsoleScreenBufferSize(hConsole, screenSize); // to set the text limit    fullScreen = fullScreenStat;                          COORD * pScnSize = &screenSize;                 // this pointer is needed for SetConsoleDisplayMode(HANDLE,DWORD,PCOORD)             SetConsoleDisplayMode(hConsole, fullScreen, pScnSize);            }void ConsoleManip::positionOutput(USHORT column, USHORT row){     sPos.X = column;     sPos.Y = row;     SetConsoleCursorPosition( hConsole, sPos );}void ConsoleManip::setOutputColor(COLOR whichColor){     SetConsoleTextAttribute ( hConsole, whichColor );}void ConsoleManip::printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, string txt){     positionOutput(column, row);     setOutputColor(whichColor);     cout << txt;}void ConsoleManip::printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, USHORT number){     positionOutput(column, row);     setOutputColor(whichColor);     cout << number;}void ConsoleManip::printAtPositionAndColor (USHORT column, USHORT row, COLOR whichColor, float number){     positionOutput(column, row);     setOutputColor(whichColor);     cout << number;}void ConsoleManip::clearScreen(){//     char buffer[50*80] = { ' ' };//     WriteConsole( hConsole, buffer, (50*80), 0, 0 ); // this formula causes a segmentation fault (dev-cpp)    COORD                       coordScreen = { 0, 0 };    DWORD                       cCharsWritten;    CONSOLE_SCREEN_BUFFER_INFO  csbi;    DWORD                       dwConSize;    GetConsoleScreenBufferInfo(hConsole, &csbi);    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;    FillConsoleOutputCharacter(hConsole, TEXT(' '),                                dwConSize, coordScreen, &cCharsWritten);    GetConsoleScreenBufferInfo(hConsole, &csbi);    FillConsoleOutputAttribute(hConsole, csbi.wAttributes,                                dwConSize, coordScreen, &cCharsWritten);    SetConsoleCursorPosition(hConsole, coordScreen);}
Character.cpp
///////////////////////////////////////// implementation of Character class /////////////////////////////////////////#include "headers.hpp"// default constructor (will be used for player character creation)Character::Character(ConsoleManip & rTheConManip):                                  // initializationsitsName(new string("Undefined")),  // the pointer 'itsName' will now point to a new string on the free store. same with all.itsLevel(new USHORT(1)),           // Characters start at level 1itsStrength(new USHORT(0)),itsDexterity(new USHORT(0)),itsConstitution(new USHORT(0)),itsHitPoints(new USHORT(90)),itsExperience(new signed long(0)),itsGold(new float(0.0)),alreadyCreated(new bool(false)),       // according to player, the character has not yet been createdlevelsFought(new USHORT(0)),itsArmor(new Armor("Unarmored", 0.0, 0, 0)),itsWeapon(new Weapon("Unarmed Strike", 0.0, 1, 3, 20, 20, 2)),ConManip(rTheConManip),itsInitiative(new USHORT(0)),itsDamaging(new USHORT(0)){                                   // empty body       }// constructor with 6 params (will be used for enemy character creation)Character::Character(string name, USHORT level, USHORT strength, USHORT dexterity, USHORT constitution,                      ConsoleManip & rTheConManip):itsName(new string(name)),itsLevel(new USHORT(level)),itsStrength(new USHORT(strength)),itsDexterity(new USHORT(dexterity)),itsConstitution(new USHORT(constitution)),itsHitPoints(new USHORT( 10 + modifier(getItsConstitution()) )), // INITIAL HPitsExperience(new signed long(0)),itsGold(new float(0.0)),alreadyCreated(new bool(true)), // many of the data members, like this one, are irrelevant for the enemy constructorlevelsFought(new USHORT(0)),ConManip(rTheConManip),itsInitiative(new USHORT(0)),itsDamaging(new USHORT(0)){     float whichArmor = (*itsLevel) * 0.6;     switch ((int)whichArmor)     {                  case 0: itsArmor = new Armor("Unarmored", 0.0, 0, 0); break;            case 1: itsArmor = new Armor("Padded Armor", 5, 1, 8); break;            case 2: itsArmor = new Armor("Leather Armor", 10, 2, 6); break;            case 3: itsArmor = new Armor("Hide Armor", 15, 3, 4); break;            case 4: itsArmor = new Armor("Studded Leather", 25, 3, 5); break;            case 5: itsArmor = new Armor("Scail Mail", 50, 4, 3); break;                case 6: itsArmor = new Armor("Chain Shirt", 100, 4, 4); break;             case 7: itsArmor = new Armor("Chainmail", 150, 5, 2); break;            case 8: itsArmor = new Armor("Breastplate", 200, 5, 3); break;            case 9: itsArmor = new Armor("Splint Mail", 225, 6, 0); break;            case 10: itsArmor = new Armor("Banded Mail", 250, 6, 1); break;            case 11: itsArmor = new Armor("Half Plate", 600, 7, 0); break;            case 12: itsArmor = new Armor("Full Plate", 1000, 8, 1); break;            default: cout << "An exception has occured.";getch();                  }          float whichWeapon = (*itsLevel) * 0.7;     switch ((int)whichWeapon)     {            case 0: itsWeapon = new Weapon("Unarmed Strike", 0.0, 1, 3, 20, 20, 2); break;            case 1: itsWeapon = new Weapon("Brass Knuckles", 1.0, 1, 4, 20, 20, 2); break;            case 2: itsWeapon = new Weapon("Dagger", 2.0, 1, 4, 19, 20, 2); break;            case 3: itsWeapon = new Weapon("Mace", 5.0, 1, 6, 20, 20, 2); break;            case 4: itsWeapon = new Weapon("Handaxe", 6.0, 1, 6, 20, 20, 3); break;            case 5: itsWeapon = new Weapon("Shortsword", 6.5, 1, 6, 19, 20, 2); break;            case 6: itsWeapon = new Weapon("Scimitar", 7.0, 1, 6, 18, 20, 2); break;            case 7: itsWeapon = new Weapon("Morningstar", 8.0, 1, 8, 20, 20, 2); break;            case 8: itsWeapon = new Weapon("Spear", 9, 1, 8, 20, 20, 3); break;            case 9: itsWeapon = new Weapon("Longsword", 9.5, 1, 8, 19, 20, 2); break;            case 10: itsWeapon = new Weapon("Greatclub", 11, 1, 10, 20, 20, 2); break;            case 11: itsWeapon = new Weapon("Halberd", 12, 1, 10, 20, 20, 3); break;            case 12: itsWeapon = new Weapon("Bastard Sword", 12.5, 1, 10, 19, 20, 2); break;            case 13: itsWeapon = new Weapon("Greataxe", 16, 1, 12, 20, 20, 3); break;            case 14: itsWeapon = new Weapon("Greatsword", 20, 2, 6, 19, 20, 2); break;            default: cout << "An exception has occured.";getch();     }}// destructor    Character::~Character(){     delete itsName;     itsName = 0;     delete itsLevel;     itsLevel = 0;     delete itsStrength;     itsStrength = 0;     delete itsDexterity;     itsDexterity = 0;     delete itsConstitution;     itsConstitution = 0;     delete itsHitPoints;     itsHitPoints = 0;     delete itsExperience;     itsExperience = 0;     delete itsGold;     itsGold = 0;     delete alreadyCreated;     alreadyCreated = 0;     delete levelsFought;     levelsFought =0;     delete itsArmor;     itsArmor = 0;     delete itsWeapon;     itsWeapon = 0;}void Character::resetStats(){     * itsName = "Undefined";      * itsLevel = 1;                * itsStrength = 0;     * itsDexterity = 0;     * itsConstitution = 0;     * itsHitPoints = 0;     * itsExperience = 0;     * itsGold = 0.0;     * alreadyCreated = false;     * levelsFought = 0;     * itsInitiative = 0;     * itsDamaging = 0;          delete itsArmor;      itsArmor = new Armor("Unarmored", 0.0, 0, 0);     delete itsWeapon;     itsWeapon = new Weapon("Unarmed Strike", 0.0, 1, 3, 20, 20, 2);}void Character::setItsName(const string name){     * itsName = name;}void Character::setItsLevel(const USHORT level){     *itsLevel = level;     }void Character::setItsStrength(const USHORT strength){     * itsStrength = strength;}void Character::setItsDexterity(const USHORT dexterity){     * itsDexterity = dexterity;}void Character::setItsConstitution(const USHORT constitution){     * itsConstitution = constitution;}void Character::setItsHitPoints(USHORT hitPoints){     *itsHitPoints = hitPoints;}             void Character::beDamaged(const USHORT howMuchDamage){     *itsHitPoints -= howMuchDamage;     if ((*itsHitPoints<=0) || (*itsHitPoints>500)) // since its USHORT, it may go below zero and wrap arond     *itsHitPoints = 0;                             // this is the protection}void Character::setItsExperience(const signed long experience){   *itsExperience += experience;  }void Character::levelUpTest(){   for (int levelUpPREV = 0, level = 1, levelUpNEXT = 1000 ;        level <= *itsLevel                                 ;         levelUpPREV = levelUpNEXT, level++, levelUpNEXT += level*1000) // this loop will step through all level-up scores, and will close in on the correct level attained by testing where does the score reach by looping   {     if (*itsExperience >= levelUpNEXT && *itsExperience < (level+1)*1000+levelUpNEXT && *itsLevel == level && *itsLevel < 20) // if player has enonugh points to level up, and yet NOT enough points to level up twice     {  ConManip.setOutputColor(PURPLE);        cout << "\n\nCongratulations, your character has leveled up to level " << level+1 << " with " << *itsExperience << "XP.";        *itsLevel = level+1;        if (*itsLevel == 3 || *itsLevel == 5 || *itsLevel == 7 || *itsLevel == 9 || *itsLevel == 11 || *itsLevel == 13 || *itsLevel == 15 || *itsLevel == 17 || *itsLevel == 19 || *itsLevel == 20)        {           if (*itsStrength<20 || *itsDexterity<20 || *itsConstitution<20)             ConManip.setOutputColor(CYAN); cout << "\nYour Character has received additional power-ups.\n";           if (*itsStrength<20) *itsStrength += 1;           if (*itsDexterity<20) *itsDexterity += 1;           if (*itsConstitution<20) *itsConstitution += 1;        }        ConManip.setOutputColor(WHITE);     }                 }}void Character::increaseItsGold(const float gold){    *itsGold += gold;}void Character::setCreatedStatus(bool status){     * alreadyCreated = status;}void Character::buyWeapon(Weapon & rTheWeapon){     * itsGold -= rTheWeapon.getItsPrice();       // pay first!     delete itsWeapon;     itsWeapon = new Weapon(rTheWeapon);}void Character::buyArmor(Armor & rTheArmor){     * itsGold -= rTheArmor.getItsPrice();       // pay first     delete itsArmor;     itsArmor = new Armor(rTheArmor);}USHORT Character::modifier(USHORT theAttribute){     USHORT modified = (theAttribute - 10) / 2;     if (modified <1 || modified > 100) // if attribute didnt survive after subtracting 10 and /2, then being a USHORT,       return 0;                          // it might have wrapped around (going below zero), therefore "if modified > 100..."     else       return modified;}void Character::setInitiative(){      *itsInitiative = getRandomNumber(1, 20) + modifier(*itsDexterity);}USHORT Character::getInitiative(){       return *itsInitiative;}USHORT Character::getArmorCheck()                            // some armors will limit the maximum value the Dexterity Modifier{                                                            // can contribute to the Armor Check (when attacking)     USHORT dexMod = modifier(*itsDexterity);                // so; first modify dexterity: (dexterity - 10) / 2     if (dexMod > accessItsArmor().getItsMaxDex())           // then, make sure it doesnt go beyond armor MaxDex limit     dexMod = accessItsArmor().getItsMaxDex();     return 10 + accessItsArmor().getItsAV() + dexMod ;       // return results (to determine attack success of attacker)}void Character::setDamaging(){   for (USHORT damageRoll = 1; damageRoll <= itsWeapon->getItsDice(); damageRoll++)   {       *itsDamaging = getRandomNumber(1, itsWeapon->getItsMax()) + modifier(*itsStrength);   }}USHORT Character::setGetAttackRoll(USHORT randomForAttackRoll){     return (randomForAttackRoll) + (*itsLevel) + (modifier(*itsStrength));}                 string Character::getItsName() const{       return * itsName;}             USHORT Character::getItsLevel() const{       return * itsLevel;}USHORT Character::getItsStrength() const{       return * itsStrength;}USHORT Character::getItsDexterity() const{       return * itsDexterity;}             USHORT Character::getItsConstitution() const{       return * itsConstitution;}USHORT Character::getItsHitPoints() const{       return * itsHitPoints;}signed long Character::getItsExperience() const{       return * itsExperience;}float Character::getItsGold() const{      return * itsGold;}bool Character::getItsCreatedStatus() const{     return * alreadyCreated;}void Character::displayAllStats(){     ConManip.clearScreen();     ConManip.printAtPositionAndColor (0, 10, WHITE, "-------------------------------------------------------------------------" );     ConManip.printAtPositionAndColor (0, 11, WHITE, "|                         CHARACTER STATISTICS                          |" );     ConManip.printAtPositionAndColor (0, 12, WHITE, "-------------------------------------------------------------------------" );     ConManip.printAtPositionAndColor (0, 15, GOLD, "Name:        \t\t\t" );     cout << * itsName;     ConManip.printAtPositionAndColor (0, 17, VIOLET, "Level:       \t\t\t" );     cout << * itsLevel;     ConManip.printAtPositionAndColor (0, 19, YELLOW, "Strength:    \t\t\t" );     cout << * itsStrength;     ConManip.printAtPositionAndColor (0, 21, GREEN, "Dexterity:   \t\t\t" );     cout << * itsDexterity;     ConManip.printAtPositionAndColor (0, 23, SILVER, "Constitution:\t\t\t" );     cout << * itsConstitution;     ConManip.printAtPositionAndColor (0, 25, RED, "Hit Points:  \t\t\t" );     cout << * itsHitPoints;     ConManip.printAtPositionAndColor (0, 27, BLUE, "Experience:  \t\t\t" );     cout << * itsExperience;     ConManip.printAtPositionAndColor (0, 29, CYAN, "Gold:        \t\t\t" );     cout << * itsGold;     ConManip.printAtPositionAndColor (0, 33, BURGUNDY, "Armor:\t" );     cout << accessItsArmor().getItsName() << " / " << accessItsArmor().getItsAV()          << " / " << accessItsArmor().getItsMaxDex();      ConManip.printAtPositionAndColor (0, 35, DARKGREEN, "Weapon:\t" );     cout << accessItsWeapon().getItsName() << " / " << accessItsWeapon().getItsDice() << "d"          << accessItsWeapon().getItsMax() << " / (" << accessItsWeapon().getItsCriticalMin()          << "-" << accessItsWeapon().getItsCriticalMax() << "/x" << accessItsWeapon().getItsCriticalMultip() << ")";     cout << endl << endl;}
CombatControl.cpp
///////////////////////////////////////////// implementation of CombatControl class /////////////////////////////////////////////#include "headers.hpp"// constructor taking 2 paramsCombatControl::CombatControl(Character & thePlayer, ConsoleManip & theConManip):rPlayer(thePlayer),rConManip(theConManip),pEnemy(new Character("Just temporary values, not to let the pEnemy pointer void",0,0,0,0,theConManip)){}CombatControl::~CombatControl(){     delete pEnemy;     pEnemy =0;}void CombatControl::setEnemyLevel(){     int theLevel = 0;      if (rPlayer.getItsLevelsFought() > 0)     {    string userInput = "Starting with invalid input to invoke the while loop";          // testing if input is more than 2 charcters, or if number is out of range          while ( userInput.length()>2 || theLevel<1 || theLevel>20 || theLevel>rPlayer.getItsLevelsFought()+1 )             {                rConManip.clearScreen();                USHORT levelMenu;                rConManip.positionOutput(0, 5); rConManip.setOutputColor(BLUE);                for (levelMenu = 1; levelMenu <= rPlayer.getItsLevelsFought() +1 && levelMenu <= 20; levelMenu++)                { cout << levelMenu << ".\tLevel " << levelMenu << "\n\n"; }                rConManip.printAtPositionAndColor(0, (levelMenu*2)+2, YELLOW, "\n\nPlease Enter the level of your enemy: ");                cin >> userInput;                istringstream iss(userInput, istringstream::in); // testing if at least 1st character of input is numerical, and,                iss>>theLevel;                                   // is it so that numerical input is within range of a int                if (!iss){                                       // so if parsing failed,                     userInput = "user's 1st input character was invalid"; // like this, while will be true                     continue;  }                                // re-loop to get new input.                if (userInput.length() == 2)            // do this test only if user entered 2 charcters                  { int theTest = atoi(&userInput[1]);  // convert 2nd character of input into an int                    if (!theTest && theTest!=0){                      // if user input 2nd character isnt numerical (cannot convert to int)                    userInput = "user's 2nd input character wass invalid"; // like this, while will be true                    continue;}                                           }             }          cout << "\nYou have chosen to fight an enemy at Level " << theLevel <<". To arms!!!";     }     else // player hasnt fought ANY enemies yet     {          rConManip.clearScreen();          rConManip.printAtPositionAndColor(11, 15, SILVER, "Your first enemy will be at Level 1. To arms!");          theLevel = 1;     }     rConManip.printAtPositionAndColor(0, 49, SILVER, "Press any key to continue...");     getch();     setupPlayers(theLevel);  //p.s., casting int to USHORT here...}void CombatControl::setupPlayers(USHORT theEnemyLevel){   delete pEnemy; // we need the enemy's constructor again to set its armor & weapon according to level   USHORT enmyStrength = getRandomNumber(8,12);      // first set initial attributes for enemy   USHORT enmyDexterity = getRandomNumber(8,12);        USHORT enmyConstitution = getRandomNumber(8,12);   // then, according to enemies level, keep adding to these attributes accordingly   for (USHORT enmyAttributeLvl = 2; enmyAttributeLvl<=theEnemyLevel ; enmyAttributeLvl+=2) // 2,4,6,8 etc.   { // level 1 fails. level 2 loops once, adding 1 to each attribute. level 4 loops twice, adding 2 to each attribute. level 6 etc.       if (enmyStrength<20) enmyStrength++;       // and make sure not to surpass the 20 limit for each attribute       if (enmyDexterity<20) enmyDexterity++;       if (enmyConstitution<20) enmyConstitution++;   } // now, these level-based attributes will set HP, attack roll, armor check, attack damage etc. accordingly to level     pEnemy = new Character("Enemy", theEnemyLevel, enmyStrength, enmyDexterity, enmyConstitution, rConManip);   for (USHORT enemyLevelHP = 2; enemyLevelHP <= pEnemy->getItsLevel(); enemyLevelHP++) // initializes enemy HP accordingly to level, applicable from when enemy is level 2+, since level 1 is aleady initialized to correct value in default constructor   {   // this will re-iterate the amount of times enemy's level value is, continuously adding HP to enemy          pEnemy->setItsHitPoints(pEnemy->getItsHitPoints() + getRandomNumber(1,10) + pEnemy->modifier(pEnemy->getItsConstitution()));   }   pEnemy->setInitiative();      rPlayer.setItsHitPoints(10+rPlayer.modifier(rPlayer.getItsConstitution()));   for (USHORT playerLevelHP = 2; playerLevelHP <= rPlayer.getItsLevel(); playerLevelHP++) // resets player HP accordingly to level, applicable from level 1, since HP need to be reset at each battle   {   // this will re-iterate the amount of times players's level value is, continuously adding HP to player       rPlayer.setItsHitPoints(rPlayer.getItsHitPoints() + getRandomNumber(1,10) + rPlayer.modifier(rPlayer.getItsConstitution()));   }   rPlayer.setInitiative();   combat();}void CombatControl::combat(){   rConManip.clearScreen();                                                                                                        // ok, first, clean the screen   rConManip.positionOutput(0,49);                                                                                                 // then bring output all the way down to get a scrolling-down effect when battle begins   Character &rFirstAttacker = (pEnemy->getInitiative() >= rPlayer.getInitiative()) ? *pEnemy : rPlayer;                           // this is how we may refer to our fighters without knowing exactly who attacks first   Character &rSecondAttacker = (pEnemy->getInitiative() < rPlayer.getInitiative()) ? *pEnemy : rPlayer;                           // , since it depends on the initiative calculation done here   for (USHORT round = 1; arePlayersAlive() ; round++)                                                                                {      USHORT randomOfAttackRoll;      rConManip.setOutputColor(WHITE);      cout << "\n________________________________________________________________________________"                                 // this is the headline of each round           << "Round " << round <<": (" << rPlayer.getItsName() << " vs. Level " << pEnemy->getItsLevel() << " Enemy) "            //           << rPlayer.getItsName() << " has " << rPlayer.getItsHitPoints() << " HP remaining.\n\n";                                //      randomOfAttackRoll = getRandomNumber(1,20);      if (rFirstAttacker.setGetAttackRoll(randomOfAttackRoll) >= rSecondAttacker.getArmorCheck() && rFirstAttacker.getItsHitPoints()>0)              // if first attacker is still alive and his attack role is better than opponents armor check,        attack(randomOfAttackRoll, rFirstAttacker, rSecondAttacker);                                                                                     // then attack successful      else if (rFirstAttacker.getItsHitPoints()>0)        miss(rFirstAttacker, rSecondAttacker);             randomOfAttackRoll = getRandomNumber(1,20);      if (rSecondAttacker.setGetAttackRoll(randomOfAttackRoll) >= rFirstAttacker.getArmorCheck() && rSecondAttacker.getItsHitPoints()>0)             // now's come-back time! same as above, just players switch seats        attack(randomOfAttackRoll, rSecondAttacker, rFirstAttacker);       else if (rFirstAttacker.getItsHitPoints()>0)        miss(rSecondAttacker, rFirstAttacker);       Sleep(1800);//////////////////////////////////CRITICAL STRIKE      }   aftermath();}bool CombatControl::arePlayersAlive(){     return (rPlayer.getItsHitPoints() > 0 && pEnemy->getItsHitPoints() > 0);}void CombatControl::attack(USHORT randomFromAttackRoll, Character & attacker, Character & opponent){     if (randomFromAttackRoll >= attacker.accessItsWeapon().getItsCriticalMin()) // if attack is critical     {         USHORT critical = 0;         for (USHORT multip = 1; multip <= attacker.accessItsWeapon().getItsCriticalMultip(); multip++)         {             attacker.setDamaging();                                                    critical += attacker.getDamaging();         }         opponent.beDamaged(critical);                          // ouch!         &attacker == &rPlayer ? rConManip.setOutputColor(GREEN) : rConManip.setOutputColor(RED);  // output the bloody success, each player in their color!         cout << attacker.getItsName() << " Attacks " << opponent.getItsName() << " a CRITICAL STRIKE with "              << attacker.accessItsWeapon().getItsName() << ", hitting for " << critical <<" damage.\n"              << opponent.getItsName() << " has " << opponent.getItsHitPoints() << " HP remaining.\n";     }     else                                            // attack is regular     {         attacker.setDamaging();                                              // set amount of damage to cause         opponent.beDamaged(attacker.getDamaging());                          // ouch!         &attacker == &rPlayer ? rConManip.setOutputColor(GREEN) : rConManip.setOutputColor(RED);  // output the bloody success, each player in their color!         cout << attacker.getItsName() << " Attacks " << opponent.getItsName() << " with "              << attacker.accessItsWeapon().getItsName() << ", hitting for " << attacker.getDamaging() <<" damage.\n"              << opponent.getItsName() << " has " << opponent.getItsHitPoints() << " HP remaining.\n";     }}void CombatControl::miss(Character & attacker, Character & oponent){     if (attacker.getItsHitPoints()>0)       {          &oponent == &rPlayer ? rConManip.setOutputColor(DARKGREEN) : rConManip.setOutputColor(BURGUNDY);         cout << attacker.getItsName() << " Attacks " << oponent.getItsName() << " with "              << attacker.accessItsWeapon().getItsName() << " but missed.\n\n";       }}void CombatControl::aftermath(){     if (rPlayer.getItsHitPoints()==0 && pEnemy->getItsHitPoints()>0)         // if player dies     {         rConManip.setOutputColor(RED); cout << "\n\nYour character died in battle.";         rConManip.setOutputColor(SILVER); cout << "\nLevel reached: " << rPlayer.getItsLevel();         cout << "\nHighest level battled victoriously: " << rPlayer.getItsLevelsFought();         cout << "\n\nCreate A new character from main menu and battle your enemies once again!\n\n";         rConManip.printAtPositionAndColor ( 0, 49, WHITE, "Press any key to continue..." );         getch();         rPlayer.resetStats();     }     else if (pEnemy->getItsHitPoints()==0 && rPlayer.getItsHitPoints()>0)  // if player wins     {         rConManip.setOutputColor(YELLOW); cout << "\n\nEnemy Died.\nYou are victorious!\n";         cout << "\nYou have Earned " << winGold() << "g and " << winExperience() << "xp.";         rPlayer.levelUpTest();                 rPlayer.increaseLevelsFought(pEnemy->getItsLevel());         rConManip.printAtPositionAndColor(0, 49, SILVER, "\n\nPress any key to continue...");         getch();          }     else {rConManip.clearScreen(); cout << "An exception has occured."; getch();}}USHORT CombatControl::winExperience(){     if (pEnemy->getItsLevel() >= rPlayer.getItsLevel()) { rPlayer.setItsExperience(300); return 300;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-1) { rPlayer.setItsExperience(150); return 150;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-2) { rPlayer.setItsExperience(75); return 75;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-3) { rPlayer.setItsExperience(35); return 35;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-4) { rPlayer.setItsExperience(15); return 15;}     else { rPlayer.setItsExperience(5); return 5;}}float CombatControl::winGold(){     if (pEnemy->getItsLevel() >= rPlayer.getItsLevel()) { rPlayer.increaseItsGold(25); return 25;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-1) { rPlayer.increaseItsGold(12); return 12;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-2) { rPlayer.increaseItsGold(6); return 6;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-3) { rPlayer.increaseItsGold(3); return 3;}     else     if (pEnemy->getItsLevel() == rPlayer.getItsLevel()-4) { rPlayer.increaseItsGold(1); return 1;}     else { rPlayer.increaseItsGold(0.5); return 0.5;}}
Equipment.cpp
/////////////////////////////////////////// implementation of Equipment classes ///////////////////////////////////////////#include "headers.hpp"Equipment::Equipment(string name, float price):itsName(new string(name)),itsPrice(new float(price)){             }// destructorEquipment::~Equipment(){     delete itsName;     itsName = 0;     delete itsPrice;     itsPrice = 0;}/////////////////////////////////////////////////////////////////// implementation of Armor class, derived from class Equipment ///////////////////////////////////////////////////////////////////// constructor taking 4 parametersArmor::Armor(string name, float price, USHORT armorValue, USHORT maxDex):Equipment(name, price),itsArmorValue(new USHORT(armorValue)),itsMaxDex(new USHORT(maxDex)){}// copy constructorArmor::Armor(const Armor & rhs):Equipment(rhs.getItsName(), rhs.getItsPrice()),itsArmorValue(new USHORT(rhs.getItsAV())),itsMaxDex(new USHORT(rhs.getItsMaxDex())){}//destructorArmor::~Armor(){     delete itsArmorValue;     itsArmorValue = 0;     delete itsMaxDex;     itsMaxDex = 0;}//////////////////////////////////////////////////////////////////// implementation of Weapon class, derives from class Equipment ////////////////////////////////////////////////////////////////////// constructor with 7 parametersWeapon::Weapon( string name,                float price,                USHORT weaponDice,                USHORT weaponPowerMax,                USHORT criticalMin,                USHORT criticalMax,                USHORT criticalMultip                )                :                       // initializations                Equipment(name, price),                itsNumberDice(new USHORT(weaponDice)),                itsWeaponPowerMax(new USHORT(weaponPowerMax)),                itsCriticalMin(new USHORT(criticalMin)),                itsCriticalMax(new USHORT(criticalMax)),                itsCriticalMultip(new USHORT(criticalMultip)){}// copy constructorWeapon::Weapon(const Weapon & rhs):Equipment(rhs.getItsName(), rhs.getItsPrice()),itsNumberDice(new USHORT(rhs.getItsDice())),itsWeaponPowerMax(new USHORT(rhs.getItsMax())),itsCriticalMin(new USHORT(rhs.getItsCriticalMin())),itsCriticalMax(new USHORT(rhs.getItsCriticalMax())),itsCriticalMultip(new USHORT(rhs.getItsCriticalMultip())){}// destructorWeapon::~Weapon(){     delete itsNumberDice;     itsNumberDice =0;     delete itsWeaponPowerMax;     itsWeaponPowerMax =0;     delete itsCriticalMin;     itsCriticalMin =0;     delete itsCriticalMultip;     itsCriticalMultip =0;}
MainMenu.cpp
///////////////////////////////////////////////////////////////// implementation of MainMenu class, derives from class Menu /////////////////////////////////////////////////////////////////#include "headers.hpp"void MainMenu::drawMenu(){     rConManip.clearScreen();     rConManip.printAtPositionAndColor ( 0, 10, CYAN, "*************\n" );     rConManip.printAtPositionAndColor ( 0, 11, CYAN, "*           *\n" );     rConManip.printAtPositionAndColor ( 0, 12, CYAN, "* Main Menu *\n" );     rConManip.printAtPositionAndColor ( 0, 13, CYAN, "*           *\n" );     rConManip.printAtPositionAndColor ( 0, 14, CYAN, "*************\n\n\n" );     cout << "\nA. Create Character\n";     cout << "\nB. Purchase Equipment\n";     cout << "\nC. View Stats\n";     cout << "\nD. Fight!\n";     cout << "\nQ. Quit\n\n\n";     cout << "\nEnter Choice: ";}void MainMenu::testChoice(){     switch( (*pItsChoice)[0] )     {            case 'a': case 'A':                              // to create character.                   if (testIfCreate() == true)  // if character already exists, warn user about overwriting it                   {                        rConManip.clearScreen();                      rConManip.printAtPositionAndColor(0, 15, GOLD, "New Character has now been created");                      userReady();                      Menu *pCCmenu = new CCMenu(rPlayer, rConManip);  // create the sub-menu object                      pCCmenu->doMenu();                               // execute the submenu                          }                                                                                                   break;                                                                                                                                                                                           case 'b': case 'B':                                            // if user chooses to purchase equipment                                    if ( rPlayer.getItsCreatedStatus() == true )  // test if buyer exists                   {                        Menu *pPurchaseMenu = new PurchaseMenu(rPlayer, rConManip);  // create the sub-menu object                        pPurchaseMenu->doMenu();                   }                   else { cout << "\n\nNo Character Found.\n\n"; userReady(); }                   break;                        case 'c': case 'C':                             // if user chooses to view character statistics                 if (rPlayer.getItsCreatedStatus() == true) // check if character officially exists                    rPlayer.displayAllStats();                 else                    cout << "\n\nNo Character Found.\n";                 userReady();                               // weather displayed stats or not, call userReady()                 break;                            case 'd': case 'D':                 if (rPlayer.getItsCreatedStatus() == true) // check if character officially exists              {    CombatControl * pTheCombat = new CombatControl(rPlayer, rConManip);                   pTheCombat->setEnemyLevel();               // this enters the combat arena              }  else { cout << "\n\nNo Character Found.\n"; userReady();}                 break;                            case 'q': case 'Q':                 * pItsExit = true;                 break;                            default:                 cout << "\nSorry, invalid input. ";                 userReady();     }}bool MainMenu::testIfCreate(){     while (rPlayer.getItsCreatedStatus() == true) // if it is true that character already created     {          rConManip.printAtPositionAndColor(0, 40, BURGUNDY, "You have already created a Character.");          rConManip.printAtPositionAndColor(0, 42, DARKGREEN, "Continue to overwrite previous character? (Y/N): ");          cin >> * pItsChoice;          if ( pItsChoice->length() !=1 )              *pItsChoice = "! Too Many Characters Entered, so First Character, !, will default in the switch statment";          switch( (*pItsChoice)[0] )          {                 case 'y': case 'Y':                      rPlayer.resetStats();  // yes, clear previous character (if applicable) and proceed with creating new one.                      return true;           // proceed with creating new character                      break;                 // (necessary?)                                       case 'n': case 'N':                      return false;           // no, i dont want to continue overwriting                      break;                  // (necessary?)                                       default:                      rConManip.printAtPositionAndColor(0, 44, RED, "Invalid input.");                      userReady();                      for (USHORT cleanRow = 40; cleanRow < 50; cleanRow++)                        for (USHORT cleanColumn = 0; cleanColumn < 80; cleanColumn++)                          rConManip.printAtPositionAndColor(cleanColumn, cleanRow, RED, " ");                      continue;                      break;   // (necessary?)          }     }     return true;    // yes, true that user qualifies for creating new character}
CCMenu.cpp
/////////////////////////////////////////////////////////////// implementation of CCMenu class, derives from class Menu ///////////////////////////////////////////////////////////////#include "headers.hpp"void CCMenu::drawMenu(){     rConManip.clearScreen();     rPlayer.setCreatedStatus(true);      // this is needed for further re-entries into this menu, to test if need to                                            // warn him not to overwrite previous character or not.     rConManip.printAtPositionAndColor ( 0, 10, TEAL, "--------------------\n" );  ////////////////////////////     rConManip.printAtPositionAndColor ( 0, 11, TEAL, "|                  |\n" );  // display menu interface //     rConManip.printAtPositionAndColor ( 0, 12, TEAL, "| Create Character |\n" );  ////////////////////////////     rConManip.printAtPositionAndColor ( 0, 13, TEAL, "|                  |\n" );     rConManip.printAtPositionAndColor ( 0, 14, TEAL, "--------------------\n\n\n" );     cout << "\nA. Name Character\n";     cout << "\nB. Roll for Stats\n";     cout << "\nR. Return to main menu\n\n\n";     cout << "Enter Choice: ";}void CCMenu::testChoice(){     switch( (*pItsChoice)[0] )     {          case 'a': case 'A':               nameCharacter();               break;                     case 'b': case 'B':               rollForStats();               break;                     case 'r': case 'R':               if (rPlayer.getItsName() == "Undefined" || rPlayer.getItsDexterity() < 1)               {                    if (rPlayer.getItsName() == "Undefined")                    rConManip.printAtPositionAndColor(0, 28, RED, "Your character needs a name. Please name your character");                    if (rPlayer.getItsDexterity() < 1)                    rConManip.printAtPositionAndColor(0, 30, RED, "Your character's stats arent set. Please roll for stats");                    userReady();                    break;               }               *pItsExit = true;               break;                                 default:               cout << "\nSorry, invalid input. ";               userReady();     }        }void CCMenu::nameCharacter(){     cout << "\n\nYour characters current name: " << rPlayer.getItsName();     cout << "\n\nEnter your character's name (no spaces): ";     string name;     cin >> name;     rPlayer.setItsName(name);     cout << "\n\nPlayer's name set to \"" << rPlayer.getItsName() << "\".";     cin.clear();          userReady();    }void CCMenu::rollForStats(){     do {           rPlayer.setItsStrength( getRandomNumber(8, 12) );      // Giving random statistics to player's character,           rPlayer.setItsDexterity( getRandomNumber(8, 12) );     // this concerns its Strength, Dexterity, and Constitution.           rPlayer.setItsConstitution( getRandomNumber(8, 12) );  // INITIAL values range from 8-12 for these 3 stats.           rPlayer.setItsHitPoints(10+rPlayer.modifier(rPlayer.getItsConstitution())); // INITIAL HP           do {                 rPlayer.displayAllStats();                 rConManip.setOutputColor(SILVER);                 cout << "\n\nEnter 1 to roll for stats again. Enter any key if satisfied with stats: ";                 cin >> * pItsChoice;                 if ( (pItsChoice->length() > 1) && ((*pItsChoice)[0] == '1') )    // if more than 1 character input                 {                                                                 // AND first charcter is'nt 'any' key,                      cout << "\n\nSorry, invalid input.\n";                       // then print error                      userReady();                                                 //                 }                                                                 //              } while ( (pItsChoice->length() > 1) && ((*pItsChoice)[0] == '1') ); // then ask again                       } while ( (*pItsChoice)[0] == '1');}
PurchaseMenu.cpp
///////////////////////////////////////////////////////////////////// implementation of PurchaseMenu class, derives from class Menu /////////////////////////////////////////////////////////////////////#include "headers.hpp"void PurchaseMenu::drawMenu(){     rConManip.clearScreen();                                                                           rConManip.printAtPositionAndColor (0, 10, WHITE, "0000000000000000000000");     rConManip.printAtPositionAndColor (0, 11, WHITE, "0                    0");     rConManip.printAtPositionAndColor (0, 12, WHITE, "0 Purchase Equipment 0");     rConManip.printAtPositionAndColor (0, 13, WHITE, "0                    0");     rConManip.printAtPositionAndColor (0, 14, WHITE, "0000000000000000000000");     rConManip.printAtPositionAndColor (0, 17, WHITE, "A. Purchase Armor");     rConManip.printAtPositionAndColor (0, 19, WHITE, "B. Purchase Weapon");     rConManip.printAtPositionAndColor (0, 21, WHITE, "R. Return to previous menu");     rConManip.printAtPositionAndColor (0, 24, WHITE, "Enter choice: ");}void PurchaseMenu::testChoice(){        switch( (*pItsChoice)[0] )          {               case 'a':                  { Menu * pArmorStore = new PurchaseMenu::ArmorStore(rPlayer, rConManip);                    pArmorStore->doMenu();                  } break;                              case 'b':                  { Menu * pWeaponStore = new PurchaseMenu::WeaponStore(rPlayer, rConManip);                    pWeaponStore->doMenu();                  } break;                              case 'r':                    * pItsExit = true;                    break;                              default:                    cout << "\nSorry, invalid input.";                    userReady();          }}///////////////////////////////////////////////////////////////////////////////// implementation of PurchaseMenu::ArmorStore class, derives from class Menu //   nested type///////////////////////////////////////////////////////////////////////////////void PurchaseMenu::ArmorStore::drawMenu(){     rConManip.clearScreen();     rConManip.printAtPositionAndColor (32, 0, YELLOW, "++++++++++++++");     rConManip.printAtPositionAndColor (32, 1, YELLOW, "+ Armor Shop +");     rConManip.printAtPositionAndColor (32, 2, YELLOW, "++++++++++++++");     rConManip.printAtPositionAndColor (0, 4, YELLOW, "   ARMOR\t\tPROTECTION\tMAX DEX\t\tPRICE");     rConManip.printAtPositionAndColor (0, 6, GREEN, "A. Padded Armor\t\t+1\t\t+8\t\t5g");     rConManip.printAtPositionAndColor (0, 8, GREEN, "B. Leather Armor\t+2\t\t+6\t\t10g");     rConManip.printAtPositionAndColor (0, 10, GREEN, "C. Hide Armor\t\t+3\t\t+4\t\t15g");     rConManip.printAtPositionAndColor (0, 12, GREEN, "D. Studded Leather\t+3\t\t+5\t\t25g");     rConManip.printAtPositionAndColor (0, 14, GREEN, "E. Scale Mail\t\t+4\t\t+3\t\t50g");     rConManip.printAtPositionAndColor (0, 16, GREEN, "F. Chain Shirt\t\t+4\t\t+4\t\t100g");     rConManip.printAtPositionAndColor (0, 18, GREEN, "G. Chainmail\t\t+5\t\t+2\t\t150g");     rConManip.printAtPositionAndColor (0, 20, GREEN, "H. Breastplate\t\t+5\t\t+3\t\t200g");     rConManip.printAtPositionAndColor (0, 22, GREEN, "I. Splint Mail\t\t+6\t\t+0\t\t225g");     rConManip.printAtPositionAndColor (0, 24, GREEN, "J. Banded Mail\t\t+6\t\t+1\t\t250g");     rConManip.printAtPositionAndColor (0, 26, GREEN, "K. Half-Plate\t\t+7\t\t+0\t\t600g");     rConManip.printAtPositionAndColor (0, 28, GREEN, "L. Full Plate\t\t+8\t\t+1\t\t1000g");     rConManip.printAtPositionAndColor (0, 30, GREEN, "X. Exit Armor Shop.");     rConManip.printAtPositionAndColor (0, 32, RED, "Note: Sales are final. Buying new armor will discard your previous.");     rConManip.printAtPositionAndColor (0, 34, CYAN, "Current Armor: ");     cout << rPlayer.accessItsArmor().getItsName() << " / " << rPlayer.accessItsArmor().getItsAV()          << " / " << rPlayer.accessItsArmor().getItsMaxDex() << ".\n\nMoney to spend: " << rPlayer.getItsGold();          cout << "\n\nEnter your choice: ";}void PurchaseMenu::ArmorStore::testChoice(){     switch ( (*pItsChoice)[0] )     {            case 'x': case 'X':                 * pItsExit = true;                 break;//-----------------------------                        case 'a': case 'A':                               {  Armor paddedArmor("Padded Armor",	5, 1, 8);                 if ( buyerHasEnoughGold( paddedArmor.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(paddedArmor);              }  break;//-----------------------------            case 'b': case 'B':                               {  Armor leatherArmor("Leather Armor", 10, 2, 6);                 if ( buyerHasEnoughGold( leatherArmor.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(leatherArmor);              }  break;//-----------------------------            case 'c': case 'C':                               {  Armor hideArmor("Hide Armor", 15, 3, 4);                 if ( buyerHasEnoughGold( hideArmor.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(hideArmor);              }  break;//-----------------------------            case 'd': case 'D':                               {  Armor studdedLeather("Studded Leather", 25, 3, 5);                 if ( buyerHasEnoughGold( studdedLeather.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(studdedLeather);              }  break;//-----------------------------            case 'e': case 'E':                               {  Armor scaleMail("Scail Mail", 50, 4, 3);                 if ( buyerHasEnoughGold( scaleMail.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(scaleMail);              }  break;//-----------------------------            case 'f': case 'F':                               {  Armor chainShirt("Chain Shirt", 100, 4, 4);                 if ( buyerHasEnoughGold( chainShirt.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(chainShirt);              }  break;//-----------------------------            case 'g': case 'G':                               {  Armor chainmail("Chainmail", 150, 5, 2);                 if ( buyerHasEnoughGold( chainmail.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(chainmail);              }  break;//-----------------------------            case 'h': case 'H':                               {  Armor breastplate("Breastplate", 200, 5, 3);	                 if ( buyerHasEnoughGold( breastplate.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(breastplate);              }  break;//-----------------------------            case 'i': case 'I':                               {  Armor splintMail("Splint Mail", 225, 6, 0);                 if ( buyerHasEnoughGold( splintMail.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(splintMail);              }  break;//-----------------------------            case 'j': case 'J':                               {  Armor bandedMail("Banded Mail", 250, 6, 1);                 if ( buyerHasEnoughGold( bandedMail.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(bandedMail);              }  break;//-----------------------------            case 'k': case 'K':                               {  Armor halfPlate("Half Plate", 600, 7, 0);	                 if ( buyerHasEnoughGold( halfPlate.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(halfPlate);              }  break;//-----------------------------            case 'l': case 'L':                               {  Armor fullPlate("Full Plate", 1000, 8, 1);                 if ( buyerHasEnoughGold( fullPlate.getItsPrice() ) )  // test if buyer has enough funds for price                      rPlayer.buyArmor(fullPlate);              }  break;                          default:                 rConManip.printAtPositionAndColor (0, 44, RED, "Sorry, invalid input.");                 userReady();                 break;      }}bool PurchaseMenu::ArmorStore::buyerHasEnoughGold(float price){     if ( rPlayer.getItsGold() < price )     {          cout << "\n\nSorry, not enough gold to buy this weapon.";          userReady();          return false;     }          return true;}////////////////////////////////////////////////////////////////////////////////// implementation of PurchaseMenu::WeaponStore class, derives from class Menu //   nested type////////////////////////////////////////////////////////////////////////////////void PurchaseMenu::WeaponStore::drawMenu(){     rConManip.clearScreen();     rConManip.printAtPositionAndColor (32, 0, SILVER, "---------------");     rConManip.printAtPositionAndColor (32, 1, SILVER, "| Weapon Shop |");     rConManip.printAtPositionAndColor (32, 2, SILVER, "---------------");     rConManip.printAtPositionAndColor (0, 4, SILVER, "    WEAPON\t\tPOWER\t\tCRITICAL\tPRICE");     rConManip.printAtPositionAndColor (0, 6, GOLD, "A. Brass Knuckles\t1d4\t\t(20/x2)\t\t1g");     rConManip.printAtPositionAndColor (0, 8, GOLD, "B. Dagger\t\t1d4\t\t(19-20/x2)\t2g");     rConManip.printAtPositionAndColor (0, 10, GOLD, "C. Mace\t\t\t1d6\t\t(20/x2)\t\t5g");     rConManip.printAtPositionAndColor (0, 12, GOLD, "D. Handaxe\t\t1d6\t\t(20/x3)\t\t6g");     rConManip.printAtPositionAndColor (0, 14, GOLD, "E. Shortsword\t\t1d6\t\t(19-20/x2)\t6.5g");     rConManip.printAtPositionAndColor (0, 16, GOLD, "F. Scimitar\t\t1d6\t\t(18-20/x2)\t7g");     rConManip.printAtPositionAndColor (0, 18, GOLD, "G. Morningstar\t\t1d8\t\t(20/x2)\t\t8g");     rConManip.printAtPositionAndColor (0, 20, GOLD, "H. Spear\t\t1d8\t\t(20/x3)\t\t9g");     rConManip.printAtPositionAndColor (0, 22, GOLD, "I. Longsword\t\t1d8\t\t(19-20/x2)\t9.5g");     rConManip.printAtPositionAndColor (0, 24, GOLD, "J. Greatclub\t\t1d10\t\t(20/x2)\t\t11g");     rConManip.printAtPositionAndColor (0, 26, GOLD, "K. Halberd\t\t1d10\t\t(20/x3)\t\t12g");     rConManip.printAtPositionAndColor (0, 28, GOLD, "L. Bastard Sword\t1d10\t\t(19-20/x2)\t12.5g");     rConManip.printAtPositionAndColor (0, 30, GOLD, "M. Greataxe\t\t1d12\t\t(20/x3)\t\t16g");     rConManip.printAtPositionAndColor (0, 32, GOLD, "N. Greatsword\t\t2d6\t\t(19-20/x2)\t20g");     rConManip.printAtPositionAndColor (0, 34, GOLD, "X. Exit Weapon Shop");     rConManip.printAtPositionAndColor (0, 36, RED, "Note: Sales are final. Buying A new weapon will discard your previous.");     rConManip.printAtPositionAndColor (0, 38, CYAN, "Current Weapon: ");     cout << rPlayer.accessItsWeapon().getItsName() << " / " << rPlayer.accessItsWeapon().getItsDice() <<"d"      << rPlayer.accessItsWeapon().getItsMax() << " / (" << rPlayer.accessItsWeapon().getItsCriticalMin()      << "-" << rPlayer.accessItsWeapon().getItsCriticalMax() << "/x" << rPlayer.accessItsWeapon().getItsCriticalMultip()      << ")\n\nMoney to spend: " << rPlayer.getItsGold();     rConManip.printAtPositionAndColor (0, 42, SILVER, "Enter the letter of the weapon you wish to buy: ");}void PurchaseMenu::WeaponStore::testChoice(){     switch( (*pItsChoice)[0] )     {              case 'x': case 'X':                   * pItsExit = true;                   break;//----------------------------                                   case 'a': case 'A':                {  Weapon brassKnuckles("Brass Knuckles", 1.0, 1, 4, 20, 20, 2);                   if ( buyerHasEnoughGold( brassKnuckles.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(brassKnuckles);                }  break;//-----------------------------              case 'b': case 'B':                {  Weapon dagger("Dagger", 2.0, 1, 4, 19, 20, 2);                   if ( buyerHasEnoughGold( dagger.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(dagger);                }  break;//------------------------------              case 'c': case 'C':                {  Weapon mace("Mace", 5.0, 1, 6, 20, 20, 2);                   if ( buyerHasEnoughGold( mace.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(mace);                }  break;        //------------------------------              case 'd': case 'D':                {  Weapon handaxe("Handaxe", 6.0, 1, 6, 20, 20, 3);                   if ( buyerHasEnoughGold( handaxe.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(handaxe);                }  break;//------------------------------               case 'e': case 'E':                {  Weapon shortsword("Shortsword", 6.5, 1, 6, 19, 20, 2);                   if ( buyerHasEnoughGold( shortsword.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(shortsword);                }  break;//------------------------------              case 'f': case 'F':                {  Weapon scimitar("Scimitar", 7.0, 1, 6, 18, 20, 2);                   if ( buyerHasEnoughGold( scimitar.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(scimitar);                }  break; //------------------------------              case 'g': case 'G':                {  Weapon morningstar("Morningstar", 8.0, 1, 8, 20, 20, 2);                   if ( buyerHasEnoughGold( morningstar.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(morningstar);                }  break;//------------------------------              case 'h': case 'H':                {  Weapon spear("Spear", 9, 1, 8, 20, 20, 3);                   if ( buyerHasEnoughGold( spear.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(spear);                }  break;//------------------------------              case 'i': case 'I':                {  Weapon longsword("Longsword", 9.5, 1, 8, 19, 20, 2);                   if ( buyerHasEnoughGold( longsword.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(longsword);                }  break;//------------------------------              case 'j': case 'J':                {  Weapon greatclub("Greatclub", 11, 1, 10, 20, 20, 2);                   if ( buyerHasEnoughGold( greatclub.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(greatclub);                }  break;//------------------------------              case 'k': case 'K':                {  Weapon halberd("Halberd", 12, 1, 10, 20, 20, 3);                   if ( buyerHasEnoughGold( halberd.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(halberd);                }  break;//------------------------------              case 'l': case 'L':                {  Weapon bastardSword("Bastard Sword", 12.5, 1, 10, 19, 20, 2);                   if ( buyerHasEnoughGold( bastardSword.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(bastardSword);                }  break;//------------------------------              case 'm': case 'M':                {  Weapon greataxe("Greataxe", 16, 1, 12, 20, 20, 3);                   if ( buyerHasEnoughGold( greataxe.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(greataxe);                }  break;//------------------------------              case 'n': case 'N':                {  Weapon greatsword("Greatsword", 20, 2, 6, 19, 20, 2);                   if ( buyerHasEnoughGold( greatsword.getItsPrice() ) )  // test if buyer has enough funds for price                        rPlayer.buyWeapon(greatsword);                }  break;//------------------------------                             default:                        rConManip.printAtPositionAndColor (0, 44, RED, "Sorry, invalid input.");                        userReady();           }}bool PurchaseMenu::WeaponStore::buyerHasEnoughGold(float price){     if ( rPlayer.getItsGold() < price )     {          cout << "\n\nSorry, not enough gold to buy this weapon.";          userReady();          return false;     }          return true;}


Didint finnish commenting everything yet... i wonder if ill recognize my code one day...

[did some editing]
[did some editing again]
[did some more editing]

[Edited by - kingIZZZY on September 30, 2006 10:53:49 PM]
Thanks, kingIZZZY. Now get started on project 2. [grin]
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Quote:
headers.hpp (i took a shortcut of putting all headers in one file... just today)


I assume you know this is bad. But just in case, it's bad. Now any .cpp file that needs one of those classes must include the entire header file, making the object files unnecessarily large. Although linkers are able to optimize this out, it has an impact on your compile/link times.

Additionally, now any time you modify one of those classes declerations in the header, it will require a COMPLETE re-compile of your entire project, which is bad for productivity.

Better is to have one .h and one .cpp for each class, which ensures the smallest number of files need to be recompiled whenever a class changes.

Cheers!





Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Advertisement
@jwalsh:

Shucks, so I was just trying to re-organize the #includes from all files, boy did I get tangled up in circular dependancies and re-declarations... where was that link someone posted about organizing #includes?

KingIZZY, I believe splitting any .h's with classes in them into a .h with the definition (the class <name> {}), making sure any default arguments are defined in the definition, not the function declarations, and placing the functions in a .cpp with an #include to the .h, can really help with those circular dependancies. If you declare any objects of the class, add an "extern <class> <name>;" after the class definition in the .h, and a "<class> <name>;" in the .cpp.

Don't forget header guards. "#ifndef SOME_UNIQUE_ID" and "#define SOME_UNIQUE_ID" at the top of the .h's, and "#endif" at the end. Then all you do is include the .h in your files. Apparently any order works.

Um.. if you need examples, PM me, or comment on my journal. It took me a LONG while (like, a day) to figure this stuff out.



Having followed this workshop a bit I decided to have a go at the project. The source is here: http://files.filefront.com/workshopzip/;5964988;;/fileinfo.html
Most of the programming that I have done has been in c only so I wasn't sure about the way I went about things during the project. Overall I'm quite happy with the finished product however its the code that is most important to me and I would be grateful for any comments about the code.

I have to say that I have always found the idea of object orientation a little confusing and wasn't sure what member functions and member variables to include in the classes. Sometimes member functions that I thought would be needed turned out not to be the case at all and I found myself changing the member variables/function in the classes as the project went on. Also I decided to make use of structs rather than classes sometimes for certain things like armor and weapon. I did think that they could be part of an item/equipment class but since the only property armor and weapon shared was the cost of the item I did not feel it was worthwhile creating a class. Whether this would be considerd poor design or a poor understanding of object orientation I can't be sure of.

Anyone else have similar thoughts during the project or did you have a clear idea of everything that the class should include?

One thing that I did have a problem with was inclusion guards in the header files. Even though I included them in all my header files I got a lot complaints from the compiler(Visual C++ 2005 express edition) about redefinition errors. The problem persisted until I put pragma once in my header files. Does anyone know what the problem may be here?
How about them apples?
@jwalsh

back to page 2 of this project1 thread, about fullscreen etc.

Quote:
Original post by jwalsh
Fair questions. There is certain functionality in the visual studio libraries which only work on specific operating systems. How horrible would it be if you accidentally used these functions without knowing that you were forcing your users to have a specific operating system in order to run your program?!?

To avoid this scenario Microsoft wraps its operating system specific functionality within conditional compiles, such as you see above. Then, in order to use that functionality YOU must specifically state that you understand you're forcing your customers to have a specific operating system in order to run your application.

So the solution to your problem is to just, somewhere in your code, define _WIN32_WINNT to have a value greater than or equal to 0x0501. By doing this you're telling your compiler its ok to use operating system specific code.

For the record, defining _WIN32_WINNT to have a value of 0x0501 means that your code will only run on WinXP or better. If you don’t have WinXP or better, I'd recommend not using that code. =) 90% of Windows users are using WinXP these days, however, so its generally safe to use 0x0501 specific functions.

Also, NEVER MODIFY THE SYSTEM HEADERS. They are implemented in a specific way for a specific reason. If you find you must modify a system header, you're generally screwing yourself somewhere down the road. Figure out the correct way to solve your problem. [cool]

Cheers!


I get a warning: (im using dev-cpp)
[Warning] "_WIN32_WINNT " redefined
[Warning] this is the location of the previous definition

and it brings me to windef.h (which is included in windows.h). there is an interesting comment there:
...#ifndef WINVER#define WINVER 0x0400/* * If you need Win32 API features newer the Win95 and WinNT then you must * define WINVER before including windows.h or any other method of including * the windef.h header. */#endif#ifndef _WIN32_WINNT#define _WIN32_WINNT WINVER/* * There may be the need to define _WIN32_WINNT to a value different from * the value of WINVER.  I don't have any example of why you would do that. * However, if you must then define _WIN32_WINNT to the value required before * including windows.h or any other method of including the windef.h header. */#endif#ifndef WIN32...


I think VC++'s stdafx files take care of these issues, dont they? and still, is there a workaround for me using dev-cpp? should i listen to the comment and modify the header in any way? (modify header- DING DING DING oops i sent off the alarm...)

This topic is closed to new replies.

Advertisement