Skip to content

Commit

Permalink
added project 1 testcases and solution
Browse files Browse the repository at this point in the history
  • Loading branch information
rizaozcelik committed Dec 3, 2020
1 parent d81f484 commit cb96474
Show file tree
Hide file tree
Showing 25 changed files with 2,972 additions and 0 deletions.
Binary file added project1/Description.pdf
Binary file not shown.
66 changes: 66 additions & 0 deletions project1/solution/riza/Character.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "Character.h"

Character::Character(string _name, string _type, int _attack, int _defense, int _remainingHealth, int _nMaxRounds) {
this->name = _name;
this->type = _type;
this->attack = _attack;
this->defense = _defense;
this->remainingHealth = _remainingHealth;
this->nMaxRounds = _nMaxRounds;

this->nRoundsSinceSpecial = 0;
this->isAlive = true;
this->healthHistory = new int[this->nMaxRounds + 1];
this->healthHistory[0] = _remainingHealth;
}

Character::Character(const Character& character) {
this->name = character.name;
this->type = character.type;
this->attack = character.attack;
this->defense = character.defense;
this->remainingHealth = character.remainingHealth;
this->nMaxRounds = character.nMaxRounds;

this->isAlive = character.isAlive;
this->nRoundsSinceSpecial = character.nRoundsSinceSpecial;
this->healthHistory = new int[this->nMaxRounds + 1];
for (int i = 0; i < this->nMaxRounds + 1; i++) {
this->healthHistory[i] = character.healthHistory[i];
}

}

Character Character::operator=(const Character& character) {
if (this == &character) {
return *this;
}

if (this->healthHistory != NULL) { // If this object was used before, free the memory it has used.
delete[] this->healthHistory;
}
this->name = character.name;
this->type = character.type;
this->attack = character.attack;
this->defense = character.defense;
this->remainingHealth = character.remainingHealth;
this->nMaxRounds = character.nMaxRounds;

this->isAlive = character.isAlive;
this->nRoundsSinceSpecial = character.nRoundsSinceSpecial;
this->healthHistory = new int[this->nMaxRounds + 1];
for (int i = 0; i < this->nMaxRounds + 1; i++) {
this->healthHistory[i] = character.healthHistory[i];
}
return *this;
}

bool Character::operator<(const Character& other) {
return this->name < other.name;
}

Character::~Character() {
if (this->healthHistory != NULL){
delete[] this->healthHistory;
}
}
24 changes: 24 additions & 0 deletions project1/solution/riza/Character.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <string>
using namespace std;

#ifndef CHARACTER_H
#define CHARACTER_H


class Character {

public:
bool isAlive = true;
string name, type;
int attack, defense, remainingHealth, nMaxRounds, nRoundsSinceSpecial;
int* healthHistory = NULL;

Character(string _name, string _type, int _attack, int _defense, int _remainingHealth, int _nMaxRounds);
Character(const Character& character);
Character operator=(const Character& character);
bool operator<(const Character& other);
~Character();
};


#endif //CHARACTER_H
213 changes: 213 additions & 0 deletions project1/solution/riza/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
#include "Character.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
void printCommunity(ofstream& outfile, vector<Character> community, int round) {
for (int i = 0; i < 5; i++) {
Character c = community[i];
outfile << c.name;
for (int i = 0; i < round + 1; i++) {
outfile << ' ' << c.healthHistory[i];
}
outfile << endl;
}
}

bool warContinues(vector<Character> community) {
bool isHobbitAlive, isAnyMemberAlive = false;
for (int i = 0; i < 5; i++) {
Character c = community[i];
if (c.type == "Hobbit") {
isHobbitAlive = c.isAlive;
} else {
isAnyMemberAlive = isAnyMemberAlive || c.isAlive;
}
}
return isHobbitAlive && isAnyMemberAlive;
}

void updateNRoundsSinceSpecial(vector<Character>& community) {
for (int i = 0; i < 5; i++) {
Character* c = &community[i];
c->nRoundsSinceSpecial = c->nRoundsSinceSpecial + 1;
}
}

void updateHealthHistory(vector<Character>& community, int round) {
for (int i = 0; i < 5; i++) {
Character* c = &community[i];
c->healthHistory[round] = c->remainingHealth;
}
}

Character findActor(string actorName, vector<Character> community) {
// Pass a copy; do not care if the vector is changed in the function.
sort(community.begin(), community.end());

int actorIdx = -1;
for (int i = 0; i < 5; i++) {
Character c = community[i];
if (actorName == c.name) {
actorIdx = i;
if (c.isAlive) {
return c;
}
break; // If the actor is dead, search the other actors.
}
}

// Check alphabetically next actor
for (int j = actorIdx + 1; j < 5; j++) {
Character c = community[j];
if (c.isAlive) {
return c;
}
}

// Check alphabetically previous actor
for (int j = actorIdx-1; j >= 0; j--) {
Character c = community[j];
if (c.isAlive) {
return c;
}
}
}

