diff --git a/Cell.cpp b/Cell.cpp new file mode 100644 index 0000000..30eb540 --- /dev/null +++ b/Cell.cpp @@ -0,0 +1,201 @@ +#include "Cell.h" +#include "unit.h" +#include +#include + +Cell::Cell(Unit * character) { + leftUp_ = left_ = leftDown_ = nullptr; + rightUp_ = right_ = rightDown_ = nullptr; + character_ = &character; + clearCell_(); + AddedToQuery_ = true; +} + +Cell * Cell::getleftUp() { + return leftUp_; +} +void Cell::setleftUp(Cell * t) { + leftUp_ = t; +} + +Cell * Cell::getleft() { + return left_; +} +void Cell::setleft(Cell * t) { + left_ = t; +} + +Cell * Cell::getleftDown() { + return leftDown_; +} +void Cell::setleftDown(Cell * t) { + leftDown_ = t; +} + +Cell * Cell::getrightUp() { + return rightUp_; +} +void Cell::setrightUp(Cell * t) { + rightUp_ = t; +} + +Cell * Cell::getright() { + return right_; +} +void Cell::setright(Cell * t) { + right_ = t; +} + +Cell * Cell::getrightDown() { + return rightDown_; +} +void Cell::setrightDown(Cell * t) { + rightDown_ = t; +} + +Unit * Cell::getCharacter() { + return character_; +} +void Cell::setCharacter(Unit * t) { + character_ = t; +} + +bool Cell::getisMoveable() { + return isMoveable_; +} +void Cell::setisMoveable(bool t) { + isMoveable_ = t; +} + +bool Cell::getisAttackable() { + return isAttackable_; +} +void Cell::setisAttackable(bool t) { + isAttackable_ = t; +} + +int Cell::getDistance() { + return distance_; +} +void Cell::setDistance(int t) { + distance_ = t; +} + +bool Cell::isEmpty() { + return character_ == NULL; +} + +void Cell::clearCell_() { + setisMoveable(false); + setisAttackable(false); + setDistance(-1); +} + +void Cell::clearTable_() { + std::queue q; + q.push(this); + clearCell_(); + this->AddedToQuery_ = false; + auto f = [&q](Cell * t) { + if (t && t->AddedToQuery_ == true) { + q.push(t); + t->AddedToQuery_ = false; + } + }; + while (!q.empty()) { + Cell * Now = q.front(); + q.pop(); + Now->clearCell_(); + f(Now->getleftUp()); + f(Now->getleft()); + f(Now->getleftDown()); + f(Now->getrightUp()); + f(Now->getright()); + f(Now->getrightDown()); + } +} + +void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue & Q) { + std::queue q; + q.push(this); + setDistance(0); + auto f = [&q, &Q](Cell * t, Cell * parent) { + if (t && !t->AddedToQuery_) { + t->AddedToQuery_ = true; + if (t->getCharacter() != NULL) { + t->setisMoveable(false); + Q.push(t); + return; + } + q.push(t); + t->setDistance(parent->getDistance() + 1); + } + }; + while (!q.empty()) { + Cell * Now = q.front(); + Now->setisMoveable(true); + if (getCharacter() != NULL && getCharacter()->СanAttack(Now->getDistance())) { + Now->setisAttackable(true); + } + else { + Now->setisAttackable(false); + } + q.pop(); + f(Now->getleftUp(), Now); + f(Now->getleft(), Now); + f(Now->getleftDown(), Now); + f(Now->getrightUp(), Now); + f(Now->getright(), Now); + f(Now->getrightDown(), Now); + } +} + +void Cell::handleAllUnmoveableCells_(std::queue & Q) { + auto f = [&Q](Cell * t, Cell * parent) { + if (t && !t->AddedToQuery_) { + t->AddedToQuery_ = true; + Q.push(t); + } + }; + while (!Q.empty()) { + Cell * Now = Q.front(); + Now->setisMoveable(false); + Now->setisAttackable(false); + Q.pop(); + f(Now->getleftUp(), Now); + f(Now->getleft(), Now); + f(Now->getleftDown(), Now); + f(Now->getrightUp(), Now); + f(Now->getright(), Now); + f(Now->getrightDown(), Now); + } +} + +void Cell::RecalculateTableWithCenterThisPoint() { + clearTable_(); + std::queue qWithoutMoveable; + handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable); + handleAllUnmoveableCells_(qWithoutMoveable); +} + +std::vector Cell::actualPath(Cell* to) {//std::vector âêëþ÷àåòñÿ â ñåáÿ è this, è end + if (!to || !to->getisMoveable())return std::vector(); + auto ret = std::vector(1, to); + while (to != this) { + Cell * parent = NULL; + auto f = [&parent](Cell * TestParent, Cell * Now) { + if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getisMoveable()) { + parent = TestParent; + } + }; + f(to->getleftUp(), to); + f(to->getleft(), to); + f(to->getleftDown(), to); + f(to->getrightUp(), to); + f(to->getright(), to); + f(to->getrightDown(), to); + to = parent; + ret.push_back(to); + } + return ret; +} diff --git a/Cell.h b/Cell.h new file mode 100644 index 0000000..e425ceb --- /dev/null +++ b/Cell.h @@ -0,0 +1,70 @@ +#pragma once +#include +#include + +class Unit; + +class Cell { + +private: + Cell * leftUp_; + Cell *left_; + Cell * leftDown_; + + Cell *rightUp_; + Cell *right_; + Cell *rightDown_; + + Unit *character_; + + bool isMoveable_; + bool isAttackable_; + + int distance_; + bool AddedToQuery_; + + void clearTable_(); + void clearCell_(); + + void handleAllMoveableCellsAndUnmoveableCells_(std::queue & Q); + void handleAllUnmoveableCells_(std::queue & Q); + +public: + + explicit Cell(Unit * character); + + Cell * getleftUp(); + void setleftUp(Cell *); + + Cell * getleft(); + void setleft(Cell *); + + Cell * getleftDown(); + void setleftDown(Cell *); + + Cell * getrightUp(); + void setrightUp(Cell *); + + Cell * getright(); + void setright(Cell *); + + Cell * getrightDown(); + void setrightDown(Cell *); + + Unit * getCharacter(); + void setCharacter(Unit *); + + bool getisMoveable(); + void setisMoveable(bool); + + bool getisAttackable(); + void setisAttackable(bool); + + int getDistance(); + void setDistance(int); + + bool isEmpty(); + + void RecalculateTableWithCenterThisPoint(); + std::vector actualPath(Cell*); +}; diff --git a/unit.cpp b/unit.cpp index 32b93db..df7fc0c 100644 --- a/unit.cpp +++ b/unit.cpp @@ -4,8 +4,31 @@ #include #include #include "unit.h" +#include "AbstractFactory.h" -Unit::Unit(){} +int Unit::getCost(){ + return cost_; +} + +void Unit::setCost(int value){ + cost_ = value; +} + +std::string Unit::getParentSpec(){ + return parent_spec_; +} + +void Unit::setParentSpec(std::string specId){ + parent_spec_ = specId; +} + +std::vector Unit::getUpgradeSpecs(){ + return upgrade_specs_; +} + +void Unit::setUpgradeSpecs(std::vector specs){ + upgrade_specs_ = specs; +} double Unit::getExperience() { return experience_; @@ -28,27 +51,6 @@ void Unit::setHealthPoints(double value) { health_points_ = value; } -double Unit::getManaPoints() { - return mana_points_; -} -void Unit::setManaPoints(double value) { - mana_points_ = value; -} - -double Unit::getEnergyPoints() { - return energy_points_; -} -void Unit::setEnergyPoints(double value) { - energy_points_ = value; -} - -double Unit::getActivePoints() { - return active_points_; -} -void Unit::setActivePoints(double value) { - active_points_ = value; -} - double Unit::getAttackRange() { return attack_range_; } @@ -56,24 +58,38 @@ void Unit::setAttackRange(double value) { attack_range_ = value; } -std::pair Unit::getLocation() { +int Unit::getActivityPoints(){ + return activity_points_; +} +void Unit::setActivityPoints(int value){ + activity_points_ = value; +} + +Cell* Unit::getLocation() { return location_; } -void Unit::setLocation(double x, double y) { - location_ = std::make_pair(x, y); +void Unit::setLocation(Cell* to) { + location_ = to; } -double Unit::getMovementSpeed() { +int Unit::getMovementSpeed() { return movement_speed_; } -void Unit::setMovementSpeed(double value) { +void Unit::setMovementSpeed(int value) { movement_speed_ = value; } -double Unit::getInitiative_() { +int Unit::getAttackCost(){ + return attack_cost_; +} +void Unit::setAttackCost(int value){ + attack_cost_ = value; +} + +double Unit::getInitiative() { return initiative_; } -void Unit::setInitiative_(double value) { +void Unit::setInitiative(double value) { initiative_ = value; } @@ -105,6 +121,13 @@ void Unit::setAgility(double value) { agility_ = value; } +int Unit::getAttackPoints(){ + return attack_cost_; +} +void Unit::setAttackPoints(int value){ + attack_cost_ = value; +} + double Unit::getMagicDefence() { return magic_defence_; } @@ -119,6 +142,27 @@ void Unit::setPhysicDefence(double value) { physic_defence_ = value; } +std::string Unit::getRace() { + return race_; +} +void Unit::setRace(std::string new_race) { + race_ = new_race; +} + +double Unit::getRealX() { + return real_x_; +} +void Unit::setRealX(double x) { + real_x_ = x; +} + +double Unit::getRealY() { + return real_y_; +} +void Unit::setRealY(double y) { + real_y_ = y; +} + void Unit::calculateDamagePerHit() { damage_per_hit_ = 0.5 * std::max(getAgility(), std::max(getStrength(), getIntelligence())); } @@ -135,3 +179,25 @@ double Unit::reduceIncomingDamage(std::string damageType, int damage) { //return return (1 - 2.5 * magic_defence_ / 100) * damage; } } + +int Unit::lenOfActualPath(Cell* destination) { + return getLocation()->actualPath(destination).size(); +} + +bool Unit::canMoveForDistance(int distance) { + return (movement_speed_ >= distance); +} + +bool Unit::canMoveToCell(Cell* destination) { + return (destination->isEmpty() && lenOfActualPath(destination) > 0 && canMoveForDistance(lenOfActualPath(destination))); +} + +void Unit::moveToCell(Cell* destination) { + if (!canMoveToCell(destination)) + return; //here could be a gui-message about failed move (x-mark, for example) + else { + int decreasedValue = getMovementSpeed() - lenOfActualPath(destination); + setMovementSpeed(decreasedValue); + setLocation(destination); + } +} \ No newline at end of file diff --git a/unit.h b/unit.h index eb1e78f..18a06a5 100644 --- a/unit.h +++ b/unit.h @@ -1,9 +1,20 @@ #pragma once #include #include +#include "AbstractFactory.h" -class Spell { - //empty for allow to compile +class Spell; +class Cell { + //waiting for a realisation +public: + //must be in cell.h + bool isEmpty() { + return true; + } + std::vector actualPath(Cell* destination) { //the shortest existing path from (*this) to (*destination) + std::vector path; + return path; + } }; class Unit { @@ -12,26 +23,31 @@ class Unit { std::vector skills_; private: - //personal growth + //personal information + int cost_; + std::string parent_spec_; + std::vector upgrade_specs_; double experience_; double level_; + std::string race_; //lower case - //connect with events - double active_points_; + //actions and events double initiative_; + int activity_points_; //movement - std::pair location_; //x - first, y - second - double movement_speed_; + Cell* location_; + int movement_speed_; //how many cells can move for one activity point + double real_x_; + double real_y_; //attack action double agility_; double attack_range_; double damage_per_hit_; - double energy_points_; //for physical attacks double intelligence_; - double mana_points_; //for magic attacks double strength_; + int attack_cost_; //how many activity points does attack cost //durability double health_points_; @@ -39,9 +55,21 @@ class Unit { double physic_defence_; //less or equal 40 public: - Unit(); + Unit() = delete; + Unit(std::string path) { + + } virtual ~Unit() = delete; + int getCost(); + void setCost(int value); + + std::string getParentSpec(); + void setParentSpec(std::string specId); + + std::vector getUpgradeSpecs(); + void setUpgradeSpecs(std::vector specs); + double getExperience(); void setExperience(double value); @@ -51,26 +79,23 @@ class Unit { double getHealthPoints(); void setHealthPoints(double value); - double getManaPoints(); - void setManaPoints(double value); - - double getEnergyPoints(); - void setEnergyPoints(double value); - - double getActivePoints(); - void setActivePoints(double value); - double getAttackRange(); void setAttackRange(double value); - std::pair getLocation(); - void setLocation(double x, double y); + int getActivityPoints(); + void setActivityPoints(int value); + + Cell* getLocation(); + void setLocation(Cell* to); - double getMovementSpeed(); - void setMovementSpeed(double value); + int getMovementSpeed(); + void setMovementSpeed(int value); - double getInitiative_(); - void setInitiative_(double value); + int getAttackCost(); + void setAttackCost(int value); + + double getInitiative(); + void setInitiative(double value); double getDamagePerHit(); void setDamagePerHit(double value); @@ -84,13 +109,39 @@ class Unit { double getAgility(); void setAgility(double value); + int getAttackPoints(); + void setAttackPoints(int value); + double getMagicDefence(); void setMagicDefence(double value); double getPhysicDefence(); void setPhysicDefence(double value); + std::string getRace(); + void setRace(std::string new_race); + + double getRealX(); + void setRealX(double x); + + double getRealY(); + void setRealY(double y); + virtual void calculateDamagePerHit(); - double reduceIncomingDamage(std::string damageType, int value); + virtual double reduceIncomingDamage(std::string damageType, int value); + + int lenOfActualPath(Cell* destination); + + virtual bool canMoveForDistance(int distance); + + virtual bool canMoveToCell(Cell* destination); + + virtual void moveToCell(Cell* destination); + + virtual bool canAttackForDistance(int distance) = 0; + + virtual bool canAttackToCell(Cell* destination) = 0; + + virtual bool canAttackUnit(Unit* target) = 0; }; \ No newline at end of file