#include "WagnisPlayer.h" #include #include #include #include namespace orxonox { RegisterClass(WagnisPlayer); //Constructor WagnisPlayer::WagnisPlayer(Context* context) : HumanPlayer(context){ RegisterObject(WagnisPlayer); this->gameBoard = nullptr; this->is_active = false; this->origin_province = nullptr; this->target_province = nullptr; this->province_selection_changed = false; this->gameStage = NOT_READY; this->reinforcements = 0; } //Destructor WagnisPlayer::~WagnisPlayer(){ } //Tick void WagnisPlayer::tick(float dt){ SUPER(WagnisPlayer, tick, dt); if(this->is_active) { for(WagnisProvince* prov:this->gameBoard->provs){ //orxout()<<"province health: "<getHealth()<getHealth() < prov->getMaxHealth()){ //Check if next-player-button was hit if(prov->getID() == 1000){ master->playerFinishedStageCallback(this); prov->setHealth(prov->getMaxHealth()); break; } //Check left/right click if(prov->getHealth() <= prov->getMaxHealth()-1000.0f){ this->target_province = prov; this->province_selection_changed = true; }else{ this->origin_province = prov; this->province_selection_changed = true; } prov->setHealth(prov->getMaxHealth()); } } if((this->province_selection_changed && this->origin_province != nullptr && this->target_province != nullptr) ||(this->province_selection_changed && this->target_province != nullptr && ((gameStage == CHOOSE_PROVINCE_STAGE)||(gameStage == REINFORCEMENT_STAGE)))){ this->province_selection_changed = false; switch(gameStage){ case CHOOSE_PROVINCE_STAGE: { if (checkMove(SET_TROOPS_INITIAL)){ this->target_province->setOwner_ID(this->Player_ID); this->target_province->setTroops(this->target_province->getTroops()+1); orxout()<<"Province "<target_province->getID()<<" owned by Player "<target_province->getOwner_ID()<<" troops: "<target_province->getTroops()<playerFinishedStageCallback(this); }else{ orxout()<<"Sorry, someone already owns this provice"< 0) { if (checkMove(SET_TROOPS)) { this->target_province->setTroops(this->target_province->getTroops()+1); this->reinforcements -= 1; orxout()<<"Province "<target_province->getID()<<" owned by Player "<target_province->getOwner_ID()<<" troops: "<target_province->getTroops()<origin_province->getTroops() > 1) && (this->target_province->getTroops() > 0)) //still troops available { while ((this->origin_province->getTroops() >= 4) && (this->target_province->getTroops() >= 2)) { //normal fight, 3 attackers, 2 defenders int att1 = dice(); int att2 = dice(); int att3 = dice(); int def1 = dice(); int def2 = dice(); int attBest = best3(att1, att2, att3); int attSecond = second3(att1, att2, att3); int defBest = best2(def1, def2); int defSecond = second2(def1, def2); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); if(defSecond >= attSecond) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attSecond > defSecond) this->target_province->setTroops(this->target_province->getTroops()-1); } if ((this->origin_province->getTroops() == 3) && (this->target_province->getTroops() >= 2)) { //2 attackers, 2 defenders int att1 = dice(); int att2 = dice(); int def1 = dice(); int def2 = dice(); int attBest = best2(att1, att2); int attSecond = second2(att1, att2); int defBest = best2(def1, def2); int defSecond = second2(def1, def2); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); if(defSecond >= attSecond) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attSecond > defSecond) this->target_province->setTroops(this->target_province->getTroops()-1); } if((this->origin_province->getTroops() == 2) && (this->target_province->getTroops() >= 2)) { //1 attacker, 2 defenders int attBest = dice(); int def1 = dice(); int def2 = dice(); int defBest = best2(def1, def2); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); } if((this->origin_province->getTroops() >= 4) && (this->target_province->getTroops() == 1)) { //3 attackers, 1 defender int att1 = dice(); int att2 = dice(); int att3 = dice(); int defBest = dice(); int attBest = best3(att1, att2, att3); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); } if((this->origin_province->getTroops() == 3) && (this->target_province->getTroops() == 1)) { //2 attackers, 1 defender int att1 = dice(); int att2 = dice(); int defBest = dice(); int attBest = best2(att1, att2); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); } if((this->origin_province->getTroops() == 2) && (this->target_province->getTroops() == 1)) { //1 attacker, 1 defender int attBest = dice(); int defBest = dice(); if(defBest >= attBest) this->origin_province->setTroops(this->origin_province->getTroops()-1); if (attBest > defBest) this->target_province->setTroops(this->target_province->getTroops()-1); } } if (this->target_province->getTroops() == 0) //attacker won { this->target_province->setOwner_ID(this->Player_ID); this->target_province->setTroops(this->origin_province->getTroops() - 1); this->origin_province->setTroops(1); } }else{ orxout()<<"Attack move check returned false"<target_province->setTroops(this->origin_province->getTroops()-1); this->origin_province->setTroops(1); master->playerFinishedStageCallback(this); } break; } default: break; } } } } //checks if a move is valid, possible MoveTypes: ATTACK, MOVE, SET_TROOPS, SET_TROOPS_INITIAL bool WagnisPlayer::checkMove(MoveType move_type) { if (move_type == ATTACK) { if (isNeighbour(this->origin_province, this->target_province))//provinces neighbours { if (this->origin_province->getOwner_ID() == this->Player_ID) //origin belongs to player { if (this->target_province->getOwner_ID() != this->Player_ID)//target belongs to enemy return true; } } } if (move_type == MOVE) { if (existPath(this->origin_province, this->target_province))//path exists, all belong to same player { if (this->origin_province->getOwner_ID() == this->Player_ID)//origin belongs to player return true; } } if (move_type == SET_TROOPS) { if (this->target_province->getOwner_ID() == this->Player_ID)//target belongs to player return true; } if (move_type == SET_TROOPS_INITIAL) { if (this->target_province->getOwner_ID() == -1)//target belongs to nobody return true; } return false; } //Return a "Player x" String std::string WagnisPlayer::toString(){ std::string str = "Player "; str.append(std::to_string(Player_ID)); return str; } //private function for CheckMove //checks if provinces are neighbours for move bool WagnisPlayer::isNeighbour(WagnisProvince* origin, WagnisProvince* target) { for (unsigned int i = 0; i < origin->neighbors.size(); ++i) { if (target == origin->neighbors[i]) return true; } return false; } //private function for CheckMove //checks if path is complete with provinces owned by player bool WagnisPlayer::existPath(WagnisProvince* origin, WagnisProvince* target) { if (origin->getOwner_ID() == target->getOwner_ID() && isNeighbour(origin, target)) return true; for (unsigned int i = 0; i < origin->neighbors.size(); ++i) { if (origin->getOwner_ID() == origin->neighbors[i]->getOwner_ID()) return existPath(origin->neighbors[i], target); } return false; } int WagnisPlayer::dice() //returns random integer in range [1, 2, 3, 4, 5, 6] { srand(time(NULL)); return (rand()%6+1); } int WagnisPlayer::best3(int a, int b, int c) //returns best of 3 integers for attack stage { if(a >= b && a>= c) return a; if(b >= a && b>= c) return b; else return c; } int WagnisPlayer::best2(int a, int b) //returns best of 2 integers for attack stage { if(a >= b) return a; else return b; } int WagnisPlayer::second3(int a, int b, int c) //returns second of 3 integers for attack stage { if((a >= b && a <= c)||(a <= b && a >= c)) return a; if((b >= a && b <= c)||(b <= a && b >= c)) return b; else return c; } int WagnisPlayer::second2(int a, int b) //returns second of 2 integers for attack stage { if(a <= b) return a; else return b; } void WagnisPlayer::setActive(bool b){ this->is_active = b; if(b == true) orxout()<<"Player "<Player_ID<<"\'s turn"<is_active; } }