adding cs142 code

This commit is contained in:
dm
2016-04-06 20:45:34 -07:00
parent 552d456d53
commit 8e52ce1982
174 changed files with 14064 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include "FighterInterface.h"
using namespace std;
/*
WARNING: It is expressly forbidden to modify any part of this document, including its name
*/
class ArenaInterface
{
public:
ArenaInterface(){}
virtual ~ArenaInterface(){}
/*
addFighter(string)
Adds a new fighter to the collection of fighters in the arena. Do not allow
duplicate names. Reject any string that does not adhere to the format
outlined in the lab specs.
Return true if a new fighter was added; false otherwise.
*/
virtual bool addFighter(string info) = 0;
/*
removeFighter(string)
Removes the fighter whose name is equal to the given name. Does nothing if
no fighter is found with the given name.
Return true if a fighter is removed; false otherwise.
*/
virtual bool removeFighter(string name) = 0;
/*
getFighter(string)
Returns the memory address of a fighter whose name is equal to the given
name. Returns NULL if no fighter is found with the given name.
Return a memory address if a fighter is found; NULL otherwise.
*/
virtual FighterInterface* getFighter(string name) = 0;
/*
getSize()
Returns the number of fighters in the arena.
Return a non-negative integer.
*/
virtual int getSize() = 0;
};
+176
View File
@@ -0,0 +1,176 @@
#include <iostream>
#include <string>
#include <sstream>
#include <cstdio>
#include "FighterInterface.h"
using namespace std;
/*
WARNING: It is expressly forbidden to modify any part of this document, including its name
*/
//=======================================================================================
FighterInterface* fight(FighterInterface*, FighterInterface*, bool);
void takeTurn(FighterInterface*, FighterInterface*, bool);
void speak(string);
//=======================================================================================
/*
fight(FighterInterface, FighterInterface, bool)
Runs through the fighting algorithm for the two given fighters.
Each fighter takes a turn using its special ability, attacking, and regenerating. If
the other fighter's current hit points falls to or drops below 0, then the other
fighter has lost. This process repeats until one fighter has fallen or 100 rounds
have occurred with neither fighter falling.
If the given bool is true, this function will print a great deal of information
during the battle. This can be useful for testing.
Returns the winner of the fight; null if the fight ends in a draw.
*/
FighterInterface* fight(FighterInterface* c1, FighterInterface* c2, bool verbose)
{
if(verbose)
{
stringstream stream;
stream << "----------";
stream << c1->getName();
stream << " vs ";
stream << c2->getName();
stream << "----------";
speak(stream.str());
}
c1->reset();
c2->reset();
for(int i=0; i<100; i++)
{
//C1's turn
takeTurn(c1, c2, verbose);
if(c2->getCurrentHP() <= 0)
{
if(verbose)
{
stringstream stream;
stream << c1->getName();
stream << " wins! (";
stream << c1->getCurrentHP();
stream << "/";
stream << c1->getMaximumHP();
stream << " HP left)";
speak(stream.str());
}
return c1;
}
//C2's turn
takeTurn(c2, c1, verbose);
if(c1->getCurrentHP() <= 0)
{
if(verbose)
{
stringstream stream;
stream << c2->getName();
stream << " wins! (";
stream << c2->getCurrentHP();
stream << "/";
stream << c2->getMaximumHP();
stream << " HP left)";
speak(stream.str());
}
return c2;
}
}
if(verbose)
{
speak("After 100 rounds, neither fighter has fallen. It's a draw!");
}
return NULL;
}
//=======================================================================================
/*
takeTurn(FighterInterface*, FighterInterface*, bool)
Runs through a single turn for [attacker] attacking [defender]. Each turn consists of
[attacker] trying to use its special ability, attacking [defender], and regenerating.
*/
void takeTurn(FighterInterface* attacker, FighterInterface* defender, bool verbose)
{
//Header
if(verbose)
{
stringstream stream;
stream << "It's ";
stream << attacker->getName();
stream << "'s turn! (";
stream << attacker->getCurrentHP();
stream << "/";
stream << attacker->getMaximumHP();
stream << " HP).";
speak(stream.str());
}
//Use Ability
if(!attacker->isSimplified())
{
bool ability = attacker->useAbility();
if(ability && verbose)
{
stringstream stream;
stream << "\t";
stream << attacker->getName();
stream << " uses a special ability!";
speak(stream.str());
}
}
//Attack
int damage = attacker->getDamage();
int before_attack = defender->getCurrentHP();
defender->takeDamage(damage);
int after_attack = defender->getCurrentHP();
if(verbose)
{
stringstream stream;
stream << "\t";
stream << attacker->getName();
stream << " attacks with ";
stream << damage;
stream << " damage, and ";
stream << defender->getName();
stream << " takes ";
stream << (before_attack-after_attack);
stream << " damage.";
speak(stream.str());
}
//Regenerate
if(!attacker->isSimplified())
{
int before_regen = attacker->getCurrentHP();
attacker->regenerate();
int after_regen = attacker->getCurrentHP();
if(verbose)
{
stringstream stream;
stream << "\t";
stream << attacker->getName();
stream << " regenerates ";
stream << (after_regen-before_regen);
stream << " HP.";
speak(stream.str());
}
}
}
//=======================================================================================
/*
speak(string)
Displays a given message.
*/
void speak(string message)
{
printf("%s\n", message.c_str());
}
//=======================================================================================
+7
View File
@@ -0,0 +1,7 @@
#include "Factory.h"
#include "arena.h"
ArenaInterface* Factory::createArena()
{
return new arena();
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "ArenaInterface.h"
/*
WARNING: It is expressly forbidden to modify any part of this document, including its name
*/
//=======================================================================================
/*
createArena()
Creates and returns an object whose class extends ArenaInterface.
This should be an object of a class you have created.
Example: If you made a class called "Arena", you might say, "return new Arena();".
*/
class Factory
{
public:
static ArenaInterface* createArena();
};
//=======================================================================================
+200
View File
@@ -0,0 +1,200 @@
#pragma once
#include <iostream>
#include <string>
using namespace std;
/*
WARNING: It is expressly forbidden to modify any part of this document, including its name
*/
/*
This class specifies the methods for a fighter.
All fighters have the following attributes:
Name - The fighter's name.
Hit Points - The amount of health the fighter has, with a specified maximum. Reaching 0 is equivalent to death.
Strength - Physical power, used to determine hit point regeneration.
Speed - Dexterity and physical movement, used to reduce damage when being attacked.
Magic - Magical prowess, used for some special abilities.
The three fighter types have unique abilities:
Robot - Relies on strength to deal damage. Also can use stored electricity to temporarily increase damage (max electricity equal to 2*magic).
Archer - Relies on speed to deal damage. Also can increase its speed for the remainder of the battle (no max bonus speed).
Cleric - Relies on magic to deal damage. Also can heal itself using mana, restoring hit points (max mana equal to 5*magic).
More details about how stats are used and how abilities work can be found in the comments below.
*/
/*
ROBOT_ABILITY_COST
The amount of energy a Robot needs to perform its special ability.
*/
const int ROBOT_ABILITY_COST = 5;
/*
CLERIC_ABILITY_COST
The amount of mana a Cleric needs to perform its special ability.
*/
const int CLERIC_ABILITY_COST = 25;
class FighterInterface
{
public:
FighterInterface(){}
virtual ~FighterInterface(){}
/*
getName()
Returns the name of this fighter.
*/
virtual string getName() = 0;
/*
getMaximumHP()
Returns the maximum hit points of this fighter.
*/
virtual int getMaximumHP() = 0;
/*
getCurrentHP()
Returns the current hit points of this fighter.
*/
virtual int getCurrentHP() = 0;
/*
getStrength()
Returns the strength stat of this fighter.
*/
virtual int getStrength() = 0;
/*
getSpeed()
Returns the speed stat of this fighter.
*/
virtual int getSpeed() = 0;
/*
getMagic()
Returns the magic stat of this fighter.
*/
virtual int getMagic() = 0;
/*
getDamage()
Returns the amount of damage a fighter will deal.
Robot:
This value is equal to the Robot's strength plus any additional damage added for having just used its special ability.
Archer:
This value is equal to the Archer's speed.
Cleric:
This value is equal to the Cleric's magic.
*/
virtual int getDamage() = 0;
/*
takeDamage(int)
Reduces the fighter's current hit points by an amount equal to the given
damage minus one fourth of the fighter's speed. This method must reduce
the fighter's current hit points by at least one. It is acceptable for
this method to give the fighter negative current hit points.
Examples:
damage=10, speed=7 => damage_taken=9
damage=10, speed=9 => damage_taken=8
damage=10, speed=50 => damage_taken=1
*/
virtual void takeDamage(int damage) = 0;
/*
reset()
Restores a fighter's current hit points to its maximum hit points.
Robot:
Also restores a Robot's current energy to its maximum value (which is 2 times its magic).
Also resets a Robot's bonus damage to 0.
Archer:
Also resets an Archer's current speed to its original value.
Cleric:
Also restores a Cleric's current mana to its maximum value (which is 5 times its magic).
*/
virtual void reset() = 0;
/*
regenerate()
Increases the fighter's current hit points by an amount equal to one sixth of
the fighter's strength. This method must increase the fighter's current hit
points by at least one. Do not allow the current hit points to exceed the
maximum hit points.
Cleric:
Also increases a Cleric's current mana by an amount equal to one fifth of the
Cleric's magic. This method must increase the Cleric's current mana by at
least one. Do not allow the current mana to exceed the maximum mana.
*/
virtual void regenerate() = 0;
/*
useAbility()
Attempts to perform a special ability based on the type of fighter. The
fighter will attempt to use this special ability just prior to attacking
every turn.
Robot: Shockwave Punch
Adds bonus damage to the Robot's next attack (and only its next attack) equal to (strength * ((current_energy/maximum_energy)^4)).
Can only be used if the Robot has at least [ROBOT_ABILITY_COST] energy.
Decreases the Robot's current energy by [ROBOT_ABILITY_COST] (after calculating the additional damage) when used.
Examples:
strength=20, current_energy=20, maximum_energy=20 => bonus_damage=20
strength=20, current_energy=15, maximum_energy=20 => bonus_damage=6
strength=20, current_energy=10, maximum_energy=20 => bonus_damage=1
strength=20, current_energy=5, maximum_energy=20 => bonus_damage=0
Robot Note:
The bonus damage formula should be computed using double arithmetic, and only
the final result should be cast into an integer.
Archer: Quickstep
Increases the Archer's speed by one point each time the ability is used.
This bonus lasts until the reset() method is used.
This ability always works; there is no maximum bonus speed.
Cleric: Healing Light
Increases the Cleric's current hit points by an amount equal to one third of its magic.
Can only be used if the Cleric has at least [CLERIC_ABILITY_COST] mana.
Will be used even if the Cleric's current HP is equal to their maximum HP
Decreases the Cleric's current mana by [CLERIC_ABILITY_COST] when used.
Cleric Note:
This ability, when successful, must increase the Cleric's current hit points
by at least one. Do not allow the current hit points to exceed the maximum
hit points.
Return true if the ability was used; false otherwise.
*/
virtual bool useAbility() = 0;
/*
isSimplified()
Returns true if you have not completed the useAbility() and/or the regenerate()
methods for this type of fighter. This allows the test driver to award points
for Part 3 even if Part 4 is incomplete.
Return true if the testing is to be simplified; false otherwise.
*/
virtual bool isSimplified() = 0;
};
+33
View File
@@ -0,0 +1,33 @@
CXXFLAGS= -Wall -g
OBJECTS=main.o arena.o Factory.o archer.o fighter.o util.o cleric.o robot.o
EXE=main
all: $(EXE)
$(EXE): main.o
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $@
main.o: main.cpp Factory.o arena.o fighter.o archer.o util.o cleric.o robot.o
Factory.o: Factory.cpp Factory.h
arena.o: arena.cpp arena.h
fighter.o: fighter.cpp fighter.h
archer.o: archer.cpp archer.h fighter.h
cleric.o: cleric.cpp cleric.h fighter.h
robot.o: robot.cpp robot.h fighter.h
util.o: util.cpp util.h
run: $(EXE)
@./$(EXE)
clean:
@rm -vf *.o
@rm -vf $(EXE)
debug: $(EXE)
gdb ./$(EXE)
valgrind: $(EXE)
valgrind --tool=memcheck --leak-check=yes ./$(EXE)
+21
View File
@@ -0,0 +1,21 @@
#include "archer.h"
archer::archer(string name, int max_hp, int strength, int speed, int magic) :
fighter(name, max_hp, strength, speed, magic), original_speed(speed) {}
int archer::getDamage() {
return speed;
}
void archer::reset() {
hp = max_hp;
speed = original_speed;
}
bool archer::useAbility() {
speed++;
return true;
}
int archer::get_original_speed() {
return original_speed;
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef __ARCHER_H__
#define __ARCHER_H__
#include "fighter.h"
class archer : public fighter {
private:
int original_speed;
public:
archer(string, int, int, int, int);
string get_type() { return "A"; };
int getDamage();
void reset();
bool useAbility();
int get_original_speed();
};
#endif
+111
View File
@@ -0,0 +1,111 @@
#include <vector>
using namespace std;
#include "arena.h"
#include "fighter.h"
#include "archer.h"
#include "cleric.h"
#include "robot.h"
#include "util.h"
arena::~arena() {
fighter * f = NULL;
for(vector<FighterInterface *>::iterator it = fighters.begin();
it != fighters.end();
it++) {
f = dynamic_cast<fighter *>(*it);
delete f;
}
}
bool arena::contains(string name) {
fighter * f = NULL;
for(unsigned int i = 0; i < fighters.size(); i++) {
f = dynamic_cast<fighter *>(fighters[i]);
if(f->getName() == name) {
return true;
}
}
return false;
}
bool arena::addFighter(string info) {
fighter * f = NULL;
string name;
string type;
int max_hp;
int strength;
int speed;
int magic;
bool worked;
worked = parse_n_load(info, name, type, max_hp, strength, speed, magic);
if(not worked) {
return false;
}
if(contains(name)) {
return false;
}
if(type == "A") {
f = new archer(name, max_hp, strength, speed, magic);
}
else if(type == "C") {
f = new cleric(name, max_hp, strength, speed, magic);
}
else if(type == "R") {
f = new robot(name, max_hp, strength, speed, magic);
}
fighters.push_back(f);
return true;
}
bool arena::removeFighter(string name) {
fighter * f = NULL;
for(vector<FighterInterface *>::iterator it = fighters.begin();
it != fighters.end();
it++) {
f = dynamic_cast<fighter *>(*it);
if(f->getName() == name) {
delete f;
fighters.erase(it);
return true;
}
}
return false;
}
FighterInterface * arena::getFighter(string name) {
fighter * f = NULL;
for(vector<FighterInterface *>::iterator it = fighters.begin();
it != fighters.end();
it++) {
f = dynamic_cast<fighter *>(*it);
if(f->getName() == name) {
return dynamic_cast<FighterInterface *>(f);
}
}
return NULL;
}
int arena::getSize() {
return fighters.size();
}
ostream & operator<<(ostream & os, arena & a) {
os << "[";
for(vector<FighterInterface * >::iterator it = a.fighters.begin();
it != a.fighters.end();
it++) {
os << *(dynamic_cast<fighter *>( *it));
if (it != a.fighters.end() - 1) {
os << ", ";
}
}
os << "]";
return os;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __ARENA_H__
#define __ARENA_H__
#include <vector>
#include "ArenaInterface.h"
class arena : public ArenaInterface {
private:
std::vector<FighterInterface *> fighters;
bool contains(string name);
public:
arena(){}
~arena();
bool addFighter(string info);
bool removeFighter(string name);
FighterInterface * getFighter(string name);
int getSize();
friend ostream & operator<<(ostream &, arena &);
};
#endif
+59
View File
@@ -0,0 +1,59 @@
#include "FighterInterface.h"
#include "cleric.h"
cleric::cleric(string name, int max_hp, int strength, int speed, int magic) :
fighter(name, max_hp, strength, speed, magic), mana(5*magic) {}
int cleric::getDamage() {
return magic;
}
void cleric::reset() {
hp = max_hp;
mana = 5 * magic;
}
void cleric::regenerate() {
fighter::regenerate();
int increase = magic / 5;
if(increase < 0) {
increase = 0;
}
else if(increase == 0) {
increase = 1;
}
if(mana + increase < magic * 5) {
mana += increase;
}
else {
mana = 5 * magic;
}
}
bool cleric::useAbility() {
// a.k.a. Healing light
if(mana - CLERIC_ABILITY_COST >= 0) {
int increase = magic / 3;
if(increase < 0) {
increase = 0;
}
else if(increase == 0) {
increase = 1;
}
if(hp + increase < max_hp) {
hp += increase;
}
else {
hp = max_hp;
}
mana -= CLERIC_ABILITY_COST;
return true;
}
return false;
}
int cleric::get_mana() {
return mana;
}
+24
View File
@@ -0,0 +1,24 @@
#ifndef __CLERIC_H__
#define __CLERIC_H__
#include "fighter.h"
class cleric : public fighter {
private:
int original_speed;
int mana;
public:
cleric(string, int, int, int, int);
string get_type() { return "A"; };
int getDamage();
void reset();
bool useAbility();
void regenerate();
int get_original_speed();
int get_mana();
};
#endif
+72
View File
@@ -0,0 +1,72 @@
#include "fighter.h"
fighter::fighter(string name, int max_hp, int strength, int speed, int magic) :
name(name), max_hp(max_hp), hp(max_hp), strength(strength),
speed(speed), magic(magic) {}
string fighter::getName() {
return name;
}
int fighter::getMaximumHP() {
return max_hp;
}
int fighter::getCurrentHP() {
return hp;
}
int fighter::getStrength() {
return strength;
}
int fighter::getSpeed() {
return speed;
}
int fighter::getMagic() {
return magic;
}
void fighter::regenerate() {
int increase = strength / 6;
if(increase < 0) {
increase = 0;
}
else if(increase == 0) {
increase = 1;
}
if(hp + increase <= max_hp) {
hp += increase;
}
else {
hp = max_hp;
}
}
void fighter::takeDamage(int damage) {
int hurt = damage - (speed / 4);
if (hurt <= 0) {
hurt = 1;
}
hp -= hurt;
}
bool fighter::isSimplified() {
return false;
}
ostream & operator<<(ostream & os, fighter & f) {
os << "{\n"
<< " \"name\": \"" << f.name << "\",\n"
<< " \"type\": \"" << f.get_type() << "\",\n"
<< " \"hp\": " << f.hp << ",\n"
<< " \"max hp\": " << f.max_hp << ",\n"
<< " \"strength\": " << f.strength << ",\n"
<< " \"speed\": " << f.speed << ",\n"
<< " \"magic\": " << f.magic << ",\n"
<< "}";
return os;
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef __FIGHTER_H__
#define __FIGHTER_H__
#include <ostream>
#include "FighterInterface.h"
class fighter : public FighterInterface
{
private:
string name;
protected:
int max_hp;
int hp;
int strength;
int speed;
int magic;
public:
fighter(string, int, int, int, int);
// virtual ~fighter();
string getName();
int getMaximumHP();
int getCurrentHP();
int getStrength();
int getSpeed();
int getMagic();
virtual string get_type() = 0;
virtual int getDamage() = 0;
void takeDamage(int damage);
virtual void reset() = 0;
virtual void regenerate();
virtual bool useAbility() = 0;
bool isSimplified();
friend ostream & operator<<(ostream & os, fighter & a);
};
#endif
+205
View File
@@ -0,0 +1,205 @@
#include <iostream>
#include <cassert>
using namespace std;
#include "Battle.h"
#include "Factory.h"
#include "arena.h"
#include "archer.h"
#include "cleric.h"
#include "robot.h"
void test_fighter() {
archer a = archer("bilbo", 100, 60, 1, 5);
a.takeDamage(90);
a.regenerate();
assert(a.getCurrentHP() == 20);
archer b = archer("frodo", 100, 0, 1, 5);
b.takeDamage(90);
b.regenerate();
}
void test_archer() {
archer a("stephen", 666, 66, 6, 0);
a.takeDamage(100);
assert(a.getCurrentHP() == 567);
assert(a.get_original_speed() == 6);
assert(a.getSpeed() == 6);
}
void test_cleric() {
cleric a("Derek", 666, 66, 6, 20);
assert(a.getDamage() == 20);
assert(a.get_mana() == 100);
a.takeDamage(100);
assert(a.getCurrentHP() == 567);
a.reset();
assert(a.getCurrentHP() == 666);
cleric b("SaintColleen", 100, 90, 4, 60);
b.takeDamage(100);
b.useAbility();
assert(b.getCurrentHP() == 21);
cleric c("Vanessa", 100, 90, 4, 1);
c.takeDamage(100);
c.useAbility();
assert(c.getCurrentHP() == 1);
cleric d("Vanessa", 100, 90, 4, 5);
d.takeDamage(100);
d.useAbility();
assert(d.getCurrentHP() == 2);
}
void test_robot() {
robot a("Derek", 100, 20, 10, 10);
assert(a.getDamage() == 20);
a.useAbility();
assert(a.getDamage() == 40);
assert(a.getDamage() == 20);
a.useAbility();
assert(a.getDamage() == 26);
a.takeDamage(100);
assert(a.getCurrentHP() == 2);
a.reset();
assert(a.getCurrentHP() == 100);
}
void test_input_parser() {
ArenaInterface * A = Factory::createArena();
arena * a = dynamic_cast<arena *>(A);
string input = "Xephos A 200 13 21 10";
assert(a->addFighter(input));
input = "Stephen A 200 13 21 10";
assert(a->addFighter(input));
input = "Billy Bob Thorton A 0 13 21 10";
assert(not a->addFighter(input));
input = "Xephos a 200 13 21 10";
assert(not a->addFighter(input));
input = "Derek A 200 13 21 a10";
assert(not a->addFighter(input));
input = "Derek A 200 13 stupid21 10";
assert(not a->addFighter(input));
delete A;
}
void test_add() {
ArenaInterface * A = Factory::createArena();
arena * a = dynamic_cast<arena *>(A);
string input = "Xephos A 200 13 21 10";
assert(a->addFighter(input));
input = "Stephen A 200 13 21 10";
assert(a->addFighter(input));
// do not allow for duplicate fighers
input = "Xephos A 200 13 21 10";
bool double_add = a->addFighter(input);
assert(not double_add);
input = "Stephen A 0 13 21 10";
assert(not a->addFighter(input));
input = "Derek A 200 13 21 10";
assert(a->addFighter(input));
// another attempt for not allowing duplicate fighters
input = "Stephen A 200 13 21 10";
assert(not a->addFighter(input));
delete A;
}
void test_remove() {
ArenaInterface * A = Factory::createArena();
arena * a = dynamic_cast<arena *>(A);
string input = "Michael A 200 13 21 10";
a->addFighter(input);
input = "Derek A 200 13 21 10";
a->addFighter(input);
input = "Bryan A 200 13 21 10";
a->addFighter(input);
assert(not a->removeFighter("Zaphodbeblebrox"));
bool remove_non_existant = a->removeFighter("Stephen");
assert(not remove_non_existant);
assert(a->getSize() == 3);
bool remove_fighter = a->removeFighter("Michael");
assert(remove_fighter);
assert(a->getSize() == 2);
a->removeFighter("Derek");
a->removeFighter("Bryan");
assert(a->getSize() == 0);
delete a;
}
void test_find() {
ArenaInterface * A = Factory::createArena();
arena * a = dynamic_cast<arena *>(A);
string input = "Michael A 200 13 21 10";
a->addFighter(input);
input = "Derek A 200 13 21 10";
a->addFighter(input);
input = "Bryan A 200 13 21 10";
a->addFighter(input);
fighter * f;
f = dynamic_cast<fighter *>(a->getFighter("Stephen"));
assert(not f);
f = dynamic_cast<fighter *>(a->getFighter("Derek"));
assert(f);
delete a;
}
void test_archer_reset() {
archer a("stephen", 666, 66, 6, 0);
a.takeDamage(100);
assert(a.getCurrentHP() == 567);
a.reset();
assert(a.getCurrentHP() == a.getMaximumHP());
assert(a.getSpeed() == a.get_original_speed());
assert(a.getSpeed() == 6);
assert(a.get_original_speed() == 6);
}
void test_archer_usability() {
archer a("stephen", 666, 66, 6, 0);
assert(a.getSpeed() == 6);
a.useAbility();
assert(a.getSpeed() == 7);
}
void test_battle() {
archer a("stephen", 200, 66, 60, 100);
robot b("derek", 1000, 20, 15, 200);
fight(&a, &b, true);
}
int main() {
test_fighter();
test_archer();
test_cleric();
test_robot();
test_input_parser();
test_add();
test_remove();
test_find();
test_archer_reset();
test_archer_usability();
test_battle();
}
+30
View File
@@ -0,0 +1,30 @@
#include <cmath>
#include "FighterInterface.h"
#include "robot.h"
robot::robot(string name, int max_hp, int strength, int speed, int magic) :
fighter(name, max_hp, strength, speed, magic),
max_energy(2 * magic), cur_energy(2 * magic), extra_damage(0) {}
int robot::getDamage() {
int damage = strength + extra_damage;
extra_damage = 0;
return damage;
}
void robot::reset() {
hp = max_hp;
cur_energy = max_energy;
}
bool robot::useAbility() {
if(cur_energy - ROBOT_ABILITY_COST >= 0) {
double a = cur_energy/double(max_energy);
double b = pow(a, 4.0);
double increase = strength * b;
extra_damage = int(increase);
cur_energy -= ROBOT_ABILITY_COST;
return true;
}
return false;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __ROBOT_H__
#define __ROBOT_H__
#include "fighter.h"
class robot : public fighter {
private:
int max_energy;
int cur_energy;
int extra_damage;
public:
robot(string, int, int, int, int);
string get_type() { return "A"; };
int getDamage();
void reset();
bool useAbility();
int get_original_speed();
};
#endif
+60
View File
@@ -0,0 +1,60 @@
#include <vector>
#include <string>
using namespace std;
#include <cstdlib>
#include "util.h"
vector<string> tokenize(const string & str, const string & delimiters) {
vector<string> tokens;
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
return tokens;
}
bool parse_n_load(const string & input, string & name, string & type,
int & max_hp, int & strength, int & speed, int & magic) {
vector<string> tokens = tokenize(input);
vector<string> tokens2 = tokenize(input, ".");
if (tokens.size() != 6 or tokens2.size() > 1) {
return false;
}
name = tokens[0];
string parsed_type = tokens[1];
if(parsed_type.size() != 1) {
return false;
}
if (not ( parsed_type == "A"
or parsed_type == "C"
or parsed_type == "R")) {
return false;
}
type = parsed_type;
int parsed_max_hp = atoi(tokens[2].c_str());
int parsed_strength = atoi(tokens[3].c_str());
int parsed_speed = atoi(tokens[4].c_str());
int parsed_magic = atoi(tokens[5].c_str());
if (parsed_max_hp == 0 or parsed_strength == 0 or parsed_speed == 0 or
parsed_magic == 0) {
return false;
}
max_hp = parsed_max_hp;
strength = parsed_strength;
speed = parsed_speed;
magic = parsed_magic;
return true;
}
+14
View File
@@ -0,0 +1,14 @@
#ifndef __UTIL_H__
#define __UTIL_H__
#include <string>
#include <vector>
using namespace std;
void print(const string & in);
vector<string> tokenize(const string & str, const string & delimiters=" ");
bool parse_n_load(const string & input, string & name, string & type,
int & max_hp, int & strength, int & speed, int & magic);
#endif