CSC112 Spring 2016 Examples
/*1* Implementation of a generic attack alpaca.2*/3#include <cmath>4#include <iostream>5#include <cstdlib>6#include "alpaca.h"78using namespace std;910//a hardened version of log. Returns 0 in the case of any11//would-be chicanery12static double alpacaLog(double x)13{14double result;1516//handle 017if(x==0) {18return 0;19}2021//try to get the log22result = log(x);2324//any other wierdness will be dealt with25if(!isnormal(x)) {26result = 0;27}2829return result;30}313233Alpaca::Alpaca(unsigned int power) {34this->power = power;3536//set all the defaults37hp=100;38attackScore=5;39defense=0.05;40myTurn = false;41status = NONE;42statusCounter=0;43}444546void47Alpaca::attack(Alpaca *opponent, unsigned int p) {48double damage;4950if(!myTurn) return;5152//limit ourselves to our remaining power53if(p > power) {54p = power;55}5657//we use a O(m lg n) attack rate58damage = attackScore * alpacaLog(p);5960//opponents can defend according to61damage -= (damage * opponent->defense);6263//make it happen, and report it64cout << " " << opponent->name()65<< " takes " << damage << " points of damage!" << endl;66opponent->hp -= damage;6768//we just used some power69power -= p;7071//you get one action!72myTurn = false;73}747576void77Alpaca::sleep(Alpaca *opponent, unsigned int p) {78int r; //number of rounds for the status counter7980if(!myTurn) return;8182//limit ourselves to our remaining power83if(p > power) {84p = power;85}8687//sleep like a alpacaLog. fnord!88r = (int) ceil(alpacaLog(p));8990//if the alpaca is currently asleep, we are adding rounds91if(opponent->status == ASLEEP) {92r = opponent->statusCounter + r;93}9495//put the alpaca to sleep96power-=p;97opponent->status = ASLEEP;98opponent->statusCounter = r;99cout << " " << opponent->name() << " goes to sleep." << endl;100101//you get one action!102myTurn = false;103}104105void106Alpaca::stun(Alpaca *opponent, unsigned int p) {107if(!myTurn) return;108int r; //number of rounds for the status counter109110if(!myTurn) return;111112//limit ourselves to our remaining power113if(p > power) {114p = power;115}116117//sleep like a alpacaLog. fnord!118r = (int) ceil(alpacaLog(2*p));119120//if the alpaca is currently asleep, we are adding rounds121if(opponent->status == STUNNED) {122r = opponent->statusCounter + r;123}124125//put the alpaca to sleep126opponent->status = STUNNED;127opponent->statusCounter = r;128power-=p;129cout << " " << opponent->name() << " suffers a mild concussion!" << endl;130131//you get one action!132myTurn = false;133}134135136void137Alpaca::decreaseDefense(Alpaca *opponent, unsigned int p) {138double d;139if(!myTurn) return;140141//limit ourselves to our remaining power142if(p > power) {143p = power;144}145146//decrease the defense according to the alpacaLog growth rate formula147d=opponent->defense * 100;148if(d>1) {149d-=alpacaLog(d) + alpacaLog(p);150} else {151d-=alpacaLog(p);152}153154//we can't do negative defense155if(d<0) d = 0;156157//set the defense158opponent->defense = d/100.0;159cout << " " << opponent->name() << "'s defense falls!" << endl;160power -= p;161162//you get one action!163myTurn = false;164}165166void167Alpaca::decreaseAttack(Alpaca *opponent, unsigned int p) {168double a;169170if(!myTurn) return;171//limit ourselves to our remaining power172if(p > power) {173p = power;174}175176//make it happen177a = opponent->attackScore - alpacaLog(opponent->attackScore) - alpacaLog(p);178if(a<0) a = 0;179power -= p;180opponent->attackScore = a;181182cout << " " << opponent->name() << "'s attack falls!" << endl;183184//you get one action!185myTurn = false;186187}188189void190Alpaca::increaseAttack(unsigned int p) {191if(!myTurn) return;192193//limit ourselves to our remaining power194if(p > power) {195p = power;196}197198//raise our attack199attackScore += alpacaLog(attackScore) + alpacaLog(p);200power-=p;201cout << " " << name() << " is getting pumped!" << endl;202203//you get one action!204myTurn = false;205}206207void208Alpaca::increaseDefense(unsigned int p) {209if(!myTurn) return;210211//limit ourselves to our remaining power212if(p > power) {213p = power;214}215216//raise our defense217defense *= 100;218defense += alpacaLog(defense) + alpacaLog(p);219if(defense >= 100) defense = 99;220defense /= 100.0;221power -= p;222cout << " " << name() << " looks a little tougher." << endl;223224//you get one action!225myTurn = false;226}227228void229Alpaca::increaseHp(unsigned int p) {230if(!myTurn) return;231232//limit ourselves to our remaining power233if(p > power) {234p = power;235}236237//increase the hp238hp += alpacaLog(hp) + alpacaLog(p);239power-=p;240cout << " " << name() << " looks healthier." << endl;241242//you get one action!243myTurn = false;244}245246//perform multi-attack moves (Each option multiplies the total point247//expendature, so 2 combos cost twice as much as 1 move, 3 cost 3, etc.248//put points into each attack category, 0 if you don't want to use that249void250Alpaca::comboAttack(Alpaca *opponent,251unsigned int attackPoints,252unsigned int sleepPoints,253unsigned int stunPoints,254unsigned int decDefensePoints,255unsigned int decAttackPoints)256{257if(!myTurn) return;258259//first, get the multiplier260int mult=0;261if(attackPoints) mult++;262if(sleepPoints) mult++;263if(stunPoints) mult++;264if(decDefensePoints) mult++;265if(decAttackPoints) mult++;266267//if there is no multiplier, return. Nothing to do!268if(!mult){ myTurn=false; return; }269270//pay the multi-attack cost271int sum = attackPoints + sleepPoints + stunPoints + decDefensePoints + decAttackPoints;272sum -= sum/mult;273if(sum > power) power = 0; else power-=sum;274275//and perform each action276if(attackPoints) {277myTurn=true;278attack(opponent, attackPoints/mult);279}280281if(sleepPoints) {282myTurn = true;283sleep(opponent, sleepPoints/mult);284}285286if(stunPoints) {287myTurn = true;288stun(opponent, stunPoints/mult);289}290291if(decDefensePoints) {292myTurn = true;293decreaseDefense(opponent, decDefensePoints/mult);294}295296if(decAttackPoints) {297myTurn = true;298decreaseAttack(opponent, decDefensePoints/mult);299}300301//regardless, our turn ends here!302myTurn = false;303}304305306307//perform a multi-buf move. (Each option multiplies the total point308//expendature, so 2 combos cost twice as much as 1 move, and so on.309void310Alpaca::comboBuf(unsigned int incAttackPoints,311unsigned int incDefensePoints,312unsigned int incHpPoints)313{314if(!myTurn) return;315316//first work out the multiplier317int mult=0;318if(incAttackPoints) mult++;319if(incDefensePoints) mult++;320if(incHpPoints) mult++;321322//if there is no multiplier, we are done323if(!mult) { myTurn = false; return; }324325//pay the multi-attack cost326int sum = incAttackPoints + incDefensePoints + incHpPoints;327sum -= sum/mult;328if(sum > power) power = 0; else power-=sum;329330//do the buffs331if(incAttackPoints) {332myTurn = true;333increaseAttack(incAttackPoints/mult);334}335336if(incDefensePoints) {337myTurn = true;338increaseDefense(incDefensePoints/mult);339}340341if(incHpPoints) {342myTurn = true;343increaseHp(incHpPoints/mult);344}345}346347348//buffs you can apply to allies (or enemies if you are nuts)349//this works like the combo buf function350void351Alpaca::bufAlly(Alpaca *ally,352unsigned int incAttackPoints,353unsigned int incDefensePoints,354unsigned int incHpPoints)355{356if(!myTurn) return;357358//first work out the multiplier359int mult;360if(incAttackPoints) mult++;361if(incDefensePoints) mult++;362if(incHpPoints) mult++;363364//if there is no multiplier, we are done365if(!mult) { myTurn = false; return; }366367//work out the total cost368int powerCost = (incAttackPoints + incDefensePoints + incHpPoints);369370//transfer the power!371if(powerCost > power) powerCost = power;372power -= powerCost;373ally->power += powerCost;374375//and let the alpaca buf itself376ally->myTurn = true;377ally->comboBuf(incAttackPoints, incDefensePoints, incHpPoints);378ally->myTurn = false;379380myTurn = false;381}382383384//checks the remaining alpaca power385unsigned int386Alpaca::getPower()387{388return power;389}390391392//checks the attack score of the alpaca393double394Alpaca::getAttack()395{396return attackScore;397}398399400//checks the defense score of the alpaca401double402Alpaca::getDefense()403{404return defense;405}406407408//checks the hp of the alpaca409double410Alpaca::getHp()411{412return hp;413}414415//checks the turn status416bool417Alpaca::isMyTurn()418{419return myTurn;420}421422423//checks the alpaca status424alpacaStatus425Alpaca::getStatus()426{427return status;428}429430431//checks how long the status will remain in effect432unsigned int433Alpaca::getStatusCounter()434{435return statusCounter;436}437438439bool440Alpaca::isAlive() {441return hp > 0 && power != 0;442}443444445/*446* This function runs the alpaca round. It starts by beginning the turn447* and then checks the alpaca status. If appropriate, it lets an alpaca448* act, or it updates statuses.449*/450void451Alpaca::performRound(Alpaca *opponent) {452myTurn = true; //it's my turn!453454//act according to the status455switch(status) {456case NONE:457act(opponent);458break;459460case ASLEEP:461statusCounter--; //sleep this round462if(statusCounter <= 0) {463status = NONE;464cout << name() << " woke up!" << endl;465} else {466cout << name() << " is asleep." << endl;467}468break;469470case STUNNED:471statusCounter--; //be stunned this round472if(statusCounter <=0) {473status = NONE;474cout << name() << " can move again!" << endl;475} else {476cout << name() << " is stunned. It may not attack." << endl;477if(rand() % 10 <= 3) act(opponent);478}479break;480}481482//end my turn483myTurn = false;484}485486487