I dont know how you set it up , and i havent reached strings since i am still at chapter 9, but your solution seems overly compicated. If i get it right you want to print "Enemy level 1" and then give extra choise as he rises up in level. would
it be simpler to write something like
for(int i=1;i<PlayerLevel;i++)
{
std::cout << "(" << i << ")" << "Level " << i << " enemy." << std::endl;
}
and the take the choise , declaring every choise bigger than playerlevel illegal
and maybe creating an enemy like like i do : Actor Enemy(choise); wicth randomly generates an enemy of that level.
Sorry if this doesnt make sense or doesnt help you or doesnt fit in your program.
Good luck with your project.
Edit: I just saw your blog and i must say I feel quite silly giving advice to you. I am temted to delete this post but i want to know if my suggestion isnt any good so i dont implement it in my project.
C++ Workshop - Project 1
Quote:
AddMenuElement(Level.operator +=(SStream.str()));
Don't do that. Don't call operator+= - just use it! " Level += SStream.str() ".
I'm afraid I don't know the specifics of using stringstream (I use boost::lexical_cast for this sort of thing myself) so I can't help with the other problem. If all else fails, just move the declaration of the stringstream into the for loop.
Thanks for the replies guys! :)
And thanks to you, gparali, in particular. Your suggestion to use std::cout instead of AddMenuElement() was what I needed. :) Seems std::cout is completely comfortable with taking an int as a parameter and converting it to a string. However, AddMenuElement(), which is basically just a wrapper I've made over std::string.append(), is not.
rating++ to you guys. :)
And thanks to you, gparali, in particular. Your suggestion to use std::cout instead of AddMenuElement() was what I needed. :) Seems std::cout is completely comfortable with taking an int as a parameter and converting it to a string. However, AddMenuElement(), which is basically just a wrapper I've made over std::string.append(), is not.
rating++ to you guys. :)
_______________________Afr0Games
AddMenuElement(Level.operator +=(SStream.str()));
Afr0m@n, when you use the operator += in that sense, the string Level is being appended by the content on the right, in this case, the integer (in string form due to the stringstream) . This is different from using the + operator which will return a combination of the strings on the left and right side of the operator, without changing the value stored in memory for the variables for either string. So, doing:
AddMenuElement(Level + (SStream.str()));
Will return the string "Level: 1" (or whatever the number is), annd the value of the variable Level will still remain unchanged, i.e "Level: " .
....
Now, I'm almost done with this game as well but I've noticed the algorithms don't really work as expected. 80% of my attacks are unsuccessful, and if they are, then the damage is so high (around 6-15) as compared to the defender's hitpoints around (10-15) that it takes just one or two successful attacks to kill the opponent.
--------------------------------------Amaze your friends! Astound your family! Kennify your text!
Ok here is my code for this project. I don't have masses of time at the moment to refactor it much better, so ill just post it as it is and you gurues can rip it to bits :) I tweaked a couple of the calculations a little because it seemed my player was dieing too much to the monster :). Project files/source and executable.
Main.cpp
Battle.cpp
Battle.h
Equipment.cpp
Equipment.h
Player.h
Player.cpp
Menu.cpp
Menu.h
[Edited by - alexjp on September 11, 2006 10:24:26 AM]
Main.cpp
#include "Equipment.h"#include "Player.h"#include "Menu.h"#include "Battle.h"#include <iostream>#include <conio.h>using std::cin;using std::cout;void init(){ // Populate the weapon, armour and monsters tables. Weapon::fillWeapInventory(); Armour::fillArmourInventory(); Monster::fillMonsterTable(); Battle::precalcXPTable();}char getInput(){ char temp; std::cout << "\nChoice: "; temp = tolower(_getch()); return temp;}int main(){ init(); Menu menusystem; PlayerCharacter player; Battle battleground; bool gameOver = false; while (!gameOver) { setColour(WHITE); menusystem.clearConsole(); menusystem.dispMainMenu(); char choice = getInput(); switch (choice) { case 'a': // Character menu char c; menusystem.clearConsole(); menusystem.dispCharacterMenu(); // Check to see if player exists. if (PlayerCharacter::playerExists(&player)) { setColour(RED); std::cout << "\nYou have already Created a player!\n"; std::cout << "\nDo you wish to continue? [y - yes, n - no] \n"; setColour(WHITE); if (getInput() == 'n') break; } do { c = getInput(); PlayerCharacter::handleChar(c,&player); } while (c != 'r'); break; case 'b': // Purchase menu. if (!(PlayerCharacter::playerExists(&player))) { std::cout << "\nPlease create a character first!\n"; system("pause"); break; } menusystem.clearConsole(); std::cout << std::endl; menusystem.dispPurchaseMenu(); c = getInput(); Item::handleInput(c); std::cout << "Choice: "; int temp; cin >> temp; if (c == 'a') player.buyArmour(temp); else if (c == 'b') player.buyWeapon(temp); system("pause"); break; case 'c': // View stats. if (!(PlayerCharacter::playerExists(&player))) { std::cout << "\nPlease create a character first!\n"; system("pause"); break; } std::cout << player; system("pause"); break; case 'd': // Fight. if (!(PlayerCharacter::playerExists(&player))) { std::cout << "Please create a character first!\n"; system("pause"); break; } do { Monster *opponent = Monster::mobsToFight(player.getLvl()); if (opponent == NULL) break; std::cout << "\nStarting HPs " << player.getName() << " " << player.getHp() << " " << opponent->getName() << " " << opponent->getHp() << "\n"; battleground.fight(&player,opponent); if (player.isAlive()) // after the fight. { // Reset hp to max. player.setInitialHP(); // Calc Experience. setColour(BLUE); int xpGain = battleground.calcXP(&player,opponent->getLvl()); player.awardXP(xpGain); std::cout << "You have been awarded " << xpGain << "xp\n"; // Award Gold. double gGain = battleground.calcGold(&player,opponent->getLvl()); player.awardGold(gGain); std::cout << "You have been awarded " << gGain << "Gold\n"; setColour(YELLOW); std::cout << "Current XP: " << player.getXp() << std::endl; std::cout << "Current Gold: " << player.getGold() << std::endl; std::cout << "XP needed to next level " << (battleground.toNextLevel(&player) - player.getXp()) << std::endl; // Check to see if player has leveled up. if (player.getXp() >= battleground.toNextLevel(&player)) { player.levelUp(); std::cout << "\nLEVEL UP! xD " << player.getLvl() << "!!"; std::cout << "\nHPS have increased to: " << player.getHp(); } } opponent->setInitialHP(); // Reset monsters hps back to normal. setColour(WHITE); system("pause"); } while (player.isAlive()); if (!player.isAlive()) { setColour(RED); std::cout << "\nYour player has died!"; } break; case 'Q': // Quit gameOver = true; break; } } return 0;}
Battle.cpp
#include "Battle.h"#include <windows.h>#define WIN32_LEAN_AND_MEANint Battle::xpTable[20];void setColour(unsigned int color){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color );}void Battle::fight(PlayerEntity *player, PlayerEntity *opponent){ // First determine who has the initative. int pInit = player->calcInitiative(); int oInit = opponent->calcInitiative(); setColour(GREEN); if (pInit > oInit) { std::cout << player->getName() << " has the initative\n"; round(player,opponent); // Player attacks first. } else { std::cout << opponent->getName() << " has the initative\n"; round(opponent,player); // Opponent attacks first. } // Keep attacking till someone dies.}void Battle::round(PlayerEntity *p1, PlayerEntity *p2){ bool isCrit = false; int critMod = 0; int rCount = 1; do { setColour(WHITE); std::cout << "---------------------------------------------------------\n"; std::cout << "Round: " << rCount << " " << p1->getName() << " vs " << p2->getName() << p2->getHp() << " HP left \n"; // First player attacking. // Determine the attack roll. int p1ARoll = p1->calcARoll(); if (p1->isCrit(p1ARoll,p1->getWeap()->getCritroll())) { isCrit = true; critMod = p1->getWeap()->getCritMod(); } int p1AR = p1->calcAR(p1ARoll); //int p2AR = p2->calcAR(); if (p1AR > p2->calcAC(p1)) { setColour(RED); // Attack is a sucess. int dmg = (p1->calcDmg()); if (isCrit) // Calculate dmg { for (int i = 0; i < critMod; i++) dmg += (p1->calcDmg()); std::cout << "CRITICAL STRIKE\n"; } std::cout << p1->getName() << " Swings his " << (p1->getWeap()->getName()) << " and hits for " << dmg << " dmg\n"; p2->setHP(-dmg); if (checkDead(p1,p2)) return; } else { setColour(LIGHTGREY); std::cout << p1->getName() << " Misses! \n"; } isCrit = false; // Otherwise its not and other player hits. // Second player attacking. int p2ARoll = p1->calcARoll(); if (p2->isCrit(p2ARoll,p2->getWeap()->getCritroll())) { isCrit = true; critMod = p2->getWeap()->getCritMod(); } int p2AR = p2->calcAR(p2ARoll); if (p2AR > p1->calcAC(p2)) { setColour(RED); int dmg = (p2->calcDmg()); if (isCrit) // Calculate dmg { for (int i = 0; i < critMod; i++) dmg += (p2->calcDmg()); std::cout << "CRITICAL STRIKE\n"; } std::cout << p2->getName() << " Swings his " << (p2->getWeap()->getName()) << " and hits for " << dmg << " dmg\n"; p1->setHP(-dmg); if (checkDead(p1,p2)) return; } else { setColour(LIGHTGREY); std::cout << p2->getName() << " Misses! \n"; } isCrit = false; rCount++; setColour(WHITE); std::cout << "---------------------------------------------------------\n"; Sleep(1000); } while (p1->getHp() > 0 && p2->getHp() > 0); }bool Battle::checkDead(PlayerEntity *p1, PlayerEntity *p2){ if (p1->getHp() <= 0) { setColour(GREEN); std::cout << p1->getName() << " has died!\n"; p1->setDefeated(); p1->setAlive(false); setColour(WHITE); return true; } if (p2->getHp() <= 0) { setColour(GREEN); std::cout << p2->getName() << " has died!\n"; p2->setDefeated(); p2->setAlive(false); return true; } return false;}int Battle::calcXP(PlayerEntity *p1, int oLevel){ int diff = (p1->getLvl() - oLevel); if (diff == 0) return 300; else if (diff == 1) return 150; else if (diff == 2) return 75; else if (diff == 3) return 35; else if (diff == 4) return 15; else return 5;}double Battle::calcGold(PlayerEntity *p1,int oLevel){ int diff = (p1->getLvl() - oLevel); if (diff == 0) return 25; else if (diff == 1) return 12; else if (diff == 2) return 6; else if (diff == 3) return 3; else if (diff == 4) return 1; else return 0.5;}void Battle::precalcXPTable(){ xpTable[0] = 0; for (int i = 1; i < 20; i++) { xpTable = i * 1000 + xpTable[i-1]; }}int Battle::toNextLevel(PlayerEntity *p){ return xpTable[(p->getLvl())];}
Battle.h
#ifndef BATTLE_H#define BATTLE_H// This class handles the fighting system.#include "Equipment.h"#include "Player.h"enum Colours { BLACK = 0,BLUE,GREEN,CYAN,RED,MAGENTA,BROWN,LIGHTGREY,DARKGRAY,LIGHTBLUE,LIGHTGREEN,LIGHTCYAN,LIGHTRED,LIGHTMAGENTA,YELLOW,WHITE };void setColour(unsigned int color);class Battle{public: void fight(PlayerEntity *player, PlayerEntity *opponent); void round(PlayerEntity *p1, PlayerEntity *p2); bool checkDead(PlayerEntity *p1, PlayerEntity *p2); void determineDamage(PlayerEntity* player); int calcXP(PlayerEntity *p1,int oLevel); double calcGold(PlayerEntity *p1,int oLevel); static void precalcXPTable(); static int xpTable[20]; static int toNextLevel(PlayerEntity *p); };#endif
Equipment.cpp
#include "Equipment.h"#include <string>#include <vector>#include <iostream>// Defines needed for static members.std::vector<Weapon> Weapon::weaponInventory; std::vector<Armour> Armour::armourInventory;/////////////////////////////// Item - Base class /////////////////////////////// Item::Item(){ this->itemName = ""; this->cost = 0;}Item::Item(std::string itemName, double cost): itemName(itemName), cost(cost){}void Item::handleInput(char c){ if (c == 'a') { Armour::dispArmourInventory(); } else if (c == 'b') { Weapon::dispInventory(); }}//////////////////////////////// Weapon Class ///////////////////////////////Weapon::Weapon(): Item("",0){ this->nDice = 0; this->nSides = 0;}Weapon::Weapon(std::string itemName,double cost, int nDice, int nSides,int critRoll,int critMod): Item(itemName,cost){ this->nDice = nDice; this->nSides = nSides; this->critRoll = critRoll; this->critMod = critMod;}// Returns a pointer to a weapon the inventory.Weapon * Weapon::getWeapon(int num){ return &(weaponInventory.at(num));}void Weapon::fillWeapInventory() // Static.. { Weapon w0("Unarmed Strike",0,1,3,20,2); weaponInventory.push_back(w0); Weapon w1("Brass Knuckles",1,1,4,20,2); weaponInventory.push_back(w1); Weapon w2("Dagger",2,1,4,19,2); weaponInventory.push_back(w2); Weapon w3("Mace",5,1,6,20,2); weaponInventory.push_back(w3); Weapon w4("HandAxe",6,1,6,20,3); weaponInventory.push_back(w4); Weapon w5("Shortsword",6.5,1,6,19,2); weaponInventory.push_back(w5); Weapon w6("Scimitar",7,1,6,18,2); weaponInventory.push_back(w6); Weapon w7("Morningstar",8,1,8,20,2); weaponInventory.push_back(w7); Weapon w8("Spear",9,1,8,20,3); weaponInventory.push_back(w8); Weapon w9("Longsword",9.5,1,8,19,2); weaponInventory.push_back(w9); Weapon w10("Greatclub",11,1,10,20,2); weaponInventory.push_back(w10); Weapon w11("Halberd",12,1,10,20,3); weaponInventory.push_back(w11); Weapon w12("Bastard Sword",12.5,1,10,19,2); weaponInventory.push_back(w12); Weapon w13("Greataxe",16,1,12,20,3); weaponInventory.push_back(w13); Weapon w14("Greatsword",20,2,6,19,2); weaponInventory.push_back(w14);}void Weapon::dispInventory(){ size_t i; for (i = 0; i < weaponInventory.size(); i++) { std::cout << i << " " << weaponInventory; }}std::ostream& operator<<(std::ostream& output,Weapon& weap){ return output << weap.getName() << " " << weap.getCost() << "g" << "\n";}///////////////////// Armour Class //////////////////////////////////////Armour::Armour(): Item("",0){ this->dexModifier = 0; this->armourClass = 0;}Armour::Armour(std::string itemName, double cost, int ac, int dexMod): Item(itemName,cost){ this->armourClass = ac; this->dexModifier = dexMod;}// Return a pointer to a piece of armour in the inventory.Armour *Armour::getArmour(int num){ return &(armourInventory.at(num));}void Armour::fillArmourInventory() // This is actaully static.{ Armour a1("Unarmoured",0,0,0); armourInventory.push_back(a1); Armour a2("Padded armour",5,1,8); armourInventory.push_back(a2); Armour a3("Leather armour",10,2,6); armourInventory.push_back(a3); Armour a4("Hide armour",15,3,4); armourInventory.push_back(a4); Armour a5("Studded Leather",25,3,5); armourInventory.push_back(a5); Armour a6("Scale Mail",50,4,3); armourInventory.push_back(a6); Armour a7("Chain Shirt",100,4,4); armourInventory.push_back(a7); Armour a8("Chainmail",150,5,2); armourInventory.push_back(a8); Armour a9("Breastplate",200,5,3); armourInventory.push_back(a9); Armour a10("Splint Mail",225,6,0); armourInventory.push_back(a10); Armour a11("Banded Mail",250,6,1); armourInventory.push_back(a11); Armour a12("Half-Plate",600,7,0); armourInventory.push_back(a12); Armour a13("Full Plate",1000,8,1); armourInventory.push_back(a13);}std::ostream& operator<<(std::ostream& output,Armour& armour){ return output << armour.getName() << " " << armour.getCost() << "g" << "\n";}void Armour::dispArmourInventory() // Tis static.{ size_t i; for (i = 0; i < armourInventory.size(); i++) { std::cout << i << " " << armourInventory; }}
Equipment.h
// This class is used for the equipment of the character.#ifndef EQUIP_H#define EQUIP_H#include <string>#include <vector>#include <iostream>class Item{public: Item(); Item(std::string itemName, double cost); std::string getName() const { return itemName; } double getCost() const { return cost; } static void handleInput(char c);protected: std::string itemName; double cost;};class Weapon : public Item{public: friend std::ostream& operator<< (std::ostream& output,Weapon& weap); Weapon(); Weapon(std::string itemName,double cost,int nDice, int nSides,int critRoll,int critMod); int getNDice() const { return nDice; } int getNSides() const { return nSides; } int getCritroll() const { return critRoll; } int getCritMod() const { return critMod; } static std::vector<Weapon> weaponInventory; static void fillWeapInventory(); static void dispInventory(); static Weapon *getWeapon(int num);private: int nDice, nSides; // d6, d12 etc.. int critRoll, critMod;};class Armour : public Item{public: friend std::ostream& operator<< (std::ostream& output,Armour& armour); Armour(); Armour(std::string itemName,double cost,int ac,int dexMod); static std::vector<Armour> armourInventory; static void fillArmourInventory(); static void dispArmourInventory(); int getAC() const { return armourClass; } int getDexMod() const { return dexModifier; } static Armour *getArmour(int num);private: int armourClass; // AC. int dexModifier; // Add to max dexterity.};#endif
Player.h
#ifndef PLAYER_H#define PLAYER_H#include <string>#include <vector>#include "Equipment.h"// Base classclass PlayerEntity{public: PlayerEntity(); PlayerEntity(std::string name, int level, int str, int dex, int con, int hp, Weapon *weapon = 0, Armour *armour = 0,bool defeated = false); ~PlayerEntity(); void setWeapon(Weapon* weapon); void setArmour(Armour* armour); void setName(); void rollStats(); void setHP(int HPmod); void setInitialHP(); void setDefeated(); void setAlive(bool alive); void resetToMaxHP(); void incLvl(); virtual void buyWeapon(int w) = 0; virtual void buyArmour(int a) = 0; int calcInitiative() const; int calcMod(int stat) const; int calcAR(int ARoll) const; int calcARoll() const; int calcAC(PlayerEntity* mob) const; int calcDmg() const; int roll(int nDice,int nSides) const; bool isCrit(int ARoll,int critValue) const; static int randRange(int start, int end); static void handleChar(char c,PlayerEntity* p); // Accessors std::string getName() const { return name; } int getLvl() const { return level; } int getStr() const { return str; } int getDex() const { return dex; } int getCon() const { return con; } int getHp() const { return hp; } bool isDefeated() const { return defeated; } bool isAlive() const { return alive; } Weapon* getWeap() { return weapon; } Armour* getArmour() { return armour; }private: std::string name; int level, str, dex, con, hp, maxHP; bool alive, defeated; // Pointers to items in inventory. Weapon* weapon; Armour* armour;};// A normal player character.class PlayerCharacter : public PlayerEntity{public: friend std::ostream& operator<< (std::ostream& output,PlayerCharacter& player); PlayerCharacter(); ~PlayerCharacter(); PlayerCharacter(std::string name,int str,int dex,int con,int hp,double gold, double xp); void buyWeapon(int w); void buyArmour(int a); void levelUp(); double getGold() const { return gold; } double getXp() const { return xp; } void awardGold(double amount); void awardXP(int amount); static bool playerExists(PlayerCharacter *p);private: double gold, xp;};// A monster in the game.class Monster : public PlayerEntity{public: friend std::ostream& operator<< (std::ostream& output,Monster& monster); Monster(); ~Monster(); Monster(std::string name,int level,int str, int dex,int con, int hp,Weapon *weapon,Armour *armour,bool defeated = false); void setMonsterHP(int hp); void setDefeated(); void buyWeapon(int w); void buyArmour(int a); static void fillMonsterTable(); static Monster *getMonster(int mob); static void dispMonsters(); static Monster *mobsToFight(int level);private: static std::vector<Monster> monsterTable; static Monster rogMonster(std::string name,int level,Weapon *weapon,Armour *armour); static int mRoll(int nDice,int nSides); static int rogHPs(int lvl,int con); // Randomly generate hps depending on lvl. bool defeated;};#endif
Player.cpp
#include "Player.h"#include "Equipment.h"#include <iostream>#include <conio.h>#include <ctime>// Defines needed for static members.std::vector<Monster> Monster::monsterTable; // Base class.PlayerEntity::PlayerEntity(){ this->level = 1; this->str = 0; this->dex = 0; this->con = 0; this->weapon = Weapon::getWeapon(0); this->armour = Armour::getArmour(0); this->hp = 0;}PlayerEntity::PlayerEntity(std::string name, int level, int str, int dex, int con, int hp, Weapon *weapon, Armour *armour,bool defeated){ this->name = name; this->level = level; this->str = str; this->dex = dex; this->con = con; this->hp = hp; this->defeated = defeated;}PlayerEntity::~PlayerEntity(){}void PlayerEntity::setDefeated(){ this->defeated = true;}void PlayerEntity::setAlive(bool alive){ this->alive = alive;}void PlayerEntity::incLvl(){ this->level++;}void PlayerEntity::setName(){ std::string name; std::cout << "\nEnter a name: "; std::cin >> name; this->name = name;}void PlayerEntity::rollStats(){ char c; do { std::cout << "\nRolling for stats: "; this->str = randRange(8,20); std::cout << "\nStrength: " << this->str << std::endl; this->dex = randRange(8,20); std::cout << "Dexterity: " << this->dex << std::endl; this->con = randRange(8,20); std::cout << "Constitution: " << this->con << std::endl; std::cout << "\nKeep stats: y for yes, n for no\n"; std::cout << "Choice: "; c = _getch(); } while (c != 'y'); setInitialHP(); setAlive(true);}void PlayerEntity::setInitialHP(){ this->hp = 10 + calcMod(getCon());}void PlayerEntity::handleChar(char c,PlayerEntity *p){ if (c == 'a') p->setName(); else if (c == 'b') p->rollStats();}void PlayerEntity::setArmour(Armour *armour){ this->armour = armour; // Update stats.}void PlayerEntity::setWeapon(Weapon *weapon){ this->weapon = weapon;}int PlayerEntity::randRange(int start,int end) { return start + (rand() % (start - end));}// Calculate the stat modifier.int PlayerEntity::calcMod(int mod) const{ return (mod - 10) / 2;}// Calculate the initiative value.int PlayerEntity::calcInitiative() const{ return randRange(1,20) + calcMod(dex);}// Calculate the attack roll.int PlayerEntity::calcARoll() const{ int ARoll = randRange(1,20); return ARoll;}int PlayerEntity::calcAR(int ARoll) const{ return ARoll + (calcMod(str) + level);}bool PlayerEntity::isCrit(int ARoll,int critValue) const{ return ARoll >= critValue;}// Calculate the armour check.int PlayerEntity::calcAC(PlayerEntity* mob) const{ return 10 + mob->getArmour()->getAC() + calcMod(dex);}int PlayerEntity::roll(int nDice,int nSides) const{ int i = 0; int r = 0; for (i = 0; i < nDice; ++i) r += randRange(1,nSides); return r;}void PlayerEntity::setHP(int HPmod){ this->hp += HPmod;}// Calculate the damage caused.int PlayerEntity::calcDmg() const{ return roll(weapon->getNDice(),weapon->getNSides()) + calcMod(str);}/////////////////////////////////////// The player character. /////////////////////////////////////////PlayerCharacter::PlayerCharacter(){ this->gold = 0; this->xp = 0; srand((unsigned)time(0)); }PlayerCharacter::~PlayerCharacter(){}PlayerCharacter::PlayerCharacter(std::string name, int str, int dex, int con, int hp, double gold, double xp): PlayerEntity(name,0,str,dex,con,hp){ this->gold = 0; this->xp = 0;}std::ostream& operator<<(std::ostream& output, PlayerCharacter& player){ return output << "\nName: " << player.getName() << "\nLevel: " << player.getLvl() << "\nStr: " << player.getStr() << "\nCon : " << player.getCon() << "\nDex: " << player.getDex()<< "\nHP" << player.getHp() << "\nWeapon: " << *player.getWeap() << "Armour: " << *player.getArmour() << "\n";}void PlayerCharacter::buyWeapon(int w){ Weapon *temp = Weapon::getWeapon(w); int t = w; do { if (temp->getCost() > this->getGold()) { std::cout << "\nSorry you cannot afford this.\n"; } // Check to see if the weapon your buying is not the same as the one you got already. else if (temp->getName().compare(this->getWeap()->getName()) == 0) { std::cout << "You already have this weapon!\n"; } std::cout << "Current gold " << this->getGold(); std::cout << "\nPlease enter a new selection, Or enter -1 to exit\n"; std::cin >> t; if (t == -1) return; temp = Weapon::getWeapon(t); } while (t != -1 || temp->getCost() > this->getGold()); setWeapon(temp);}void PlayerCharacter::buyArmour(int a){ Armour *temp = Armour::getArmour(a); int t = a; do { if (temp->getCost() > this->getGold()) { std::cout << "\nSorry you cannot afford this.\n"; } // Check to see if the weapon your buying is not the same as the one you got already. else if (temp->getName().compare(this->getArmour()->getName()) == 0) { std::cout << "You already have this weapon!\n"; } if (temp->getCost() < this->getGold()) { std::cout << "You have purchased: " << temp->getName() << std::endl; setArmour(temp); return; } std::cout << "Current gold " << this->getGold(); std::cout << "\nPlease enter a new selection Or enter -1 to exit\n"; std::cin >> t; if (t == -1) return; temp = Armour::getArmour(t); } while (t != -1 || temp->getCost() > this->getGold()); setArmour(temp);}bool PlayerCharacter::playerExists(PlayerCharacter *p){ return p->isAlive() && p->getName() != "" && p->getCon() != 0 && p->getDex() != 0 && p->getStr() != 0;}void PlayerCharacter::levelUp(){ // Increase hps setHP(randRange(1,10) + calcMod(getCon())); // Add one to level. incLvl();}void PlayerCharacter::awardGold(double amount){ this->gold += amount;}void PlayerCharacter::awardXP(int amount){ this->xp += amount;}// Monster class.Monster::Monster(){}Monster::Monster(std::string name,int lvl,int str, int dex, int con, int hp, Weapon *weapon, Armour *armour,bool defeated): PlayerEntity(name,lvl,str,dex,con,hp,weapon,armour){ setWeapon(weapon); setArmour(armour); setMonsterHP(hp); this->defeated = defeated;}Monster::~Monster(){}void Monster::setMonsterHP(int hp){ setHP(hp);}void Monster::setDefeated(){ this->defeated = true;}std::ostream& operator<<(std::ostream& output, Monster& monster){ return output << "\nName: " << monster.getName() << "\nLevel: " << monster.getLvl() << "\nStr: " << monster.getStr() << "\nCon : " << monster.getCon() << "\nDex: " << monster.getDex() << "\nHP : " << monster.getHp() << "\n" << *(monster.getWeap()) << "Defeated: " << monster.isDefeated() << "\n";}Monster *Monster::getMonster(int mob){ return &monsterTable.at(mob);}void Monster::dispMonsters(){ size_t i; for (i = 0; i < monsterTable.size(); i++) { std::cout << monsterTable; }}void Monster::buyWeapon(int w){ setWeapon(Weapon::getWeapon(w));}void Monster::buyArmour(int a){ setArmour(Armour::getArmour(a));}// Populate a table full of 20 monsters, the max level.void Monster::fillMonsterTable(){ monsterTable.push_back(rogMonster("Level 1 Monster ",1,Weapon::getWeapon(0),Armour::getArmour(0))); monsterTable.push_back(rogMonster("Level 2 Monster ",2,Weapon::getWeapon(0),Armour::getArmour(0))); monsterTable.push_back(rogMonster("Level 3 Monster ",3,Weapon::getWeapon(1),Armour::getArmour(1))); monsterTable.push_back(rogMonster("Level 4 Monster ",4,Weapon::getWeapon(1),Armour::getArmour(1))); monsterTable.push_back(rogMonster("Level 5 Monster ",5,Weapon::getWeapon(2),Armour::getArmour(2))); monsterTable.push_back(rogMonster("Level 6 Monster ",6,Weapon::getWeapon(2),Armour::getArmour(2))); monsterTable.push_back(rogMonster("Level 7 Monster ",7,Weapon::getWeapon(3),Armour::getArmour(3))); monsterTable.push_back(rogMonster("Level 8 Monster ",8,Weapon::getWeapon(3),Armour::getArmour(3))); monsterTable.push_back(rogMonster("Level 9 Monster ",9,Weapon::getWeapon(4),Armour::getArmour(4))); monsterTable.push_back(rogMonster("Level 10 Monster ",10,Weapon::getWeapon(4),Armour::getArmour(4))); monsterTable.push_back(rogMonster("Level 11 Monster ",11,Weapon::getWeapon(5),Armour::getArmour(5))); monsterTable.push_back(rogMonster("Level 12 Monster ",12,Weapon::getWeapon(5),Armour::getArmour(5))); monsterTable.push_back(rogMonster("Level 13 Monster ",13,Weapon::getWeapon(6),Armour::getArmour(6))); monsterTable.push_back(rogMonster("Level 14 Monster ",14,Weapon::getWeapon(6),Armour::getArmour(6))); monsterTable.push_back(rogMonster("Level 15 Monster ",15,Weapon::getWeapon(7),Armour::getArmour(7))); monsterTable.push_back(rogMonster("Level 16 Monster ",16,Weapon::getWeapon(7),Armour::getArmour(7))); monsterTable.push_back(rogMonster("Level 17 Monster ",17,Weapon::getWeapon(8),Armour::getArmour(8))); monsterTable.push_back(rogMonster("Level 18 Monster ",18,Weapon::getWeapon(9),Armour::getArmour(9))); monsterTable.push_back(rogMonster("Level 19 Monster ",19,Weapon::getWeapon(10),Armour::getArmour(10))); monsterTable.push_back(rogMonster("Level 20 Monster ",20,Weapon::getWeapon(11),Armour::getArmour(11)));}// Randomly generate a monsters statistics.Monster Monster::rogMonster(std::string name, int level, Weapon *weapon, Armour *armour){ int str = randRange(8,16); int dex = randRange(8,16); int con = randRange(8,16); int hp = rogHPs(level,con); return Monster(name,level,str,dex,con,hp,weapon,armour);}int Monster::rogHPs(int lvl,int con){ int hp = 0, i = 0; for (i = 0; i < lvl; ++i) hp += mRoll(1,8) + (con-11)/2; return hp;}int Monster::mRoll(int nDice,int nSides){ int i = 0, r = 0; for (i = 0; i < nDice; ++i) r += randRange(1,nSides); return r;}// Display all the available monsters to fight.// And then return the oponent.Monster *Monster::mobsToFight(int level){ std::cout << monsterTable.at(0); // Always display first monster. for (size_t i = 1; i < monsterTable.size(); i++) { if (monsterTable.at(i-1).isDefeated()) // If the previous monster is defeated. { std::cout << "\n" << monsterTable.at(i); } } int choice = 0;loop: do { std::cout << "Please choose a level\n"; std::cout << "Choice [0 for previous menu]: "; std::cin >> choice; if (choice == 0) { Monster *nullmob = 0; return nullmob; } } while (!(choice > 0 && choice < 21)); if (choice != 1 && !(monsterTable.at(choice-2).isDefeated())) { std::cout << "You cannot fight this monster yet\n"; goto loop; // Eeek. } return &monsterTable.at(choice-1);}
Menu.cpp
#include "Menu.h"#include <iostream>using std::cout;using std::endl;// Function for displaying the main menu.void Menu::dispMainMenu(){ cout << "==============================" << endl; cout << "Main Menu" << endl; cout << "==============================" << endl; cout << "Menu Options: " << endl; cout << "a. Create Character" << endl; cout << "b. Purchase Equipment" << endl; cout << "c. View Stats" << endl; cout << "d. Fight!" << endl; cout << "Q. Quit" << endl;}// Function for displaying character options.void Menu::dispCharacterMenu(){ cout << "==============================" << endl; cout << "Create Character" << endl; cout << "==============================" << endl; cout << "Menu Options: " << endl; cout << "a. Name Character" << endl; cout << "b. Roll for Stats" << endl; cout << "R. Return to previous menu" << endl; cout << "==============================" << endl;}// Displays Purchase Options.void Menu::dispPurchaseMenu(){ cout << "==============================" << endl; cout << "Purchase Equipment" << endl; cout << "==============================" << endl; cout << "Menu Options: " << endl; cout << "a. Purchase Armor" << endl; cout << "b. Purchase Weapon" << endl; cout << "R. Return to previous menu" << endl; cout << "==============================" << endl;}// Function to clear the console.void Menu::clearConsole(){ system("cls");}
Menu.h
#ifndef MENU_H#define MENU_Hclass Menu{public: void getInput(); void dispMainMenu(); void dispCharacterMenu(); void dispPurchaseMenu(); void clearConsole();};#endif
[Edited by - alexjp on September 11, 2006 10:24:26 AM]
Quote:
Original post by kingIZZZY
alexjp: gr8 job.
(p.s. bug, cannot quit game.)
Ah yes, I changed my input method to convert everything to lower case then forgot to change the Case statement, ty :)
Well, here is my program. I already had C++ knoledge, but I can't get the OOP,so I found these project really interesting. Here is my code, in which I like the CItemStore class, and I don't like the CArena class. It is just a big gontainer of everything, so at that point I could not get a better design... Hope time and practice gives me a better understanding of this. By the way, thanks for all the tutors for the help, that encourages us so much!
item.h --> Abstract class for items
armor.h --> Armors
weapon.h --> Weapons
store.h --> For buying items (armors and weapons)
die.h --> For simulating dice playing
menu.h --> For the menus (but them don't make decission switching)
console.h --> For managing the console (colors and input mainly)
character.h --> For the player and the enemyes
battle.h --> Battle system
arena.h --> ... huge class that has all the components of the program
Already taking a lot of space, so the whole source code and the compiled program is in here. Critics are welcomed :)
Source code
Executable for Windows
item.h --> Abstract class for items
#ifndef __ITEM__#define __ITEM__#include <string>enum tItemType{ ARMOR_TYPE = 1, WEAPON_TYPE = 2};class IItem{public:protected: std::string _sName; float _fPrice; int _nType;public: IItem (); IItem (const int &nType, const std::string &sName, const float fPrice=0); ~IItem (); void SetName (const std::string sName); const std::string &GetName () const; void SetPrice (const float &fPrice); float GetPrice () const; int GetType () const; virtual void Print () const =0;protected:};#endif
armor.h --> Armors
#ifndef __ARMOR__#define __ARMOR__#include "item.h"#include <string>class CArmor : public IItem{public: void SetArmorCheck (const int &check); void SetLimitDexterityModifier (const int &nMultiplier); int GetArmorCheck () const; int GetLimitDexterityModifier () const; void Print () const;private: int nArmorCheck; int nLimitDexterityModifier;public: CArmor (const std::string &name, const float &price=0, const int &check=0, const int &limiteDexterity=1000); ~CArmor ();private:};#endif
weapon.h --> Weapons
#ifndef __WEAPON__#define __WEAPON__#include "item.h"#include <string>class CWeapon : public IItem{public: void SetDamage (const int &nMin, const int &nMax); void SetCriticalStrikeLevel (const int &nLevel); void SetCriticalStrikeMultiplier (const int &nMultiplier); void GetDamage (int &nMin, int &nMax) const; int GetCriticalStrikeLevel () const; int GetCriticalStrikeMultiplier () const; void Print () const;private: int nDamageMin; int nDamageMax; int nCriticalStrikeLevel; int nCriticalStrikeMultiplier;public: CWeapon (const std::string &name, const float &price=1, const int &minDamage=1, const int &maxDamage=1, const int &strikeLevel=20, const int &strikeMultiplier=1); ~CWeapon ();private:};#endif
store.h --> For buying items (armors and weapons)
#ifndef __STORE__#define __STORE__#include "item.h"#include "character.h"#include <vector>class CItemStore{public:protected: std::vector <IItem*> _Items;public: CItemStore (); ~CItemStore (); void BuyItem (CCharacter &character); void SetStock (const std::vector <IItem*> &stock); const std::vector <IItem*> &GetStock () const;private: void Print (const CCharacter &character) const; int GetOption ();};#endif
die.h --> For simulating dice playing
#ifndef __DIE__ #define __DIE__class CDie{public:private:public: static unsigned long Dies (const unsigned long &nTimes=1, const unsigned long &nFaces=6, const unsigned long &nMin=1);};#endif
menu.h --> For the menus (but them don't make decission switching)
#ifndef __CMENU__#define __CMENU__#include <vector>#include <string>class CMenu{public:private: char cSeparator; unsigned int nSeparatorCount; std::string sTitle; std::vector <std::string> options;public: CMenu (); ~CMenu (); void SetOption (const unsigned long &nPos, const std::string &text); void SetOptionCount (const unsigned long &nCount); void SetTitle (const std::string &text); void SetSeparatorCharacter (const char &separator); void SetSeparatorCount (const unsigned int &nCount); int GetOption ();private: void Print () const;};#endif
console.h --> For managing the console (colors and input mainly)
#ifndef __CONSOLE__#define __CONSOLE__#include "windows.h"#include <vector>#include <string>enum tConsoleColor{ foreground_white, foreground_red, foreground_green, foreground_blue, foreground_yellow, foreground_white_low, foreground_red_low, foreground_green_low, foreground_blue_low, foreground_yellow_low};class CConsole{public:private: HANDLE _hConsole; static CConsole* _pConsole; std::vector <std::string> _vsArgs;public: static CConsole& Console (); void ClearScreen () const; void SetTextColor (const int &color) const; std::vector <std::string> GetInput (); void KeyPress () const; bool GetNumber (const std::string &sToken, int &nNumber);protected: CConsole ();};#endif
character.h --> For the player and the enemyes
#ifndef __CHARACTER__#define __CHARACTER__#include <vector>#include <string>#include "weapon.h"#include "armor.h"enum tCharacterAttributes{ character_strength, character_dexterity, character_constitution, character_intellect, character_wisdom, character_charisma, character_attributes_count};class CCharacter{public: private: std::string _sName; unsigned int _nLevel; unsigned long _nExperience; float _fGold; int _nHitPoints; std::vector <std::string> _attributes_name; std::vector <int> _attributes; CArmor _armor; CWeapon _weapon;public: CCharacter (const std::string &sName); ~CCharacter (); const std::string &GetName () const; unsigned int GetStrength () const; unsigned int GetDexterity () const; unsigned int GetConstitution () const; unsigned int GetIntellect () const; unsigned int GetWisdom () const; unsigned int GetCharisma () const; unsigned int GetLevel () const; unsigned int GetHP () const; unsigned long GetExperience() const; float GetGold () const; void SetName (const std::string &sName); void SetStrength (const unsigned int &nStrength); void SetDexterity (const unsigned int &nDexterity); void SetConstitution (const unsigned int &nConstitution); void SetIntellect (const unsigned int &nIntellect); void SetWisdom (const unsigned int &nWisdom); void SetCharisma (const unsigned int &nCharisma); void SetLevel (const unsigned int &nLevel); void SetGold (const float &fGold); void SetExperience(const unsigned long &nExperience); void SetHP (const unsigned int &nHP); void SetAttribute (const unsigned int &id, const int &nValue); int GetAttribute (const unsigned int &id) const; void SetArmor (const CArmor &armor); const CArmor &GetArmor () const; void SetWeapon (const CWeapon &weapon); const CWeapon &GetWeapon () const; void Print () const; void PrintStats () const;private:};#endif
battle.h --> Battle system
#ifndef __BATTLE__#define __BATTLE__#include "character.h"#include "armor.h"#include "weapon.h"class CBattle{public:private:public: CBattle (); bool Fight (CCharacter &player, CCharacter &enemy);private: int AttackRole (const CCharacter &character) const; bool AttackSucces (const CCharacter &character, const CArmor &armor, const CArmor &armor2, const int &attack) const; int AttackDamage (const CCharacter &character, const CWeapon &weapon); void Wait (const int &nMiliSeconds);};#endif
arena.h --> ... huge class that has all the components of the program
#ifndef __ARENA__#define __ARENA__#include <vector>#include "character.h"#include "armor.h"#include "weapon.h"#include "menu.h"#include "store.h"enum tArenaState{ arena_state_main_menu, arena_state_character_menu, arena_state_equipment_menu, arena_state_fight, arena_state_show_stats, arena_state_exit};class CArena{public:private: CMenu _mainMenu; CMenu _characterMenu; CMenu _equipmentMenu; CItemStore _armors; CItemStore _weapons; CCharacter _character; bool _bCharacter; int _nState; std::vector <int> _ExperinceLevelUpgrade;public: CArena (); ~CArena (); void Play ();private: void LoadArmor (); void LoadWeapon (); void InitializeMenus (); tArenaState StateMainMenu (); tArenaState StateEquipmentMenu (); tArenaState StateCharacterMenu (); tArenaState StateFight (); tArenaState StateShowStats (); void NameCharacter (); void RollStats (); bool Fight (const int &nEnemyLevel);};#endif
Already taking a lot of space, so the whole source code and the compiled program is in here. Critics are welcomed :)
Source code
Executable for Windows
Thought I'd join to get some routine. So, we're not expected to build up an inventory management and when the character buys a weapon/armor piece it should be replacing the existing one and not be an extra option?
Quote:
Original post by Darkstrike
Thought I'd join to get some routine. So, we're not expected to build up an inventory management and when the character buys a weapon/armor piece it should be replacing the existing one and not be an extra option?
I'd advocate KISS (keep it simple, stupid) as implementing a inventory management doesn't add much to the project so far (it might change, I don't know what jwalsh is preparing for project 2). The user will probably select the more effective piece of equipement he have, that's all (but you still can do something: when the user buy a weapon, his current weapon is automatically sold for 1/4 of the item price).
Regards,
-- Emmanuel D. [blog, in French] [blog, very bad googlized translation]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement