#include <iostream> //cin cout
#include <vector> //vector
#include <ctime> //time() for srand()
#include <cstdlib> //rand()
using namespace std;
class Plyr
{
public:
string name;
int max;
int min;
int classlol;
int specid;
Plyr(string name1,int rating1,int drop1,string classlol1,string specid1)
{
name = name1;
max = rating1 + 100;
min = rating1 - 100 * (drop1 + 1);
if (classlol1=="priest")
classlol = 0;
else if (classlol1=="druid")
classlol = 1;
else if (classlol1=="paladin")
classlol = 2;
else if (classlol1=="shaman")
classlol = 3;
else if (classlol1=="hunter")
classlol = 4;
else if (classlol1=="warrior")
classlol = 5;
else if (classlol1=="rogue")
classlol = 6;
else if (classlol1=="deathknight")
classlol = 7;
else if (classlol1=="warlock")
classlol = 8;
else if (classlol1=="mage")
classlol = 9;
else
classlol = -1;
// healerspecs first then the rest otherwise matchuptonumber function will produce higher numbers
if (specid1=="discpri")
specid = 0;
else if (specid1=="hpal")
specid = 1;
else if (specid1=="rsham")
specid = 2;
else if (specid1=="rdru")
specid = 3;
else if (specid1=="holypri")
specid = 4;
else if (specid1=="protpalheal")
specid = 5;
else if (specid1=="shadowpri")
specid = 6;
else if (specid1=="protpaldd")
specid = 7;
else if (specid1=="retripal")
specid = 8;
else if (specid1=="feraldru")
specid = 9;
else if (specid1=="moonkindru")
specid = 10;
else if (specid1=="elesham")
specid = 11;
else if (specid1=="enhsham")
specid = 12;
else if (specid1=="armswar")
specid = 13;
else if (specid1=="protwar")
specid = 14;
else if (specid1=="furywar")
specid = 15;
else if (specid1=="unholydk")
specid = 16;
else if (specid1=="frostdk")
specid = 17;
else if (specid1=="bloodk")
specid = 18;
else if (specid1=="mmhunt")
specid = 19;
else if (specid1=="survhunt")
specid = 20;
else if (specid1=="bmhunt")
specid = 21;
else if (specid1=="sdrogue")
specid = 22;
else if (specid1=="mutirogue")
specid = 23;
else if (specid1=="combatrogue")
specid = 24;
else if (specid1=="frostmage")
specid = 25;
else if (specid1=="firemage")
specid = 26;
else if (specid1=="arcanemage")
specid = 27;
else if (specid1=="afflilock")
specid = 28;
else if (specid1=="demolock")
specid = 29;
else if (specid1=="destrolock")
specid = 30;
else
specid = -1;
if (specid == -1 || classlol == -1)
cout<<"YOU BLIND MORON "<<classlol<<" "<<specid<<endl;
}
};
class Matchup
{
public:
string dd1name;
string dd2name;
string heal1name;
string dd3name;
string dd4name;
string heal2name;
Matchup(string d1name,string d2name,string h1name,string d3name,string d4name,string h2name)
{
dd1name = d1name;
dd2name = d2name;
heal1name = h1name;
dd3name = d3name;
dd4name = d4name;
heal2name = h2name;
}
};
int globalcount;
bool queuechanged = true;
bool queuefound = false;
const long bannedmatchupnumbers[] = {
1000000,1000001,1000002,1000003,1000004,1000005,10 00006,1000007,1000008,1000009,1000010,1000011,1000 012,1000013,
2000000,2000001,2000002,2000003,2000004,2000005,20 00006,2000007,2000008,2000009,2000010,2000011,2000 012,2000013,
3000000,3000001,3000002,3000003,3000004,3000005,30 00006,3000007,3000008,3000009,3000010,3000011,3000 012,3000013,
4000000,4000001,4000002,4000003,4000004,4000005,40 00006,4000007,4000008,4000009,4000010,4000011,4000 012,4000013,
5000000,5000001,5000002,5000003,5000004,5000005,50 00006,5000007,5000008,5000009,5000010,5000011,5000 012,5000013,
6000000,6000001,6000002,6000003,6000004,6000005,60 00006,6000007,6000008,6000009,6000010,6000011,6000 012,6000013,
7000000,7000001,7000002,7000003,7000004,7000005,70 00006,7000007,7000008,7000009,7000010,7000011,7000 012,7000013,
8000000,8000001,8000002,8000003,8000004,8000005,80 00006,8000007,8000008,8000009,8000010,8000011,8000 012,8000013,
9000000,9000001,9000002,9000003,9000004,9000005,90 00006,9000007,9000008,9000009,9000010,9000011,9000 012,9000013
}; // just blanket numbers, probably none of those are equal to a real matchcomb id. it has to be sorted
vector<Matchup> viablematchups;
vector<long> uniquematchupsfound;
vector<Plyr> erasedlist;
void printlist(vector<Plyr> &list,char param)
{
if (param=='d')
cout<<"\nQueued DD:"<<endl;
else if (param=='h')
cout<<"\nQueued Healers:"<<endl;
for (int i=0; i<list.size(); i++)
cout<<list[i].name<<endl;
cout<<endl;
}
long matchuptonumber(int d1, int d2, int h1, int d3, int d4, int h2)
{
long res;
int t1,t2;
if (d1>d2) //war dk hpal is the same as dk war hpal
t1 = d1+d2*25+h1*625; //this is why healer specids should go first, so max possible value of t1 is much less
else
t1 = d1*25+d2+h1*625; //25 is the abount of different dps specids, 24*25+24=624
if (d3>d4)
t2 = d3+d4*25+h2*625;
else
t2 = d3*25+d4+h2*625;
if (t1>t2) //war dk hpal - rog mag rdru is the same as rog mag rdru - war dk hpal
res = t1+t2*3750; //max possible value of t1/t2 is 24+24*25+5*625=3749
else if (t1<t2)
res = t1*3750+t2;
else
res = 0; //this means it's a mirror
return res; //max possible return value is 3749*3750+3749=14062499
}
// will do search in sorted array size of n=max-min in only log2(n) steps
void lnsearch(long x,int min, int max,bool &foundlol)
{
if (min<max)
if (x < bannedmatchupnumbers[(min+max)/2])
lnsearch(x,min,(min+max)/2-1,foundlol);
else if (x > bannedmatchupnumbers[(min+max)/2])
lnsearch(x,(min+max)/2+1,max,foundlol);
else
foundlol = true;
else if (min==max)
if (x == bannedmatchupnumbers[min])
foundlol = true;
}
void savematchup(const Plyr &d1,const Plyr &d2,const Plyr &h1,const Plyr &d3,const Plyr &d4,const Plyr &h2)
{
viablematchups.push_back(Matchup(d1.name,d2.name,h 1.name,d3.name,d4.name,h2.name));
}
void matchupcheck(const Plyr &d1,const Plyr &d2,const Plyr &h1,const Plyr &d3,const Plyr &d4,const Plyr &h2)
{
if (d1.classlol == d2.classlol || d1.classlol == h1.classlol || d2.classlol == h1.classlol ||
d3.classlol == d4.classlol || d3.classlol == h2.classlol || d4.classlol == h2.classlol)
return; // only 1 of each class in a team
long z = matchuptonumber(d1.specid,d2.specid,h1.specid,d3.s pecid,d4.specid,h2.specid);
int num = sizeof(bannedmatchupnumbers) / sizeof(bannedmatchupnumbers[0]);
bool foundlol = false;
lnsearch(z,0,num-1,foundlol);
if (!foundlol)
{
bool isunique = true;
for (int i=0; i<uniquematchupsfound.size(); i++)
{
if (uniquematchupsfound[i] == z)
isunique = false;
}
if (isunique)
{
globalcount++;
uniquematchupsfound.push_back(z);
}
savematchup(d1,d2,h1,d3,d4,h2);
}
}
//covers all possible matchup combinations of 6 given players
void matchup6analisys(const Plyr &d1,const Plyr &d2,const Plyr &d3,const Plyr &d4,const Plyr &h1,const Plyr &h2)
{
matchupcheck(d1,d2,h1,d3,d4,h2);
matchupcheck(d1,d2,h2,d3,d4,h1);
matchupcheck(d1,d3,h1,d2,d4,h2);
matchupcheck(d1,d3,h2,d2,d4,h1);
matchupcheck(d1,d4,h1,d2,d3,h2);
matchupcheck(d1,d4,h2,d2,d3,h1);
}
void searchViableMatchups(const vector<Plyr> &list,int flag,int k,int i1,int i2,int i3,int i4,const Plyr &h1,const Plyr &h2)
{
if (globalcount > 1) //2 is the minimum amount of possible unique matchups required for queue to pop
return;
matchup6analisys(list[i1],list[i2],list[i3],list[i4],h1,h2);
if (list.size()>4+k)
{
k++;
searchViableMatchups(list,1,k,i1,i2,i3,3+k,h1,h2);
if (flag >= 2)
searchViableMatchups(list,2,k,i1,i2,i4,3+k,h1,h2);
if (flag >= 3)
searchViableMatchups(list,3,k,i1,i3,i4,3+k,h1,h2);
if (flag == 4)
searchViableMatchups(list,4,k,i2,i3,i4,3+k,h1,h2);
}
}
int ddlistcheck(const vector<Plyr> &list,const Plyr &h1,const Plyr &h2)
{
int res=0;
int speccount[25]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0};
vector<Plyr> viableddlist;
for (int i=0; i<list.size(); i++)
{
int maxposspecs=2;
if (list[i].classlol == h1.classlol || list[i].classlol == h2.classlol)
maxposspecs--;
if (speccount[list[i].specid-6]<maxposspecs && list[i].max >= max(h1.min,h2.min) and list[i].min <= min(h1.max,h2.max))
{
speccount[list[i].specid-6]++;
viableddlist.push_back(list[i]);
}
if (viableddlist.size() >= 48)
break;
}
globalcount = 0;
uniquematchupsfound.clear();
if (viableddlist.size() >= 4)
searchViableMatchups(viableddlist,4,0,0,1,2,3,h1,h 2);
if (globalcount > 1)
return 1;
else
return 0;
}
void erasebyname(vector<Plyr> &list,string name1)
{
for (int i=0; i<list.size(); i++)
if (list[i].name == name1)
{
erasedlist.push_back(list[i]);
list.erase(list.begin()+i);
}
queuechanged = true;
}
void requeueerased(vector<Plyr> &hlist,vector<Plyr> &dlist)
{
for (int i=0; i<erasedlist.size(); i++)
{
if (erasedlist[i].specid<=5)
hlist.push_back(erasedlist[i]);
else
dlist.push_back(erasedlist[i]);
}
erasedlist.clear();
queuechanged = true;
}
void popqueue(vector<Plyr> &hlist,vector<Plyr> &dlist)
{
cout<<"\nViable Matchups found:"<<endl;
for (int i=0; i<viablematchups.size(); i++)
{
cout<<viablematchups[i].dd1name<<" "<<viablematchups[i].dd2name<<" "<<viablematchups[i].heal1name<<" - "<<
viablematchups[i].dd3name<<" "<<viablematchups[i].dd4name<<" "<<viablematchups[i].heal2name<<endl;
}
cout<<endl;
int chosenindex = rand() % viablematchups.size(); //once we got more than 2 possible matchups, choose one of them
string d1name = viablematchups[chosenindex].dd1name;
string d2name = viablematchups[chosenindex].dd2name;
string h1name = viablematchups[chosenindex].heal1name;
string d3name = viablematchups[chosenindex].dd3name;
string d4name = viablematchups[chosenindex].dd4name;
string h2name = viablematchups[chosenindex].heal2name;
cout<<"Chosen Matchup: \n"<<d1name<<" "<<d2name<<" "<<h1name<<" - "<<d3name<<" "<<d4name<<" "<<h2name<<endl<<endl;
//cout<<d1name<<" "<<d2name<<" "<<h1name<<" - "<<d3name<<" "<<d4name<<" "<<h2name<<endl;
viablematchups.clear();
erasebyname(dlist,d1name); //remove players from queue
erasebyname(dlist,d2name);
erasebyname(dlist,d3name);
erasebyname(dlist,d4name);
erasebyname(hlist,h1name);
erasebyname(hlist,h2name);
}
void healerlistcheck(const vector<Plyr> &hlist,const vector<Plyr> &dlist)
{
for (int i=1; i<hlist.size(); i++) //the cycle is organized to go 01 02 12 03 13 23 04 14 24 34 and so on
{
for (int j=0; j<i; j++)
{
if (hlist[i].max >= hlist[j].min and hlist[i].min <= hlist[j].max)
{
int res = ddlistcheck(dlist,hlist[i],hlist[j]);
if (res)
{
queuefound = true;
return;
}
}
}
}
}
void filltest1(vector<Plyr> &hlist,vector<Plyr> &dlist)
{
hlist.push_back(Plyr("punter",3055,1,"shaman","rsh am"));
hlist.push_back(Plyr("drass",2854,0,"druid","rdru" ));
hlist.push_back(Plyr("next",2880,0,"paladin","hpal "));
hlist.push_back(Plyr("raint",2935,1,"druid","rdru" ));
hlist.push_back(Plyr("seasun",2822,0,"druid","rdru "));
hlist.push_back(Plyr("soumi",2946,2,"priest","disc pri"));
hlist.push_back(Plyr("oddwafle",2914,1,"priest","d iscpri"));
dlist.push_back(Plyr("worldsbest",2444,0,"rogue"," sdrogue"));
dlist.push_back(Plyr("ripzy",2988,1,"warlock","aff lilock"));
dlist.push_back(Plyr("simba",3088,2,"druid","feral dru"));
dlist.push_back(Plyr("khrystal",3022,1,"priest","s hadowpri"));
dlist.push_back(Plyr("merce",2988,1,"warlock","des trolock"));
dlist.push_back(Plyr("onlysd",2444,0,"rogue","sdro gue"));
dlist.push_back(Plyr("touptite",2849,0,"warlock"," afflilock"));
dlist.push_back(Plyr("homerjay",2812,0,"hunter","m mhunt"));
dlist.push_back(Plyr("sebii",2916,1,"warrior","pro twar"));
dlist.push_back(Plyr("swepy",2714,0,"warrior","arm swar"));
dlist.push_back(Plyr("preghera",2717,1,"paladin"," retripal"));
dlist.push_back(Plyr("batysasai",2666,0,"deathknig ht","unholydk"));
dlist.push_back(Plyr("azk",2810,0,"hunter","mmhunt "));
dlist.push_back(Plyr("petosatana",2835,1,"shaman", "enhsham"));
dlist.push_back(Plyr("darthsotek",2788,0,"priest", "shadowpri"));
dlist.push_back(Plyr("slayermode",2777,1,"mage","f rostmage"));
dlist.push_back(Plyr("hanry",2705,0,"mage","frostm age"));
}
void filltest2(vector<Plyr> &hlist,vector<Plyr> &dlist)
{
hlist.push_back(Plyr("2.5hpal",2544,2,"paladin","h pal"));
hlist.push_back(Plyr("punter",3055,1,"shaman","rsh am"));
hlist.push_back(Plyr("2.2rdru",2264,3,"druid","rdr u"));
hlist.push_back(Plyr("2.5disc",2517,2,"priest","di scpri"));
hlist.push_back(Plyr("2.6disc",2644,1,"priest","di scpri"));
hlist.push_back(Plyr("drass",2854,0,"druid","rdru" ));
hlist.push_back(Plyr("1.8rsham",1790,3,"shaman","r sham"));
hlist.push_back(Plyr("next",2880,0,"paladin","hpal "));
hlist.push_back(Plyr("2.4rsham",2410,3,"shaman","r sham"));
hlist.push_back(Plyr("1.5rdru",1537,0,"druid","rdr u"));
hlist.push_back(Plyr("2.2hpal",2271,2,"paladin","h pal"));
hlist.push_back(Plyr("2.2disc",2177,2,"priest","di scpri"));
hlist.push_back(Plyr("raint",2935,1,"druid","rdru" ));
hlist.push_back(Plyr("2.1rsham",2090,1,"shaman","r sham"));
hlist.push_back(Plyr("1.3hpal",1374,5,"paladin","h pal"));
hlist.push_back(Plyr("seasun",2822,0,"druid","rdru "));
hlist.push_back(Plyr("1.5hpal",1516,1,"paladin","h pal"));
hlist.push_back(Plyr("2.6rdru",2588,1,"druid","rdr u"));
hlist.push_back(Plyr("soumi",2946,2,"priest","disc pri"));
hlist.push_back(Plyr("oddwafle",2914,1,"priest","d iscpri"));
hlist.push_back(Plyr("2.3hpal",2333,2,"paladin","h pal"));
hlist.push_back(Plyr("1.8hpal",1844,1,"paladin","h pal"));
hlist.push_back(Plyr("1.5disc",1488,3,"priest","di scpri"));
hlist.push_back(Plyr("1.9rdru",1888,0,"druid","rdr u"));
hlist.push_back(Plyr("1.7rsham",1750,3,"shaman","r sham"));
hlist.push_back(Plyr("1.8disc",1817,2,"priest","di scpri"));
hlist.push_back(Plyr("1.9disc",1947,1,"priest","di scpri"));
dlist.push_back(Plyr("worldsbest",2444,3,"rogue"," sdrogue"));
dlist.push_back(Plyr("1.8arms",1845,3,"warrior","a rmswar"));
dlist.push_back(Plyr("ripzy",2988,2,"warlock","aff lilock"));
dlist.push_back(Plyr("1.6lock",1644,2,"warlock","a fflilock"));
dlist.push_back(Plyr("simba",3088,2,"druid","feral dru"));
dlist.push_back(Plyr("1.5rog",1477,4,"rogue","sdro gue"));
dlist.push_back(Plyr("1.6ele",1615,3,"shaman","ele sham"));
dlist.push_back(Plyr("2.6hunt",2625,2,"hunter","mm hunt"));
dlist.push_back(Plyr("khrystal",3022,1,"priest","s hadowpri"));
dlist.push_back(Plyr("slayermode",2777,1,"mage","f rostmage"));
dlist.push_back(Plyr("merce",2988,1,"warlock","des trolock"));
dlist.push_back(Plyr("2.0hunt",2033,2,"hunter","mm hunt"));
dlist.push_back(Plyr("onlysd",2444,3,"rogue","sdro gue"));
dlist.push_back(Plyr("1.7shpr",1695,1,"priest","sh adowpri"));
dlist.push_back(Plyr("touptite",2849,1,"warlock"," afflilock"));
dlist.push_back(Plyr("1.9mag",1870,2,"mage","frost mage"));
dlist.push_back(Plyr("1.3rog",1324,2,"rogue","sdro gue"));
dlist.push_back(Plyr("2.6dk",2577,2,"deathknight", "unholydk"));
dlist.push_back(Plyr("homerjay",2812,0,"hunter","m mhunt"));
dlist.push_back(Plyr("1.8lock",1777,3,"warlock","a fflilock"));
dlist.push_back(Plyr("sebii",2916,2,"warrior","pro twar"));
dlist.push_back(Plyr("2.4dk",2405,2,"deathknight", "unholydk"));
dlist.push_back(Plyr("1.5mag",1489,2,"mage","frost mage"));
dlist.push_back(Plyr("1.9hunt",1921,3,"hunter","mm hunt"));
dlist.push_back(Plyr("2.4retri",2462,1,"paladin"," retripal"));
dlist.push_back(Plyr("2.3dk",2354,3,"deathknight", "unholydk"));
dlist.push_back(Plyr("1.8ele",1855,2,"shaman","ele sham"));
dlist.push_back(Plyr("swepy",2714,0,"warrior","arm swar"));
dlist.push_back(Plyr("2.5shpr",2481,2,"priest","sh adowpri"));
dlist.push_back(Plyr("2.2dk",2177,3,"deathknight", "unholydk"));
dlist.push_back(Plyr("2.6arms",2628,1,"warrior","a rmswar"));
dlist.push_back(Plyr("2.4mag",2389,2,"mage","frost mage"));
dlist.push_back(Plyr("2.6retri",2645,2,"paladin"," retripal"));
dlist.push_back(Plyr("2.0lock",1980,3,"warlock","a fflilock"));
dlist.push_back(Plyr("preghera",2717,1,"paladin"," retripal"));
dlist.push_back(Plyr("1.9ele",1945,2,"shaman","ele sham"));
dlist.push_back(Plyr("1.6feral",1677,2,"druid","fe raldru"));
dlist.push_back(Plyr("batysasai",2666,0,"deathknig ht","unholydk"));
dlist.push_back(Plyr("2.6lock",2584,1,"warlock","a fflilock"));
dlist.push_back(Plyr("2.5arms",2521,1,"warrior","a rmswar"));
dlist.push_back(Plyr("2.2retri",2217,2,"paladin"," retripal"));
dlist.push_back(Plyr("azk",2810,1,"hunter","mmhunt "));
dlist.push_back(Plyr("2.4feral",2388,2,"druid","fe raldru"));
dlist.push_back(Plyr("petosatana",2835,1,"shaman", "enhsham"));
dlist.push_back(Plyr("2.1arms",2104,4,"warrior","a rmswar"));
dlist.push_back(Plyr("1.8retri",1855,2,"paladin"," retripal"));
dlist.push_back(Plyr("1.7dk",1754,2,"deathknight", "unholydk"));
dlist.push_back(Plyr("2.3lock",2341,1,"warlock","a fflilock"));
dlist.push_back(Plyr("1.6arms",1578,2,"warrior","a rmswar"));
dlist.push_back(Plyr("2.6ele",2667,1,"shaman","ele sham"));
dlist.push_back(Plyr("darthsotek",2788,0,"priest", "shadowpri"));
dlist.push_back(Plyr("2.1shpr",2148,2,"priest","sh adowpri"));
dlist.push_back(Plyr("2.5hunt",2541,1,"hunter","mm hunt"));
dlist.push_back(Plyr("1.6retri",1634,3,"paladin"," retripal"));
dlist.push_back(Plyr("1.7rog",1727,2,"rogue","sdro gue"));
dlist.push_back(Plyr("2.4ele",2372,2,"shaman","ele sham"));
dlist.push_back(Plyr("hanry",2705,0,"mage","frostm age"));
dlist.push_back(Plyr("1.6hunt",1597,2,"hunter","mm hunt"));
}
int main()
{
string incstr;
srand(time(0));
vector<Plyr> healerlist;
vector<Plyr> ddlist;
filltest2(healerlist,ddlist);
while(true)
{
cout << "->";
cin >> incstr;
if (incstr=="next")
{
if (queuechanged)
{
healerlistcheck(healerlist,ddlist);
queuechanged = false;
}
else
cout<<"\nQueue didn't change since last time"<<endl<<endl;
if (queuefound)
{
popqueue(healerlist,ddlist);
queuefound = false;
}
else
cout<<"\nNo viable matchups for queue were found"<<endl<<endl;
}
if (incstr=="go")
{
while(true)
{
bool shouldstop = false;
if (queuechanged)
{
healerlistcheck(healerlist,ddlist);
queuechanged = false;
}
else
cout<<"\nQueue didn't change since last time"<<endl<<endl;
if (!queuefound)
shouldstop = true;
if (queuefound)
{
popqueue(healerlist,ddlist);
queuefound = false;
}
else
cout<<"\nNo viable matchups for queue were found"<<endl<<endl;
if (shouldstop)
break;
}
}
if (incstr=="req")
{
requeueerased(healerlist,ddlist);
}
if (incstr=="ddlist")
{
printlist(ddlist,'d');
}
if (incstr=="hlist")
{
printlist(healerlist,'h');
}
if (incstr=="elist")
{
printlist(erasedlist,'1');
}
if (incstr=="exit")
break;
}
return 0;
}