Character readCharacter(ifstream& infile, int nMaxRounds) {
string charName, charType;
int attack, defense, initialHealth;
infile >> charName >> charType >> attack >> defense >> initialHealth;
return Character(charName, charType, attack, defense, initialHealth, nMaxRounds);
}

int main(int argc, char* argv[]) {

ifstream infile;
infile.open(argv[1]);

int nMaxRounds;
infile >> nMaxRounds;

// Create an empty vector of characters. If you try to intialize it with 5 characters, you shall get an error!
vector<Character> community1;
for (int i = 0; i < 5; i++) {
community1.push_back(readCharacter(infile, nMaxRounds));
}

vector<Character> community2;
for (int i = 0; i < 5; i++) {
community2.push_back(readCharacter(infile, nMaxRounds));
}

// Store one pointer for each of the attacker and defenders. Will swap them at each round.
vector<Character>* attackerCommunity = &community1;
vector<Character>* defenderCommunity = &community2;
int idxLastDeadAttacker = -1, idxLastDeadDefender = -1; // Track the last dead character for Wizard's special skill.
bool ifWarContinues = true;
int round = 1;
while (round <= nMaxRounds && ifWarContinues) {
string attackerName, defenderName, isSpecialStr;
infile >> attackerName >> defenderName >> isSpecialStr;
bool isSpecial = isSpecialStr == "SPECIAL";
Character attacker = findActor(attackerName, *attackerCommunity); // These will be used only for info read. Updates are useless.
Character defender = findActor(defenderName, *defenderCommunity);

int extraDamagePoint = 0; // Will be used for Dwarf's special skill.
if (isSpecial) {
if (attacker.type == "Elves" && attacker.nRoundsSinceSpecial >= 10) {
int transferAmount = attacker.remainingHealth / 2;
for (int i = 0; i < 5; i++) {
// I will modify the character so I use alias operator.
// I can also use address and pointers. See Dwarf's special skill for such example
Character& c = attackerCommunity->at(i);
if (c.type == "Hobbit") {
c.remainingHealth += transferAmount;
c.healthHistory[round] = c.remainingHealth;
} else if (c.type == "Elves") {
c.remainingHealth -= transferAmount;
c.nRoundsSinceSpecial = 0;
}
}
} else if (attacker.type == "Dwarfs" && attacker.nRoundsSinceSpecial >= 20) {
extraDamagePoint = attacker.attack - defender.defense;
for (int i = 0; i < 5; i++) {
// I will modify c and obtain its pointer.
Character* c = &(attackerCommunity->at(i));
if (c->type == "Dwarfs") {
c->nRoundsSinceSpecial = 0;
}
}
} else if (attacker.type == "Wizards" && attacker.nRoundsSinceSpecial >= 50 && idxLastDeadAttacker != -1) {
attackerCommunity->at(idxLastDeadAttacker).isAlive = true;
attackerCommunity->at(idxLastDeadAttacker).remainingHealth = attackerCommunity->at(idxLastDeadAttacker).healthHistory[0];
attackerCommunity->at(idxLastDeadAttacker).nRoundsSinceSpecial = 0;
for (int i = 0; i < 5; i++) {
Character* c = &((*attackerCommunity)[i]);
if (c->type == "Wizards") {
c->nRoundsSinceSpecial = 0;
}
}
}
}

// Finally, do the attack!
int damagePoint = max(attacker.attack - defender.defense + extraDamagePoint, 0);
for (int i = 0; i < 5; i++) {
Character& c = defenderCommunity->at(i);
if (defender.name == c.name) {
c.remainingHealth = max(c.remainingHealth - damagePoint, 0);
c.isAlive = c.remainingHealth > 0;
if (!c.isAlive) {
idxLastDeadDefender = i;
}
}
}

// Bookkeeping
updateHealthHistory(community1, round);
updateHealthHistory(community2, round);
// Move to next round.
updateNRoundsSinceSpecial(community1);
updateNRoundsSinceSpecial(community2);
ifWarContinues = warContinues(*defenderCommunity);
swap(attackerCommunity, defenderCommunity);
swap(idxLastDeadAttacker, idxLastDeadDefender);
round++;
}
round--;
infile.close();

ofstream outfile;
outfile.open(argv[2]);

if (ifWarContinues) {
outfile << "Draw" << endl;
} else if (round % 2 == 1) {
outfile << "Community-1" << endl;
} else {
outfile << "Community-2" << endl;
}

outfile << round << endl;
int nCasualties = 0;
for (int i = 0; i < 5; i++) {
Character c1 = community1[i];
Character c2 = community2[i];
if (!c1.isAlive) {
nCasualties += 1;
}
if (!c2.isAlive) {
nCasualties += 1;
}
}

outfile << nCasualties << endl;

printCommunity(outfile, community1, round);
printCommunity(outfile, community2, round);

return 0;
}
Loading

0 comments on commit cb96474

Please sign in to comment.