// Test.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
enum TroopType
{
TYPE_INVALID,
TYPE_BARBARIN,
TYPE_ARCHER,
TYPE_GIANT,
TYPE_GOBLIN,
TYPE_WALLBREAKER,
TYPE_BALLOON,
TYPE_WIZARD,
TYPE_HEALER,
TYPE_DRAGON,
TYPE_PEKKA,
};
int GetTroopCapacity(TroopType t)
{
switch (t)
{
case TYPE_BARBARIN: return 1; break;
case TYPE_ARCHER: return 1; break;
case TYPE_GIANT: return 5; break;
case TYPE_GOBLIN: return 1; break;
case TYPE_WALLBREAKER: return 2; break;
case TYPE_BALLOON: return 5; break;
case TYPE_WIZARD: return 4; break;
case TYPE_HEALER: return 14; break;
case TYPE_DRAGON: return 20; break;
case TYPE_PEKKA: return 25; break;
}
return -1;
};
int GetTroopBuildTimeSec(TroopType t)
{
switch (t)
{
case TYPE_BARBARIN: return 20; break;
case TYPE_ARCHER: return 25; break;
case TYPE_GIANT: return 120; break;
case TYPE_GOBLIN: return 30; break;
case TYPE_WALLBREAKER: return 120; break;
case TYPE_BALLOON: return 480; break;
case TYPE_WIZARD: return 480; break;
case TYPE_HEALER: return 900; break;
case TYPE_DRAGON: return 1800; break;
case TYPE_PEKKA: return 2700; break;
}
return -1;
};
string GetTroopName(TroopType t)
{
switch (t)
{
case TYPE_BARBARIN: return "Barbarian"; break;
case TYPE_ARCHER: return "Archer"; break;
case TYPE_GIANT: return "Giant"; break;
case TYPE_GOBLIN: return "Healer"; break;
case TYPE_WALLBREAKER: return "Wall Breaker"; break;
case TYPE_BALLOON: return "Balloon"; break;
case TYPE_WIZARD: return "Wizard"; break;
case TYPE_HEALER: return "Healer"; break;
case TYPE_DRAGON: return "Dragon"; break;
case TYPE_PEKKA: return "Pekka"; break;
}
return "";
};
struct Troop
{
TroopType type;
int quantity;
Troop(TroopType t, int qty)
{
type = t;
quantity = qty;
}
Troop()
{
type = TYPE_INVALID;
quantity = 0;
}
};
struct Barracks
{
int currentQueueTimeSec;
int currentCapacity;
int totalCapacity;
vector<Troop> queuedTroops;
Barracks(int capacity)
{
currentQueueTimeSec = 0;
currentCapacity = 0;
totalCapacity = capacity;
}
Barracks()
{
currentQueueTimeSec = 0;
currentCapacity = 0;
totalCapacity = 0;
}
int AvailableSpace()
{
return (totalCapacity - currentCapacity);
}
void Queue(TroopType t)
{
if (AvailableSpace() >= GetTroopCapacity(t))
{
bool exists = false;
for (int i = 0; i < queuedTroops.size(); i++)
{
if (t == queuedTroops[i].type)
{
queuedTroops[i].quantity++;
exists = true;
}
}
if (!exists)
{
queuedTroops.push_back(Troop(t, 1));
}
currentCapacity += GetTroopCapacity(t);
currentQueueTimeSec += GetTroopBuildTimeSec(t);
}
}
};
vector<Barracks> ActiveBarracks;
vector<Troop> ArmyCompList;
//Tweak the variables here to see the example.
void ExampleSetup()
{
//Establish the number of barracks and their capacities
ActiveBarracks.push_back(Barracks(75));
ActiveBarracks.push_back(Barracks(75));
ActiveBarracks.push_back(Barracks(75));
ActiveBarracks.push_back(Barracks(75));
ArmyCompList.push_back(Troop(TYPE_ARCHER, 20));
ArmyCompList.push_back(Troop(TYPE_HEALER, 3));
ArmyCompList.push_back(Troop(TYPE_GIANT , 14));
ArmyCompList.push_back(Troop(TYPE_WIZARD, 23));
ArmyCompList.push_back(Troop(TYPE_WALLBREAKER, 8));
ArmyCompList.push_back(Troop(TYPE_DRAGON, 1));
//ArmyCompList.push_back(Troop(TYPE_PEKKA, 2));
//ArmyCompList.push_back(Troop(TYPE_DRAGON, 1));
//ArmyCompList.push_back(Troop(TYPE_BALLOON, 5));
//ArmyCompList.push_back(Troop(TYPE_GIANT, 5));
//ArmyCompList.push_back(Troop(TYPE_WIZARD, 5));
//ArmyCompList.push_back(Troop(TYPE_WALLBREAKER, 8));
//ArmyCompList.push_back(Troop(TYPE_ARCHER, 20));
}
//Checks if the test about to be performed is valid. you can not queue up more troops than what you have the capacity for
bool ValidSetup()
{
int totalCapacity = 0;
for (int i = 0; i < ActiveBarracks.size(); i++)
{
totalCapacity += ActiveBarracks[i].totalCapacity;
}
int totalQueue = 0;
for (int i = 0; i < ArmyCompList.size(); i++)
{
totalQueue += ArmyCompList[i].quantity * GetTroopCapacity(ArmyCompList[i].type);
}
return totalQueue <= totalCapacity;
}
int main()
{
//setup the example run
ExampleSetup();
//Check conditions of test
if (!ValidSetup())
{
printf("ERROR: You've queued up more than possible!\n");
return 1;
}
//Sort based off of time. Longest to shortest. Uses the STL sort algorithm with the lambda function to compare build times.
std::sort(ArmyCompList.begin(), ArmyCompList.end(), [](const Troop &lhs, const Troop &rhs)
{
return GetTroopBuildTimeSec(lhs.type) > GetTroopBuildTimeSec(rhs.type);
});
//perform the queing algorithm
while (ArmyCompList.size() > 0)
{
//Get the first troop!
int curTroopCapacity = GetTroopCapacity(ArmyCompList[0].type);
//Loop through the barracks, find the lowest capacity barrack right now
int barrackIdx = -1; //save off the index for use later
int leastTime = 99999; //start the time off with a very high number for the test
for (int i = 0; i < ActiveBarracks.size(); i++)
{
int time = ActiveBarracks[i].currentQueueTimeSec;
int space = ActiveBarracks[i].AvailableSpace();
//Check if this barrack has the smallest current build time AND that it has the capacity to queue the troop in question
if (time < leastTime && space >= curTroopCapacity)
{
barrackIdx = i;
leastTime = time;
}
}
//Something went wrong if this was hit... it should not have been hit assuming the ValidSetup() function call was performed correctly
if (barrackIdx == -1)
{
printf("Error occured, whups!\n");
return 0;
}
//Queue 1 troop into the best barrack
ActiveBarracks[barrackIdx].Queue(ArmyCompList[0].type);
ArmyCompList[0].quantity--;
//if the remaining quantity is 0, then remove it from the composition list
if (ArmyCompList[0].quantity <= 0)
{
ArmyCompList.erase(ArmyCompList.begin());
}
}
//Print the results to the console
for (int i = 0; i < ActiveBarracks.size(); i++)
{
printf("-----------\n");
printf("Barrack #%d - Build Time: %d, Capacity: %d\n", i, ActiveBarracks[i].currentQueueTimeSec, ActiveBarracks[i].currentCapacity);
for (int j = 0; j < ActiveBarracks[i].queuedTroops.size(); j++)
{
string name = GetTroopName(ActiveBarracks[i].queuedTroops[j].type);
int qty = ActiveBarracks[i].queuedTroops[j].quantity;
printf("\tTroop %s, qty %d\n", name.c_str(), qty);
}
printf("\n");
}
//Exit successfully
return 0;
}