This is the main Test File and cannot be changed and there are 3 files in total not including Header files. main.cpp, engine.cpp, ship.cpp. I have included a screenshot of my error as well but its the invalid read of size 8 error (memory leak) at the T5 part of the test in the ship.cpp file. It outputs the correct answer but obviously has a memory leak.My error pic
#include <iostream>
#include "Ship.h"
#include "Ship.h"
#include "Engine.h"
#include "Engine.h"
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
int main()
{
{
printHeader("T1: Testing Constants");
cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
cout << endl;
}
{
printHeader("T2: Testing Default Constructor");
Ship invalid;
invalid.display();
invalid += Engine("D2", 2.1);
cout << endl;
}
Engine engines[] = {
Engine("V8", 4.4),
Engine("V8", 5.0),
Engine("Inline", 4.1),
Engine("D3", 7.0),
Engine("D0", 2.0),
Engine("D1", 3.2),
};
{
printHeader("T3: Testing Custom Constructor");
Ship titanic("cruiser", engines, 6);
titanic.display();
cout << endl;
}
{
printHeader("T4: Testing Conversion to Bool Operator");
Ship invalid;
Ship titanic("liner", engines, 1);
if (invalid)
cout << "1. Test Failed! Object should be invalid.\n";
else
cout << "1. Test succeeded!\n";
if (titanic)
cout << "2. Test succeeded!\n";
else
cout << "3. Test Failed! Object should be valid.\n";
cout << endl;
}
{
printHeader("T5: Testing += and < Operators");
Ship titanic("liner", engines, 3);
char type[]{ "D0" };
while (titanic < sdds::MIN_STD_POWER)
{
type[1]++;
cout << "Ship not up to standard. Required power: "
<< sdds::MIN_STD_POWER << endl;
titanic += Engine(type, 2.1);
}
titanic.display();
if (sdds::MAX_STD_POWER < titanic)
cout << "Too much power." << endl;
else
cout << "Ship doesn't exceed power regulation of: "
<< sdds::MAX_STD_POWER << endl;
}
return 0;
}
This is my engine.cpp file
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include "Engine.h"
using namespace sdds;
using namespace std;
namespace sdds {
Engine::Engine(){ // Default Empty Engine
m_type[0] = '\0';
m_size = 0.0;
}
Engine::Engine(const char* type, double size){ // Custom Engine
strncpy(m_type, type, TYPE_MAX_SIZE);
m_size = size;
}
double Engine::get() const{ // Getter for the size of the engine
return m_size;
}
void Engine::display() const{ // Basic Display Function
cout << m_size << " liters - " << m_type << endl;
}
}
This is my ship.cpp where the error is in the += overloaded operator function.
#include <iostream>
#include <cstring>
#include "Ship.h"
using namespace std;
namespace sdds {
Ship::Ship(){ // Default Ship (empty)
m_type = nullptr;
m_engines = nullptr;
m_engCnt = 0;
}
Ship::Ship(const char* type, const Engine* engines, int engCnt){ // Custom Ship
if (type != nullptr && engines != nullptr && engCnt > 0) {
// creating a Valid Ship
int len = (unsigned)strlen(type);
m_type = new char[len + 1];
strcpy(m_type, type);
m_engines = new Engine[engCnt];
for (int i = 0; i < engCnt; i++) {
m_engines[i] = engines[i];
}
m_engCnt = engCnt;
}else{
m_type = nullptr; // Setting Ship to Empty State
m_engines = nullptr;
m_engCnt = 0;
}
}
Ship::~Ship(){
delete[] m_engines;
delete[] m_type;
}
Ship::operator bool() const {
// returning true if the ship is valid (not empty)
return m_type != nullptr;
}
Ship& Ship::operator+=(Engine e){ // THIS IS WHERE THE ERROR IS <-----------------
if (!*this) {
cout << "The object is not valid! Engine cannot be added!" << endl;
}else{
Engine* tmp = new Engine[m_engCnt + 1];
for (int i = 0; i <= m_engCnt; i++) {
tmp[i] = m_engines[i];
}
tmp[m_engCnt++] = e;
for (int i = 0; i <= m_engCnt; i++) {
m_engines[i] = tmp[i];
}
}
return *this;
}
double Ship::calculatePower() const { // Multiplying the Engines Size * 5 to get the power(sum of all)
double power = 0;
for (int i = 0; i < m_engCnt; i++) {
power += m_engines[i].get() * 5;
}
return power;
}
void Ship::display()const{ // Displaying the Ship
if (*this) {
streamsize dp = cout.precision(); // save default precision
cout.precision(2); // change default precision
cout << fixed; // enable fixed
cout << m_type << " - " << calculatePower() << endl;
for (int i = 0; i < m_engCnt; i++) {
m_engines[i].display(); // Engines Display function
}
cout.unsetf(ios::fixed); // disable fixed
cout.precision(dp); // restore default precision
}else{
cout << "No available data" << endl;
}
}
bool Ship::operator<(double power) const{ // Comparing the passed in power with the power of the ship
if (calculatePower() < power) {
return true;
}else{
return false;
}
}
bool operator<(double power, const Ship& theShip){ // Global < overloaded operator
if (power < theShip.calculatePower()) {
return true;
}else{
return false;
}
}
}
Related
Learning operator overloading in this project, and below in the ship.cpp file is where I think my error is.
This is the test file, I cannot change this:
#include <iostream>
#include "Ship.h"
#include "Ship.h"
#include "Engine.h"
#include "Engine.h"
using namespace std;
using namespace sdds;
void printHeader(const char* title)
{
char oldFill = cout.fill('-');
cout.width(40);
cout << "" << endl;
cout << "|> " << title << endl;
cout.fill('-');
cout.width(40);
cout << "" << endl;
cout.fill(oldFill);
}
int main()
{
{
printHeader("T1: Testing Constants");
cout << "TYPE_MAX_SIZE: " << sdds::TYPE_MAX_SIZE << endl;
cout << "MIN_STD_POWER: " << sdds::MIN_STD_POWER << endl;
cout << "MAX_STD_POWER: " << sdds::MAX_STD_POWER << endl;
cout << endl;
}
{
printHeader("T2: Testing Default Constructor");
Ship invalid;
invalid.display();
invalid += Engine("D2", 2.1);
cout << endl;
}
Engine engines[] = {
Engine("V8", 4.4),
Engine("V8", 5.0),
Engine("Inline", 4.1),
Engine("D3", 7.0),
Engine("D0", 2.0),
Engine("D1", 3.2),
};
{
printHeader("T3: Testing Custom Constructor");
Ship titanic("cruiser", engines, 6);
titanic.display();
cout << endl;
}
{
printHeader("T4: Testing Conversion to Bool Operator");
Ship invalid;
Ship titanic("liner", engines, 1);
if (invalid)
cout << "1. Test Failed! Object should be invalid.\n";
else
cout << "1. Test succeeded!\n";
if (titanic)
cout << "2. Test succeeded!\n";
else
cout << "3. Test Failed! Object should be valid.\n";
cout << endl;
}
{
printHeader("T5: Testing += and < Operators");
Ship titanic("liner", engines, 3);
char type[]{ "D0" };
while (titanic < sdds::MIN_STD_POWER)
{
type[1]++;
cout << "Ship not up to standard. Required power: "
<< sdds::MIN_STD_POWER << endl;
titanic += Engine(type, 2.1);
}
titanic.display();
if (sdds::MAX_STD_POWER < titanic)
cout << "Too much power." << endl;
else
cout << "Ship doesn't exceed power regulation of: "
<< sdds::MAX_STD_POWER << endl;
}
return 0;
}
This is my Ship.cpp file. My error is in the += operator function, where I have to add an engine but don't understand how I should approach it.
#include <iostream>
#include <cstring>
#include "Ship.h"
using namespace std;
namespace sdds {
Ship::Ship(){
m_type[0] = '\0';
m_engCnt = 0;
}
Ship::Ship(const char* type, const Engine engines[], int cnt){
if (type != nullptr && engines != nullptr && cnt > 0) {
// create a valid ship
strncpy(m_type, type, TYPE_MAX_SIZE);
for (int i = 0; i < cnt; i++) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}else{
m_type[0] = '\0';
m_engCnt = 0;
}
}
Ship::operator bool() const {
// return true if the ship is valid (not empty)
if(m_type[0] == '\0' || m_engCnt == 0){
return false;
}else{
return true;
}
}
Ship& Ship::operator+=(Engine e){
if (!*this) {
cout << "The Object is not valid! Engine cannot be added!" << endl;
return *this;
}else if (m_engCnt == NUM_OF_ENGINES){
return *this;
}else{
// ERROR I BELIEVE IS HERE --> I dont understand the syntax to add engine here
m_engCnt++;
return *this;
}
}
double Ship::calculatePower() const {
double power = 0;
for (int i = 0; i < m_engCnt; i++) {
power += m_engines[i].get() * 5;
}
return power;
}
void Ship::display()const{
if (*this) {
cout << m_type << " - " << calculatePower() << endl;
Engine e;
for (int i = 0; i < m_engCnt; i++) {
m_engines[i].display();
}
}else{
cout << "No available data" << endl;
}
}
bool Ship::operator<(double power) const{
if (calculatePower() < power) {
return true;
}else{
return false;
}
}
bool operator<(double power, const Ship& theShip){
if (power < theShip.calculatePower()) {
return true;
}else{
return false;
}
}
}
This is my engine.cpp file:
#include <iostream>
#include <iomanip>
#include <stdio.h>
#include <string.h>
#include "Engine.h"
using namespace sdds;
using namespace std;
namespace sdds {
Engine::Engine(){
m_type[0] = '\0';
m_size = 0.0;
}
Engine::Engine(const char* type, double size){
strncpy(m_type, type, TYPE_MAX_SIZE);
m_size = size;
}
double Engine::get() const{
return m_size;
}
void Engine::display() const{
cout << m_size << " liters - " << m_type << endl;
}
}
This should be the output, but my function is stuck in the while loop:
|> T5: Testing += and < Operators
----------------------------------------
Ship not up to standard. Required power: 90.111
Ship not up to standard. Required power: 90.111
Ship not up to standard. Required power: 90.111
liner - 99
4.4 liters - V8
5 liters - V8
4.1 liters - Inline
2.1 liters - D1
2.1 liters - D2
2.1 liters - D3
Ship doesn't exceed power regulation of: 99.999
Your operator+= is not doing anything with the Engine that is passed to it. Your Ship class has an m_engines array, which your Ship constructor adds Engines to (without regard to NUM_OF_ENGINES, though), but your operator+= is not.
Your constructor and operator+= should look more like this instead:
Ship::Ship(const char* type, const Engine engines[], int cnt){
if (type != nullptr && engines != nullptr && cnt > 0) {
// create a valid ship
strncpy(m_type, type, TYPE_MAX_SIZE);
if (cnt > NUM_OF_ENGINES) cnt = NUM_OF_ENGINES; // <-- ADD THIS LINE!
for (int i = 0; i < cnt; ++i) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}else{
m_type[0] = '\0';
m_engCnt = 0;
}
}
Ship& Ship::operator+=(Engine e){
if (!*this) {
cout << "The Object is not valid! Engine cannot be added!" << endl;
return *this;
}else if (m_engCnt == NUM_OF_ENGINES){
return *this;
}else{
m_engines[m_engCnt] = e; // <-- ADD THIS LINE!!!
m_engCnt++;
return *this;
}
}
I would suggest re-writing the constructor and operator+= to look more like this instead:
Ship::Ship(const char* type, const Engine engines[], int cnt){
strncpy(m_type, type != nullptr ? type : "", TYPE_MAX_SIZE);
if (engines != nullptr && cnt > 0) {
if (cnt > NUM_OF_ENGINES) cnt = NUM_OF_ENGINES;
for (int i = 0; i < cnt; ++i) {
m_engines[i] = engines[i];
}
m_engCnt = cnt;
}
else
m_engCnt = 0;
}
Ship& Ship::operator+=(const Engine &e){
if (m_type[0] != '\0' && m_engCnt < NUM_OF_ENGINES) {
m_engines[m_engCnt] = e;
++m_engCnt;
}
return *this;
}
It is a homework problem. It compiles fine, but linker gives undefined reference to my function getSalesData - line 20 just after my first for loop. Here is the code. I cannot find where I have done anything incorrectly; I have my prototype defined and it matches my function header, and I am simply calling the function.
// chips and salsa
#include <iostream>
#include <iomanip>
#include <string>
int getJarsSold(std::string type);
void getSalesData(int jarsSold[],int size,int &totalJars,int &highSeller,int &lowSeller);
int main() {
const int SIZE = 5;
const std::string salsaTypes[] {"Mild","Medium","Sweet","Hot","Zesty"};
int jarsSold[SIZE] = {};
int highIndex,lowIndex,totalJarsSold;
for (int i = 0; i < SIZE; i++) {
jarsSold[i] = getJarsSold(salsaTypes[i]);
}
getSalesData(jarsSold,SIZE,totalJarsSold,highIndex,lowIndex);
std::cout << " Type Jars Sold\n";
std::cout << "---------------------\n";
for (int i = 0; i < SIZE; i++) {
std::cout << std::setw(8) << salsaTypes[i] << std::setw(15) << jarsSold[i] << std::endl;
}
std::cout << "*********************\n";
std::cout << "Total Sales = " << totalJarsSold << std::endl;
std::cout << "Highest Seller = " << salsaTypes[highIndex] << std::endl;
std::cout << "Lowest Seller = " << salsaTypes[lowIndex] << std::endl;
}
int getJarsSold(std::string type) {
bool validData = false;
int numJars;
while (!validData) {
std::cout << "Enter jars sold this month for " << type << " salsa type: ";
std::cin >> numJars;
if (numJars < 0) {
std::cout << "Number of jars sold must be 0 or positive number.\n";
}
else {
validData = true;
}
}
validData = false;
return numJars;
}
void getSalesData(int jarsSold[],int size,int totalJars,int highIndex,int lowIndex) {
bool firstRun = true;
int highVal,lowVal;
totalJars = 0;
for (int i = 0; i < size; i++) {
if (firstRun) {
highIndex = i;
highVal = jarsSold[highIndex];
lowIndex = i;
lowVal = jarsSold[lowIndex];
totalJars += jarsSold[i];
firstRun = false;
}
else {
totalJars += jarsSold[i];
if (jarsSold[i] > highVal) {
highVal = jarsSold[i];
highIndex = i;
}
if (jarsSold[i] < lowVal) {
lowVal = jarsSold[i];
lowIndex = i;
}
}
}
}
Any help is appreciated. I am just using -c for compiling and -o for linking, nothing fancy as I know no better.
I have a problem in my OOP homework. I have to code a 1 v 1 battle.
This is a Survival Game where in the player fights continuously with enemies until the player dies. The Player gets stronger as he advances through. The enemy also grows stronger every round.
I have created two Classes, The Unit and the Spawner.
We cannot use Inheritance nor Polymorphism.
We Have to use only the simple definition of the class.
My problem is that i cannot think of a SIMPLE way to make the class Spawner spawn a stronger enemy every round.
I have thought of overloading the Unit's Contructor but i have trouble manipulating that.
Would anyone please help?
Here's my Unit Header file (Unit.h):
#pragma once
#include <string>
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// Class Types
const string CLASS_WARRIOR = "Warrior" ;
const string CLASS_ASSASSIN = "Assassin";
const string CLASS_MAGE = "Mage" ;
// Class Choices
const int CHOICE_WARRIOR = 1;
const int CHOICE_ASSASSIN = 2;
const int CHOICE_MAGE = 3;
// Multipliers
const double MULTIPLIER_DAMAGE = 0.50f;
const double MULTIPLER_HEAL = 0.30f;
// Advantage
const bool ADVANTAGE = true;
// Win Bonus
const int BONUS_THREE = 3;
const int BONUS_FIVE = 5;
// Minimum and maximum values
const int HIT_RATE_MAX = 80;
const int HIT_RATE_MIN = 20;
const int DAMAGE_MIN = 1;
// Hit or miss
const bool ATTACK_HIT = true;
const bool ATTACK_MISS = false;
class Unit
{
public:
// Constructors
Unit(string name, int classChoice);
// Getters and setters
string getName();
string getClass();
int getHp();
int getMaxHp();
int getPower();
int getVitality();
int getAgility();
int getDexterity();
int getDamage();
int getHeal();
int getBonusDamage();
bool getFirstToAttack();
bool getHit();
void setClassStats(const int classChoice);
// Primary Actions
void attack(Unit* target);
// Secondary Actions
void check(const Unit* target); // Inspects the enemy
void lvlUp(); // Grants this Unit Bonus Stats on Victory
private:
// Info
string mName;
string mClass;
// Basic Stats
int mHp;
int mMaxHp;
int mPower;
int mVitality;
int mAgility;
int mDexterity;
// Derived Stats
int mDamage;
int mHitrate;
int mHeal;
int mBonusDamage;
// Miscellaneous
bool mAdvantage; // If the player has the advantage
string mTargetClass;// This Unit keeps in mind the class of this Unit's Opponent for reference
int mChanceOfHit; // The random chance if the attack will Hit/Miss
bool mFirstToAttack;//if this unit will attack first
bool mHit; // if the attack is a hit or miss
};
Here's my Unit.cpp file (Unit.cpp):
#include "Unit.h"
Unit::Unit(string name, int classChoice)
{
mName = name;
setClassStats(classChoice);
}
string Unit::getName()
{
return mName;
}
string Unit::getClass()
{
return mClass;
}
int Unit::getHp()
{
return mHp;
}
int Unit::getMaxHp()
{
return mMaxHp;
}
int Unit::getPower()
{
return mPower;
}
int Unit::getVitality()
{
return mVitality;
}
int Unit::getAgility()
{
return mAgility;
}
int Unit::getDexterity()
{
return mDexterity;
}
int Unit::getDamage()
{
return mDamage;
}
int Unit::getHeal()
{
return mHeal;
}
int Unit::getBonusDamage()
{
return mBonusDamage;
}
bool Unit::getFirstToAttack()
{
return mFirstToAttack;
}
bool Unit::getHit()
{
return mHit;
}
void Unit::setClassStats(const int classChoice)
{
if (classChoice == CHOICE_WARRIOR) {
mClass = CLASS_WARRIOR;
mMaxHp = 20;
mHp = mMaxHp;
mPower = 15;
mVitality = 10;
mAgility = 7;
mDexterity = 7;
return;
}
else if (classChoice == CHOICE_ASSASSIN) {
mClass = CLASS_ASSASSIN;
mMaxHp = 15;
mHp = mMaxHp;
mPower = 17;
mVitality = 8;
mAgility = 12;
mDexterity = 10;
return;
}
else if (classChoice == CHOICE_MAGE) {
mClass = CLASS_MAGE;
mMaxHp = 30;
mHp = mMaxHp;
mPower = 12;
mVitality = 12;
mAgility = 9;
mDexterity = 8;
return;
}
throw exception("Error! Class not part of this game. ");
}
void Unit::attack(Unit * target)
{
// Determine Whether the attack will Hit/Miss Based on the hit rate
mChanceOfHit = rrand() % 100 + 1;
if (mChanceOfHit > mHitrate) {
mHit = ATTACK_MISS;
return;
}
// Deducts the targets Hp by the Damage given by this Unit (if the attack didn't miss)
target->mHp -= mDamage;
mHit = ATTACK_HIT;
// if target HP is negative, set it to zero
if (target->mHp < 0) target->mHp = 0;
}
void Unit::check(const Unit * target)
{
// The Unit Keeps in Mind his target's Class
if (target->mClass == CLASS_WARRIOR) mTargetClass = CLASS_WARRIOR;
else if (target->mClass == CLASS_ASSASSIN) mTargetClass = CLASS_ASSASSIN;
else if (target->mClass == CLASS_MAGE) mTargetClass = CLASS_MAGE;
// Checks if the Unit is Advantageous Against his Target
if (mClass == CLASS_WARRIOR) {
if (target->mClass == CLASS_ASSASSIN) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
else if (mClass == CLASS_ASSASSIN) {
if (target->mClass == CLASS_MAGE) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
else if (mClass == CLASS_MAGE) {
if (target->mClass == CLASS_WARRIOR) mAdvantage = ADVANTAGE;
else mAdvantage = false;
}
// Determine if this Unit Will Attack first
if (mAgility >= target->mAgility) mFirstToAttack = true;
else mFirstToAttack = false;
// Determines Damage, Bonus Damage ( If Applicable ), and Hit Rate Based on targets stats
mDamage = mPower - target->mVitality;
if (mDamage < DAMAGE_MIN) mDamage = DAMAGE_MIN;
mBonusDamage = mDamage * MULTIPLIER_DAMAGE;
// Evaluates Damage Based on advantage
if (mAdvantage) mDamage += mBonusDamage;
mHitrate = ((float)mDexterity / (float)target->mAgility) * 100;
// Clamps the Hit Rate within the Hit Rate Range
if (mHitrate > HIT_RATE_MAX) mHitrate = HIT_RATE_MAX;
else if (mHitrate < HIT_RATE_MIN) mHitrate = HIT_RATE_MIN;
}
void Unit::lvlUp()
{
// Determine Win Bonus Based on the target that he kept in mind
if (mTargetClass == CLASS_WARRIOR) {
mMaxHp += BONUS_THREE;
mVitality += BONUS_THREE;
}
else if (mTargetClass == CLASS_ASSASSIN) {
mAgility += BONUS_THREE;
mDexterity += BONUS_THREE;
}
else if (mTargetClass == CLASS_MAGE) {
mPower += BONUS_FIVE;
}
// Heals the player 30% of his Maximum HP
mHeal = mMaxHp * MULTIPLER_HEAL;
mHp += mHeal;
}
Here's my Spawner Header file (Spawner.h):
#pragma once
#include "Unit.h"
class Spawner
{
public:
Spawner();
~Spawner();
void spawn(Unit*& unit);
private:
Unit* mUnit;
int mRandomClass;
};
Here's my Spawner.cpp file (Spawner.cpp):
#include "Spawner.h"
Spawner::Spawner()
{
}
Spawner::~Spawner()
{
delete mUnit;
mUnit = NULL;
}
void Spawner::spawn(Unit *& unit)
{
mRandomClass = rand() % 3 + 1;
unit = new Unit("Enemy", mRandomClass);
mUnit = unit;
}
And finally here is my main.cpp:
#include "Unit.h"
#include "Spawner.h"
// Create player
Unit* createPlayer();
// Display Stats
void displayStats(Unit* unit);
// Play 1 round
void playRound(Unit*player, Unit* enemy);
// Simulate 1 attack (implement Higher agility gets to atttack first)
void combat(Unit* player, Unit* enemy);
void main()
{
srand(time(NULL));
Unit* player = createPlayer();
Unit* enemy = NULL;
Spawner *spawner = new Spawner();
int round = 1;
while (true) {
cout << "Round " << round << endl;
spawner->spawn(enemy);
player->check(enemy);
enemy->check(player);
playRound(player, enemy);
// if player is dead, end the game
if (player->getHp() == 0) break;
// else, add stats
player->lvlUp();
delete enemy;
enemy = NULL;
cout << "You defeted an enemy" << endl;
system("pause>nul");
system("cls");
round++;
}
cout << "You were defeted! " << endl;
cout << "You survived until Round " << round << endl;
displayStats(player);
delete player;
player = NULL;
delete spawner;
spawner = NULL;
system("pause>nul");
system("cls");
}
Unit* createPlayer()
{
Unit* unit = NULL;
string name;
int classChoice;
cout << "Enter your Name: ";
getline(cin, name);
system("cls");
cout << "Pick a class: " << endl
<< "\t [ 1 ] Warrior" << endl
<< "\t [ 2 ] Assassin" << endl
<< "\t [ 3 ] Mage" << endl
<< endl;
cin >> classChoice;
while (classChoice > 3 || classChoice <= 0) {
cout << "INVALID INPUT! Please try again" << endl;
cout << "Pick a class: " << endl
<< "\t [ 1 ] Warrior" << endl
<< "\t [ 2 ] Assassin" << endl
<< "\t [ 3 ] Mage" << endl
<< endl;
cin >> classChoice;
}
unit = new Unit(name, classChoice);
return unit;
}
void displayStats(Unit* unit)
{
cout << "=========================================================================================" << endl
<< "Name: " << unit->getName() << " \t \t \t HP: " << unit->getHp() << " / " << unit->getMaxHp() << endl
<< "Class: " << unit->getClass() << endl
<< "==========================================================================================" << endl
<< "POW: " << unit->getPower() << endl
<< "VIT: " << unit->getVitality() << endl
<< "AGI: " << unit->getAgility() << endl
<< "DEX: " << unit->getDexterity() << endl
<< endl;
}
void playRound(Unit*player, Unit* enemy)
{
while (player->getHp() > 0 && enemy->getHp() > 0) {
displayStats(player);
displayStats(enemy);
system("pause>nul");
combat(player, enemy);
system("cls");
}
}
void combat(Unit* player, Unit* enemy)
{
if (player->getFirstToAttack()) {
player->attack(enemy);
if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
system("pause>nul");
if (enemy->getHp() == 0) return;
enemy->attack(player);
if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
system("pause>nul");
return;
}
else if (enemy->getFirstToAttack()) {
enemy->attack(player);
if (enemy->getHit() == ATTACK_MISS) cout << enemy->getName() << "'s Attack Missed! " << endl;
else if (enemy->getHit() == ATTACK_HIT) cout << enemy->getName() << " dealt " << enemy->getDamage() << " Damage" << endl;
system("pause>nul");
if (player->getHp() == 0) return;
player->attack(enemy);
if (player->getHit() == ATTACK_MISS) cout << player->getName() << "'s Attack Missed! " << endl;
else if (player->getHit() == ATTACK_HIT) cout << player->getName() << " dealt " << player->getDamage() << " Damage" << endl;
system("pause>nul");
return;
}
}
Add a "level" to the Unit class, and use the level to increase the stats of the unit (for example level 2 could mean the stats are multiplied by 1.5 or some such). Pass the level as an argument to the constructor similar to the units class.
You need to make your spawner aware of how many enemies it has spawned:
// this belongs into your class definition, it should start at zero
int mCurrentSpawn;
So set it to zero in your constructor:
Spawner::Spawner()
{
mCurrentSpawn = 0;
}
Then reference it when you spawn an enemy:
void Spawner::spawn(Unit *& unit)
{
mRandomClass = rand() % 3 + 1;
unit = new Unit("Enemy", mRandomClass);
mUnit = unit;
mCurrentSpawn++;
int levelUps = mCurrentSpawn - 1;
while(levelUps > 0)
{
mUnit->lvlUp();
levelUps--;
}
}
I'm at a bit of a roadblock and I just can't seem to figure out where I went wrong. Essentially, I just want to pass the values from the array in the test code to a vector via constructor and then print the contents of the vector. For whatever reason, I can't even hit the for loop that starts to add the array values to the vector.
header code:
#pragma once
#ifndef BoxOfProduce_H
#define BoxOfProduce_H
#include <vector>
#include <iostream>
#include <cstdlib> //for exit
using namespace std;
class BoxOfProduce
{
public:
BoxOfProduce();
BoxOfProduce(string customerId, int size, bool doRandom, bool okDuplicates, std::string productList[], int listSize);
void addBundle(string productList);
void displayBox();
private:
string customerID;
vector<string> test;
vector<string> bundles;
bool allowDuplicates;
bool buildRandom;
int size;
};
#endif
// End of dayOfYear.h
BocOfProduce.cpp
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <algorithm>
#include <cstdlib> //for exit
using namespace std;
#include "BoxOfProduce.h"
vector<string> tempbundles;
bool isInVect = false;
BoxOfProduce::BoxOfProduce()
{
customerID = "No Name";
allowDuplicates = true;
buildRandom = false;
}
BoxOfProduce::BoxOfProduce(string customerId, int size, bool doRandom, bool okDuplicates, string productList[], int listSize)
{
customerID = customerId;
buildRandom = doRandom;
allowDuplicates = okDuplicates;
size = size;
for (int k = 0; k > listSize; k++)
{
tempbundles.push_back(productList[k]);
cout << "added to temp" << endl;
}
if (allowDuplicates == false)
{
for (int k = 0; k > listSize; k++)
{
tempbundles.push_back(productList[k]);
cout << "added to temp" << endl;
}
for (int i = 0; i < listSize; i++)
{
for (int j = 0 + 1; j < listSize; j++)
{
if (tempbundles[i] == bundles[j])
{
isInVect = true;
}
if (isInVect == false)
{
bundles.push_back(tempbundles[i]);
cout << "added to isinvect bundle" << endl;
}
}
}
}
else if (allowDuplicates == true)
{
for (int k = 1; k > listSize; k++)
{
bundles.push_back(productList[k]);
cout << "added to normal bundle" << endl;
}
}
}
void BoxOfProduce::addBundle(string productList)
{
for (int k = 1; k > 100; k++)
{
bundles.push_back(productList);
}
}
void BoxOfProduce::displayBox()
{
cout << "custome ID is: " << customerID << "\n" << endl;
std::cout << std::boolalpha;
cout << "-buildRandom set to " << buildRandom << endl;
cout << "-allowDuplicates set to " << allowDuplicates << endl;
cout << "Contents of box: " << customerID << " with size: " << size << endl;
test.push_back("test");
for (int i = 0; i < bundles.size(); i++)
{
cout << bundles[i] << "\n";
}
cout << "\n" << endl;
}
Test code:
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <algorithm>
#include <cstdlib> //for exit
#include "BoxOfProduce.h"
using namespace std;
int main()
{
srand(1234); // Seed random generator for random additions of products
const int LISTSIZE = 12;
string produceList[] = { "Broccoli", "Tomato", "Kiwi", "Kale", "Tomatillo",
"Mango", "Spinach", "Cucumber", "Radish", "Chard", "Spinach", "Mango" };
cout << "Original list of produce:" << endl;
for (int i = 0; i < LISTSIZE; i++)
{
cout << "item[" << i << "] = " << produceList[i] << endl;
}
// Test BoxOfProduce class
cout << endl << "Start with empty box0" << endl;
BoxOfProduce box0; // Default constructor creates empty box
cout << "Display box0:" << endl;
box0.displayBox(); // Display the empty box
cout << endl; // Skip a line
cout << "Add all products from the produceList[] to box0 allowing duplicates:"
<< endl;
for (int i = 0; i < LISTSIZE; i++)
box0.addBundle(produceList[i]); // Duplicates allowed in box
cout << "Display box0 again after loading with products:" << endl;
box0.displayBox();
cout << endl;
BoxOfProduce box1("Box-1", 4, false, true, produceList, LISTSIZE);
box1.displayBox();
BoxOfProduce box2("Box-2", 4, true, false, produceList, LISTSIZE);
box2.displayBox();
BoxOfProduce box3("Box-3", 8, true, true, produceList, LISTSIZE);
box3.displayBox();
BoxOfProduce box4("Box-4", 12, true, true, produceList, LISTSIZE);
box4.displayBox();
BoxOfProduce box5("Box-5", 12, true, false, produceList, LISTSIZE);
box5.displayBox(); // This box produces an error message
}
Thank you for any and all help!
your problem is that in case of duplicate you use the list size for bundle and tempbundle which is not the case this should fix check the code for BocOfProduce.cpp
vector<string> tempbundles;
bool isInVect = false;
BoxOfProduce::BoxOfProduce()
{
customerID = "No Name";
allowDuplicates = true;
buildRandom = false;
}
BoxOfProduce::BoxOfProduce(string customerId, int size, bool doRandom, bool okDuplicates, string productList[], int listSize)
{
customerID = customerId;
buildRandom = doRandom;
allowDuplicates = okDuplicates;
size = size;
tempbundles = vector<int>() ; // set temp bundles to empty vector
for (int k = 0; k < listSize; k++) //k was >listSize it should be <
{
tempbundles.push_back(productList[k]);
cout << "added to temp" << endl;
}
if (allowDuplicates == false)
{
for (int k = 0; k < listSize; k++)
{
tempbundles.push_back(productList[k]);
cout << "added to temp" << endl;
}
for (int i = 0; i < listSize; i++)
{
isInVect = false;
for (int j = 0 + 1; j < bundles.size(); j++)
{
if (tempbundles[i] == bundles[j])
{
isInVect = true;
}
}
if (isInVect == false)
{
bundles.push_back(tempbundles[i]);
cout << "added to isinvect bundle" << endl;
}
}
}
else if (allowDuplicates == true)
{
for (int k = 1; k < listSize; k++)
{
bundles.push_back(productList[k]);
cout << "added to normal bundle" << endl;
}
}
}
void BoxOfProduce::addBundle(string productList)
{
for (int k = 1; k > 100; k++)
{
bundles.push_back(productList);
}
}
void BoxOfProduce::displayBox()
{
cout << "custome ID is: " << customerID << "\n" << endl;
std::cout << std::boolalpha;
cout << "-buildRandom set to " << buildRandom << endl;
cout << "-allowDuplicates set to " << allowDuplicates << endl;
cout << "Contents of box: " << customerID << " with size: " << bundles.size() << endl;
test.push_back("test");
for (int i = 0; i < bundles.size(); i++)
{
cout << bundles[i] << "\n";
}
cout << "\n" << endl;
}
When I Create An Instance of the following class using Game newGame; it throws a c1001 error stating that there was a compiler error.
game.h:
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <conio.h>
#include "cls.h"
#include "explode.h"
using namespace std;
class Game
{
private:
explode EXP;
CLS cls;
string _SaveGame, _DIRECTORY;
int _GAMEDATA[500];
string _DATATITLES[500] = { "Ticks", "Dwarves", "Grain Mills", "Lumber Mills", "Mines", "Grain Workers", "Lumber Workers", "Mine Workers", "Grain Mill Experts", "Lumber Mill Experts", "Mine Experts" };
public:
void CS()
{
cls.clear();
}
void SetSaveName(string SaveName)
{
_SaveGame = SaveName;
}
void init(string directory)
{
_DIRECTORY = directory;
cout << "Init Game" << endl;
CS();
ofstream gameSave;
gameSave.open(_DIRECTORY + _SaveGame + ".save", ofstream::out | ofstream::app);
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
if (!gameSave.good())
{
// Write New Data To File
cout << "Game Saved As: " << _DIRECTORY + _SaveGame + ".save";
gameSave.flush();
gameSave << "0\n"; // TICKS
gameSave.flush();
gameSave << "7\n"; // Dwarves
gameSave.flush();
gameSave << "1\n"; // Grain Mills
gameSave.flush();
gameSave << "1\n"; // Lumber Mill
gameSave.flush();
gameSave << "1\n"; // Mine
gameSave.flush();
gameSave << "2\n"; // Grain Mill Workers
gameSave.flush();
gameSave << "2\n"; // Lumber Mill Workers
gameSave.flush();
gameSave << "3\n"; // Mine Workers
gameSave.flush();
gameSave << "1\n"; // Grain Mill Experts
gameSave.flush();
gameSave << "1\n"; // Lumber Mill Experts
gameSave.flush();
gameSave << "1\n"; // Mine Experts
gameSave.flush();
gameSave << "ENDFILE";
gameSave.flush();
}
else
{
// Read Data From File
loadGame(_SaveGame);
}
bool GameLoop = true;
while (GameLoop)
{
// Begin Game Loop Instance
printData();
string in;
bool parseDataLoop = 1;
while (parseDataLoop)
{
in = getData();
int parseDataInt = parseData(in);
if (parseDataInt == 1) {
GameLoop = 0;
saveGame();
exit(0);
}
else if (parseDataInt == 2) {
_getch();
}
else
{
parseDataLoop = 0;
}
}
saveGame();
}
}
void GameTick()
{
_GAMEDATA[0] += 1; // Number Of Game Ticks
}
void printData()
{
CS();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
cout << _DATATITLES[i] << " : " << _GAMEDATA[i];
}
}
}
string getData()
{
string DATA;
cin >> DATA;
return DATA;
}
int parseData(string input)
{
int quit = 0;
if (input == "help")
{
// Print List Of Commands And Descriptions:
cout << "List Of All Available Commands:" << endl;
cout << "help : Shows A List Of All Available Commands" << endl;
cout << "tick : Makes Game Progress One Tick" << endl;
cout << "tick.NUM : Makes Game Progress NUM Tick(s)" << endl;
cout << "quit : Saves Game And Terminates Program" << endl;
quit = 2;
}
else if (input == "quit")
{
quit = 1;
}
else if (input == "tick")
{
// Skip One Tick
GameTick();
}
else if (find(input, '.')) {
vector<string> output;
output = EXP.explodeStuff(input, '.');
if (output[0] == "tick") {
if (isInterger(output[1]))
{
for (int i = 0; i < stoi(output[1]); i++) {
GameTick();
}
}
else
{
cout << "ERROR: tick." << output[1] << ", is not vaid please use numbers not letters." << endl;
quit = 2;
}
}
}
else
{
cout << "ERROR: Invalid Command Please type \"help\" To See A List Of Available Commands." << endl;
quit = 2;
}
return quit;
}
void loadGame(string saveGame)
{
ifstream inData;
string temp;
inData.open(_DIRECTORY + saveGame + ".cod");
if (inData.good())
{
for (int i = 0; i < 500; i++) {
getline(inData, temp);
if (temp == "ENDFILE") { break; }
if (temp != "")
{
_GAMEDATA[i] = stoi(temp);
}
}
inData.close();
}
}
void saveGame()
{
// Update Data in file
ofstream gameSave(_DIRECTORY + _SaveGame + ".save");
gameSave.clear();
for (int i = 0; i < 500; i++) {
if (_GAMEDATA[i] != NULL) {
gameSave << _GAMEDATA[i];
}
}
gameSave << "\nENDFILE";
}
bool find(string input, char find)
{
bool RETURN = 0;
for each (char CHAR in input)
{
if (CHAR == find) {
RETURN = 1;
break;
}
}
return RETURN;
}
inline bool isInterger(const std::string & s)
{
if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) return false;
char* p;
strtol(s.c_str(), &p, 10);
return (*p == 0);
}
};
main.cpp:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include "game.h"
#include "programSettings.h"
#include "cls.h"
#include "explode.h" // Adds explode(string input, char delimeter), and explodePrint(vector<string> input)
using namespace std;
string _DIRECTORY = (string)getenv("APPDATA") + "/cityOfDwarves/";
vector<int> _SETTINGS; // Array To Hold All Settings In The SETTINGS.cod File
int SettingsConfigured;
explode EXP;
CLS cls;
int main()
{
SetConsoleTitle("CityOfDwarves");
programSettings pSet(_DIRECTORY);
_SETTINGS = pSet.readSettings();
if (_SETTINGS.size() > 0) {
SettingsConfigured = _SETTINGS[0];
}
else
{
SettingsConfigured = 0;
}
if (!SettingsConfigured) {
pSet.setSettings();
}
cout << "Settings Configured" << endl;
cls.clear();
cout << "Please Enter a Save Name:" << endl;
string SaveName;
cin >> SaveName;
cout << "Using: " << SaveName << ", As The Current Save File." << endl;
// Begin Game Loop
Game mainGame;
mainGame.SetSaveName(SaveName);
mainGame.init(_DIRECTORY);
char i;
cin >> i;
return 0;
}
Complete Error Code:
Severity Code Description Project File Line
Error C1001 An internal error has occurred in the compiler. CityOfDwarves C:\Users\Daniel\Documents\Visual Studio 2015\Projects\CityOfDwarves\CityOfDwarves\main.cpp 1