SlideShare a Scribd company logo
//Ifgqueue.h
#ifndef LFGQUEUE_H
#define LFGQUEUE_H
#include "player.h"
class LFGQueue
{
public:
LFGQueue(int scrimmage_threshold);
void add_player(Player* p);
bool remove_next_group(Player** players);
bool remove_next_scrimmage(Player** players);
int player_count();
int position(Player* p);
private:
class Node
{
public:
Player* p;
Node* next;
Node* prev;
};
void remove_node(Node* n);
Node* head;
Node* tail;
int scrimmage_threshold;
int count;
};
#endif
//**************************************************************************
//main.cpp
#include
#include
#include
#include
#include
#include "lfgqueue.h"
using namespace std;
void permute(Player** players, int len)
{
for (int i = 0; i < len; ++i)
swap(players[i], players[i + rand() % (len-i)]);
}
int main()
{
// Setup for testing
srand(2017);
Player* group[3];
Player* scrimmage[6];
Player daria("Daria", Player::Defender);
Player daniela("Daniela", Player::Defender);
Player diego("Diego", Player::Defender);
Player hector("Hector", Player::Hunter);
Player hugo("Hugo", Player::Hunter);
Player henri("Henri", Player::Hunter);
Player berta("Berta", Player::Bard);
Player bernardo("Bernardo", Player::Bard);
Player brigida("Brigida", Player::Bard);
// Test that everything compiles and queues
// construct without issue.
LFGQueue q1(3);
// Test when queue contains a single complete group in
// in an undesired order (Bard, Hunter, Defender)
q1.add_player(&bernardo);
q1.add_player(&hugo);
q1.add_player(&daria);
assert(q1.player_count() == 3);
assert(q1.position(&bernardo) == 1);
assert(q1.position(&hugo) == 2);
assert(q1.position(&daria) == 3);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daria);
assert(group[0]->name == "Daria");
assert(group[0]->role == Player::Defender);
assert(group[1] == &hugo);
assert(group[1]->name == "Hugo");
assert(group[1]->role == Player::Hunter);
assert(group[2] == &bernardo);
assert(group[2]->name == "Bernardo");
assert(group[2]->role == Player::Bard);
assert(q1.player_count() == 0);
cout << "20% earned." << endl;
// Test what happens when not enough group
group[0] = group[1] = group[2] = 0;
assert(!q1.remove_next_group(group));
assert(group[0] == 0);
assert(group[1] == 0);
assert(group[2] == 0);
for (int i = 0; i < 6; ++i)
scrimmage[i] = 0;
assert(!q1.remove_next_scrimmage(scrimmage));
for (int i = 0; i < 6; ++i)
assert(scrimmage[i] == 0);
cout << "25% earned." << endl;
// Test what happens when two full groups of players
// not in the right order (Def, Hunt, Hunt, Bard, Bard, Def)
q1.add_player(&daria);
q1.add_player(&hector);
q1.add_player(&hugo);
q1.add_player(&bernardo);
q1.add_player(&berta);
q1.add_player(&daniela);
assert(q1.player_count() == 6);
assert(q1.position(&daria) == 1);
assert(q1.position(&hector) == 2);
assert(q1.position(&hugo) == 3);
assert(q1.position(&bernardo) == 4);
assert(q1.position(&berta) == 5);
assert(q1.position(&daniela) == 6);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daria);
assert(group[1] == &hector);
assert(group[2] == &bernardo);
assert(q1.player_count() == 3);
assert(q1.position(&hugo) == 1);
assert(q1.position(&berta) == 2);
assert(q1.position(&daniela) == 3);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daniela);
assert(group[1] == &hugo);
assert(group[2] == &berta);
assert(q1.player_count() == 0);
group[0] = group[1] = group[2] = 0;
assert(!q1.remove_next_group(group));
assert(group[0] == 0);
assert(group[1] == 0);
assert(group[2] == 0);
cout << "40% earned." << endl;
// Test what happens when queue reaches enough for a scrimmage
// (6 players past max size of 3)
q1.add_player(&daria);
q1.add_player(&daniela);
q1.add_player(&diego);
q1.add_player(&hector);
q1.add_player(&hugo);
q1.add_player(&henri);
q1.add_player(&berta);
q1.add_player(&bernardo);
assert(q1.player_count() == 8);
for (int i = 0; i < 6; ++i)
scrimmage[i] = 0;
assert(!q1.remove_next_scrimmage(scrimmage));
for (int i = 0; i < 6; ++i)
assert(scrimmage[i] == 0);
q1.add_player(&brigida);
assert(q1.position(&daria) == 1);
assert(q1.position(&daniela) == 2);
assert(q1.position(&diego) == 3);
assert(q1.position(&hector) == 4);
assert(q1.position(&hugo) == 5);
assert(q1.position(&henri) == 6);
assert(q1.position(&berta) == 7);
assert(q1.position(&bernardo) == 8);
assert(q1.position(&brigida) == 9);
assert(q1.player_count() == 9);
assert(q1.remove_next_scrimmage(scrimmage));
assert(scrimmage[0] == &hector);
assert(scrimmage[1] == &hugo);
assert(scrimmage[2] == &henri);
assert(scrimmage[3] == &berta);
assert(scrimmage[4] == &bernardo);
assert(scrimmage[5] == &brigida);
assert(q1.player_count() == 3);
assert(q1.position(&daria) == 1);
assert(q1.position(&daniela) == 2);
assert(q1.position(&diego) == 3);
cout << "65% earned." << endl;
// Make a queue with 3000 players:
// 1000xDefenders, 1000xHunters,
// 1000xBards in a nice order
// and max size of 2000 players.
LFGQueue q2(2000);
Player** all = new Player*[3000];
ostringstream oss;
for (int i = 0; i < 3000; i += 3)
{
oss.str("");
oss << "Defender_" << i+1;
all[i] = new Player(oss.str(), Player::Defender);
oss.str("");
oss << "Hunter_" << i+2;
all[i+1] = new Player(oss.str(), Player::Hunter);
oss.str("");
oss << "Bard_" << i+3;
all[i+2] = new Player(oss.str(), Player::Bard);
}
for (int i = 0; i < 3000; ++i)
{
q2.add_player(all[i]);
assert(q2.player_count() == i+1);
}
// First, remove 1 scrimmage.
for (int j = 0; j < 6; ++j)
scrimmage[j] = 0;
assert(q2.remove_next_scrimmage(scrimmage));
assert(q2.player_count() == 3000 - 6);
assert(scrimmage[0]->name == "Defender_2995");
assert(scrimmage[0]->role == Player::Defender);
assert(scrimmage[1]->name == "Hunter_2996");
assert(scrimmage[1]->role == Player::Hunter);
assert(scrimmage[2]->name == "Bard_2997");
assert(scrimmage[2]->role == Player::Bard);
assert(scrimmage[3]->name == "Defender_2998");
assert(scrimmage[3]->role == Player::Defender);
assert(scrimmage[4]->name == "Hunter_2999");
assert(scrimmage[4]->role == Player::Hunter);
assert(scrimmage[5]->name == "Bard_3000");
assert(scrimmage[5]->role == Player::Bard);
cout << "70% earned." << endl;
// Now remove 165 more scrimmages
for (int i = 0; i < 165; ++i)
{
for (int j = 0; j < 6; ++j)
scrimmage[j] = 0;
assert(q2.remove_next_scrimmage(scrimmage));
assert(q2.player_count() == 3000 - 6 - 6*(i+1));
assert(scrimmage[0]->role == Player::Defender);
assert(scrimmage[1]->role == Player::Hunter);
assert(scrimmage[2]->role == Player::Bard);
assert(scrimmage[3]->role == Player::Defender);
assert(scrimmage[4]->role == Player::Hunter);
assert(scrimmage[5]->role == Player::Bard);
}
// Now 3000 - 166 * 6 = 2004 players remain
assert(!q2.remove_next_scrimmage(scrimmage));
// Now remove the rest of the queue as groups
group[0] = group[1] = group[2] = 0;
assert(q2.remove_next_group(group));
assert(q2.player_count() == 2001);
assert(group[0]->name == "Defender_1");
assert(group[0]->role == Player::Defender);
assert(group[1]->name == "Hunter_2");
assert(group[1]->role == Player::Hunter);
assert(group[2]->name == "Bard_3");
assert(group[2]->role == Player::Bard);
// (1 + 667) * 3 = 2004
for (int i = 0; i < 667; ++i)
{
group[0] = group[1] = group[2] = 0;
assert(q2.remove_next_group(group));
assert(q2.player_count() == 2001 - 3 * (i+1));
assert(group[0]->role == Player::Defender);
assert(group[1]->role == Player::Hunter);
assert(group[2]->role == Player::Bard);
}
assert(!q2.remove_next_group(group));
cout << "80% earned." << endl;
// Timing test. Make a queue with 3000000 players:
// 1000000xDefender, 1000000xHunter, 1000000xBard,
// in collections of shuffled 30 complete groups.
LFGQueue qt(100000);
const int timing_player_count = 1000000;
all = new Player*[timing_player_count];
for (int i = 0; i < timing_player_count; i += 3)
{
all[i] = new Player("Defender_???", Player::Defender);
all[i+1] = new Player("Hunter_???", Player::Hunter);
all[i+2] = new Player("Bard_???", Player::Bard);
}
for (int i = 0; i < timing_player_count; i += 30)
permute(&(all[i]), 30);
// Time how long it takes to add all players
clock_t start = clock();
for (int i = 0; i < timing_player_count; ++i)
qt.add_player(all[i]);
float duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count);
assert(duration < 2.0);
// Time how long it takes to form 10000 scrimmages
start = clock();
for (int i = 0; i < 10000; ++i)
assert(qt.remove_next_scrimmage(scrimmage));
duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count - 60000);
assert(duration < 0.1);
// Time how long it takes to form 10000 groups
start = clock();
for (int i = 0; i < 10000; ++i)
assert(qt.remove_next_group(group));
duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count - 60000 - 30000);
assert(duration < 0.1);
// Test removing a group correctly
group[0] = group[1] = group[2] = 0;
assert(qt.remove_next_group(group));
assert(group[0]->role == Player::Defender);
assert(group[1]->role == Player::Hunter);
assert(group[2]->role == Player::Bard);
cout << "100% earned." << endl;
}
//************************************************************************
//player.h
#ifndef PLAYER_H
#define PLAYER_H
#include
using namespace std;
class Player
{
public:
enum Role {Defender, Hunter, Bard};
Player(string name, Role role)
{
this->name = name;
this->role = role;
}
string name;
Role role;
};
#endif
//***********************************************************************
/*
Long queuing times are common in many games, leading to player boredom as they wait idly. As
a solution, many games have a “scrimmage” mode where players at the end of a long queue are
placed into large, unstructured groups to play a casual game.
Here you’ll add such a scrimmage feature to a “looking for group” queue. Whenever more than 6
additional players past the queue’s specified “threshold” size have joined the queue, the last such
6 players are removed from the queue and placed into a scrimmage (group) with no role
requirements.
Since reducing wait times is the entire purpose of this feature, it must run extremely quick and a
doubly linked list is needed. Since the feature is triggered only when the queue is larger than a
specified maximum size, the number of players in the queue must also be computed extremely
fast.
*/
Solution
Given below is the implementation of lfgqueue.cpp. Please use it along with other files from
question - lfgqueue.h, main.cpp, player.h. These files are not modified. The only new file is
lfgqueue.cpp. Output shown in the end. Please don't forget to rate the answer if it helped. Thank
you very much.
player.h
//************************************************************************
//player.h
#ifndef PLAYER_H
#define PLAYER_H
#include
using namespace std;
class Player
{
public:
enum Role {Defender, Hunter, Bard};
Player(string name, Role role)
{
this->name = name;
this->role = role;
}
string name;
Role role;
};
#endif
//***********************************************************************
/*
Long queuing times are common in many games, leading to player boredom as they wait idly.
As a solution, many games have a “scrimmage” mode where players at the end of a long queue
are placed into large, unstructured groups to play a casual game.
Here you’ll add such a scrimmage feature to a “looking for group” queue. Whenever more than
6 additional players past the queue’s specified “threshold” size have joined the queue, the last
such 6 players are removed from the queue and placed into a scrimmage (group) with no role
requirements.
Since reducing wait times is the entire purpose of this feature, it must run extremely quick and a
doubly linked list is needed. Since the feature is triggered only when the queue is larger than a
specified maximum size, the number of players in the queue must also be computed extremely
fast.
*/
lfgqueue.h
//Ifgqueue.h
#ifndef LFGQUEUE_H
#define LFGQUEUE_H
#include "player.h"
class LFGQueue
{
public:
LFGQueue(int scrimmage_threshold);
void add_player(Player* p);
bool remove_next_group(Player** players);
bool remove_next_scrimmage(Player** players);
int player_count();
int position(Player* p);
private:
class Node
{
public:
Player* p;
Node* next;
Node* prev;
};
void remove_node(Node* n);
Node* head;
Node* tail;
int scrimmage_threshold;
int count;
};
#endif
lfgqueue.cpp
#include "lfgqueue.h"
LFGQueue::LFGQueue(int scr_threshold)
{
head = NULL;
tail = NULL;
count = 0;
scrimmage_threshold = scr_threshold;
}
void LFGQueue::add_player(Player* p)
{
Node *n = new Node;
n->p = p;
n->next = NULL;
n->prev = NULL;
if(head == NULL)
head = tail = n;
else
{
n->prev = tail;
tail->next = n;
tail = n;
}
count++;
}
bool LFGQueue::remove_next_group(Player** group)
{
if(count < 3) return false;
Node *gp[3] = { NULL, NULL, NULL};
Node *curr = head;
while(curr != NULL)
{
if(gp[0] == NULL && curr->p->role == Player::Defender)
gp[0] = curr;
else if(gp[1] == NULL && curr->p->role == Player::Hunter)
gp[1] = curr;
else if(gp[2] == NULL && curr->p->role == Player::Bard)
gp[2] = curr;
if(gp[0] != NULL && gp[1] != NULL && gp[2] != NULL)
{
for(int i = 0; i < 3; i++)
{
group[i] = gp[i]->p;
remove_node(gp[i]);
}
return true;
}
curr = curr->next;
}
return false;
}
//simliar to remove_next_group, but removing players from tail
bool LFGQueue::remove_next_scrimmage(Player** players)
{
if(count < 6 + scrimmage_threshold) return false;
for(int i = 5; i >= 0; i--)
{
players[i] = tail->p;
remove_node(tail);
}
return true;
}
int LFGQueue::player_count()
{
return count;
}
int LFGQueue::position(Player* p)
{
Node *curr = head;
int position = 1;
while(curr != NULL)
{
if(curr->p->name == p->name && curr->p->role == p->role)
return position;
position++;
curr = curr->next;
}
return -1;
}
void LFGQueue::remove_node(Node* n)
{
if(n == NULL || head == NULL)
return;
if(n->prev == NULL) //deleteing head node
{
head = n->next;
if(head != NULL) //make head's previous as NULL, if queue si not empty
head->prev = NULL;
else //head is NULL , so no more nodes in queue
tail = NULL;
}
else
{
//make previous node to point to a node after the node to be deleted
n->prev->next = n->next;
if(n->next != NULL) //not deleting tail node
n->next->prev = n->prev;
else //deleting tail node
tail = n->prev;
}
delete n;
count --;
}
main.cpp
//**************************************************************************
//main.cpp
#include
#include
#include
#include
#include
#include "lfgqueue.h"
using namespace std;
void permute(Player** players, int len)
{
for (int i = 0; i < len; ++i)
swap(players[i], players[i + rand() % (len-i)]);
}
int main()
{
// Setup for testing
srand(2017);
Player* group[3];
Player* scrimmage[6];
Player daria("Daria", Player::Defender);
Player daniela("Daniela", Player::Defender);
Player diego("Diego", Player::Defender);
Player hector("Hector", Player::Hunter);
Player hugo("Hugo", Player::Hunter);
Player henri("Henri", Player::Hunter);
Player berta("Berta", Player::Bard);
Player bernardo("Bernardo", Player::Bard);
Player brigida("Brigida", Player::Bard);
// Test that everything compiles and queues
// construct without issue.
LFGQueue q1(3);
// Test when queue contains a single complete group in
// in an undesired order (Bard, Hunter, Defender)
q1.add_player(&bernardo);
q1.add_player(&hugo);
q1.add_player(&daria);
assert(q1.player_count() == 3);
assert(q1.position(&bernardo) == 1);
assert(q1.position(&hugo) == 2);
assert(q1.position(&daria) == 3);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daria);
assert(group[0]->name == "Daria");
assert(group[0]->role == Player::Defender);
assert(group[1] == &hugo);
assert(group[1]->name == "Hugo");
assert(group[1]->role == Player::Hunter);
assert(group[2] == &bernardo);
assert(group[2]->name == "Bernardo");
assert(group[2]->role == Player::Bard);
assert(q1.player_count() == 0);
cout << "20% earned." << endl;
// Test what happens when not enough group
group[0] = group[1] = group[2] = 0;
assert(!q1.remove_next_group(group));
assert(group[0] == 0);
assert(group[1] == 0);
assert(group[2] == 0);
for (int i = 0; i < 6; ++i)
scrimmage[i] = 0;
assert(!q1.remove_next_scrimmage(scrimmage));
for (int i = 0; i < 6; ++i)
assert(scrimmage[i] == 0);
cout << "25% earned." << endl;
// Test what happens when two full groups of players
// not in the right order (Def, Hunt, Hunt, Bard, Bard, Def)
q1.add_player(&daria);
q1.add_player(&hector);
q1.add_player(&hugo);
q1.add_player(&bernardo);
q1.add_player(&berta);
q1.add_player(&daniela);
assert(q1.player_count() == 6);
assert(q1.position(&daria) == 1);
assert(q1.position(&hector) == 2);
assert(q1.position(&hugo) == 3);
assert(q1.position(&bernardo) == 4);
assert(q1.position(&berta) == 5);
assert(q1.position(&daniela) == 6);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daria);
assert(group[1] == &hector);
assert(group[2] == &bernardo);
assert(q1.player_count() == 3);
assert(q1.position(&hugo) == 1);
assert(q1.position(&berta) == 2);
assert(q1.position(&daniela) == 3);
group[0] = group[1] = group[2] = 0;
assert(q1.remove_next_group(group));
assert(group[0] == &daniela);
assert(group[1] == &hugo);
assert(group[2] == &berta);
assert(q1.player_count() == 0);
group[0] = group[1] = group[2] = 0;
assert(!q1.remove_next_group(group));
assert(group[0] == 0);
assert(group[1] == 0);
assert(group[2] == 0);
cout << "40% earned." << endl;
// Test what happens when queue reaches enough for a scrimmage
// (6 players past max size of 3)
q1.add_player(&daria);
q1.add_player(&daniela);
q1.add_player(&diego);
q1.add_player(&hector);
q1.add_player(&hugo);
q1.add_player(&henri);
q1.add_player(&berta);
q1.add_player(&bernardo);
assert(q1.player_count() == 8);
for (int i = 0; i < 6; ++i)
scrimmage[i] = 0;
assert(!q1.remove_next_scrimmage(scrimmage));
for (int i = 0; i < 6; ++i)
assert(scrimmage[i] == 0);
q1.add_player(&brigida);
assert(q1.position(&daria) == 1);
assert(q1.position(&daniela) == 2);
assert(q1.position(&diego) == 3);
assert(q1.position(&hector) == 4);
assert(q1.position(&hugo) == 5);
assert(q1.position(&henri) == 6);
assert(q1.position(&berta) == 7);
assert(q1.position(&bernardo) == 8);
assert(q1.position(&brigida) == 9);
assert(q1.player_count() == 9);
assert(q1.remove_next_scrimmage(scrimmage));
assert(scrimmage[0] == &hector);
assert(scrimmage[1] == &hugo);
assert(scrimmage[2] == &henri);
assert(scrimmage[3] == &berta);
assert(scrimmage[4] == &bernardo);
assert(scrimmage[5] == &brigida);
assert(q1.player_count() == 3);
assert(q1.position(&daria) == 1);
assert(q1.position(&daniela) == 2);
assert(q1.position(&diego) == 3);
cout << "65% earned." << endl;
// Make a queue with 3000 players:
// 1000xDefenders, 1000xHunters,
// 1000xBards in a nice order
// and max size of 2000 players.
LFGQueue q2(2000);
Player** all = new Player*[3000];
ostringstream oss;
for (int i = 0; i < 3000; i += 3)
{
oss.str("");
oss << "Defender_" << i+1;
all[i] = new Player(oss.str(), Player::Defender);
oss.str("");
oss << "Hunter_" << i+2;
all[i+1] = new Player(oss.str(), Player::Hunter);
oss.str("");
oss << "Bard_" << i+3;
all[i+2] = new Player(oss.str(), Player::Bard);
}
for (int i = 0; i < 3000; ++i)
{
q2.add_player(all[i]);
assert(q2.player_count() == i+1);
}
// First, remove 1 scrimmage.
for (int j = 0; j < 6; ++j)
scrimmage[j] = 0;
assert(q2.remove_next_scrimmage(scrimmage));
assert(q2.player_count() == 3000 - 6);
assert(scrimmage[0]->name == "Defender_2995");
assert(scrimmage[0]->role == Player::Defender);
assert(scrimmage[1]->name == "Hunter_2996");
assert(scrimmage[1]->role == Player::Hunter);
assert(scrimmage[2]->name == "Bard_2997");
assert(scrimmage[2]->role == Player::Bard);
assert(scrimmage[3]->name == "Defender_2998");
assert(scrimmage[3]->role == Player::Defender);
assert(scrimmage[4]->name == "Hunter_2999");
assert(scrimmage[4]->role == Player::Hunter);
assert(scrimmage[5]->name == "Bard_3000");
assert(scrimmage[5]->role == Player::Bard);
cout << "70% earned." << endl;
// Now remove 165 more scrimmages
for (int i = 0; i < 165; ++i)
{
for (int j = 0; j < 6; ++j)
scrimmage[j] = 0;
assert(q2.remove_next_scrimmage(scrimmage));
assert(q2.player_count() == 3000 - 6 - 6*(i+1));
assert(scrimmage[0]->role == Player::Defender);
assert(scrimmage[1]->role == Player::Hunter);
assert(scrimmage[2]->role == Player::Bard);
assert(scrimmage[3]->role == Player::Defender);
assert(scrimmage[4]->role == Player::Hunter);
assert(scrimmage[5]->role == Player::Bard);
}
// Now 3000 - 166 * 6 = 2004 players remain
assert(!q2.remove_next_scrimmage(scrimmage));
// Now remove the rest of the queue as groups
group[0] = group[1] = group[2] = 0;
assert(q2.remove_next_group(group));
assert(q2.player_count() == 2001);
assert(group[0]->name == "Defender_1");
assert(group[0]->role == Player::Defender);
assert(group[1]->name == "Hunter_2");
assert(group[1]->role == Player::Hunter);
assert(group[2]->name == "Bard_3");
assert(group[2]->role == Player::Bard);
// (1 + 667) * 3 = 2004
for (int i = 0; i < 667; ++i)
{
group[0] = group[1] = group[2] = 0;
assert(q2.remove_next_group(group));
assert(q2.player_count() == 2001 - 3 * (i+1));
assert(group[0]->role == Player::Defender);
assert(group[1]->role == Player::Hunter);
assert(group[2]->role == Player::Bard);
}
assert(!q2.remove_next_group(group));
cout << "80% earned." << endl;
// Timing test. Make a queue with 3000000 players:
// 1000000xDefender, 1000000xHunter, 1000000xBard,
// in collections of shuffled 30 complete groups.
LFGQueue qt(100000);
const int timing_player_count = 1000000;
all = new Player*[timing_player_count];
for (int i = 0; i < timing_player_count; i += 3)
{
all[i] = new Player("Defender_???", Player::Defender);
all[i+1] = new Player("Hunter_???", Player::Hunter);
all[i+2] = new Player("Bard_???", Player::Bard);
}
for (int i = 0; i < timing_player_count; i += 30)
permute(&(all[i]), 30);
// Time how long it takes to add all players
clock_t start = clock();
for (int i = 0; i < timing_player_count; ++i)
qt.add_player(all[i]);
float duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count);
assert(duration < 2.0);
// Time how long it takes to form 10000 scrimmages
start = clock();
for (int i = 0; i < 10000; ++i)
assert(qt.remove_next_scrimmage(scrimmage));
duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count - 60000);
assert(duration < 0.1);
// Time how long it takes to form 10000 groups
start = clock();
for (int i = 0; i < 10000; ++i)
assert(qt.remove_next_group(group));
duration = static_cast(clock() - start) / CLOCKS_PER_SEC;
assert(qt.player_count() == timing_player_count - 60000 - 30000);
assert(duration < 0.1);
// Test removing a group correctly
group[0] = group[1] = group[2] = 0;
assert(qt.remove_next_group(group));
assert(group[0]->role == Player::Defender);
assert(group[1]->role == Player::Hunter);
assert(group[2]->role == Player::Bard);
cout << "100% earned." << endl;
}
output
20% earned.
25% earned.
40% earned.
65% earned.
70% earned.
80% earned.
100% earned.

More Related Content

PDF
import java.util.Scanner;public class Main {    public static in.pdf
PPTX
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
PDF
The Ring programming language version 1.5.2 book - Part 52 of 181
PDF
The Ring programming language version 1.10 book - Part 70 of 212
PDF
The Ring programming language version 1.6 book - Part 55 of 189
PDF
The Ring programming language version 1.10 book - Part 71 of 212
PPTX
ES6(ES2015) is beautiful
import java.util.Scanner;public class Main {    public static in.pdf
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
The Ring programming language version 1.5.2 book - Part 52 of 181
The Ring programming language version 1.10 book - Part 70 of 212
The Ring programming language version 1.6 book - Part 55 of 189
The Ring programming language version 1.10 book - Part 71 of 212
ES6(ES2015) is beautiful

Similar to Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf (20)

PPTX
Workshop 1: Good practices in JavaScript
PDF
Dpsm simu.cpp
PDF
#include stdio.h #include string.h #include stdlib.h #in.pdf
PPT
Mobile Game and Application with J2ME - Collision Detection
PPT
Mobile Game and Application with J2ME
PDF
PDF
package com.tictactoe; public class Main {public void play() {.pdf
PDF
The main class of the tictoe game looks like.public class Main {.pdf
DOCX
Hangman Game Programming in C (coding)
PDF
2024 PHPCon - Symfony background processing
PDF
Code em Poker
PDF
AI For Texam Hold'em poker
DOCX
Cs pritical file
PDF
I have written the code but cannot complete the assignment please help.pdf
PDF
Lập trình Python cơ bản
PDF
Node meetup feb_20_12
DOCX
include.docx
PDF
The following code, is a one player battleship game in JAVA. Im tryi.pdf
PDF
Clock For My
PDF
groovy databases
Workshop 1: Good practices in JavaScript
Dpsm simu.cpp
#include stdio.h #include string.h #include stdlib.h #in.pdf
Mobile Game and Application with J2ME - Collision Detection
Mobile Game and Application with J2ME
package com.tictactoe; public class Main {public void play() {.pdf
The main class of the tictoe game looks like.public class Main {.pdf
Hangman Game Programming in C (coding)
2024 PHPCon - Symfony background processing
Code em Poker
AI For Texam Hold'em poker
Cs pritical file
I have written the code but cannot complete the assignment please help.pdf
Lập trình Python cơ bản
Node meetup feb_20_12
include.docx
The following code, is a one player battleship game in JAVA. Im tryi.pdf
Clock For My
groovy databases
Ad

More from fazilfootsteps (20)

PDF
Why are the mass extinctions followed by a burst of speciation in .pdf
PDF
Why is African American history important What challenges have Afri.pdf
PDF
Using the phase diagram of polydstyrene and DOP below, would you ex.pdf
PDF
What does it mean to say that individuals as a group are net supplier.pdf
PDF
True or False Statement The DNS namespace is hierarchical. Protocols.pdf
PDF
Thoughts on this Rule by the people is the main idea behind dem.pdf
PDF
The symmetry properties of the plane figure formed by the four point.pdf
PDF
QUESTION 12 (Learning Outcome 3) Which of the following flawed uses o.pdf
PDF
Robbinsdale Hospital is one of two hospitals among the six facilitie.pdf
PDF
Research excise taxes in other states besides North Carolina. Report.pdf
PDF
Prove that E X is not connected if and only if there exist open sets.pdf
PDF
potential benefits of sustainability strategySolutionpotential.pdf
PDF
Please write a code in JAVA to do line editor..Your program will b.pdf
PDF
Nessus is a network security tool- write a pragraph describe itsto.pdf
PDF
Module 01 Discussion - Dominant CultureDefine the .pdf
PDF
List and explain the states of process in a specific operating syste.pdf
PDF
Most integer types are directly supported by hardware, but some are n.pdf
PDF
Introduction to Philosophy 101 HomeworkSection 3 Deductive Argum.pdf
PDF
Indian Institute of Management Kashipur Executive Post Graduate Pro.pdf
PDF
implemement the game.cpp by the header file given. And create main.c.pdf
Why are the mass extinctions followed by a burst of speciation in .pdf
Why is African American history important What challenges have Afri.pdf
Using the phase diagram of polydstyrene and DOP below, would you ex.pdf
What does it mean to say that individuals as a group are net supplier.pdf
True or False Statement The DNS namespace is hierarchical. Protocols.pdf
Thoughts on this Rule by the people is the main idea behind dem.pdf
The symmetry properties of the plane figure formed by the four point.pdf
QUESTION 12 (Learning Outcome 3) Which of the following flawed uses o.pdf
Robbinsdale Hospital is one of two hospitals among the six facilitie.pdf
Research excise taxes in other states besides North Carolina. Report.pdf
Prove that E X is not connected if and only if there exist open sets.pdf
potential benefits of sustainability strategySolutionpotential.pdf
Please write a code in JAVA to do line editor..Your program will b.pdf
Nessus is a network security tool- write a pragraph describe itsto.pdf
Module 01 Discussion - Dominant CultureDefine the .pdf
List and explain the states of process in a specific operating syste.pdf
Most integer types are directly supported by hardware, but some are n.pdf
Introduction to Philosophy 101 HomeworkSection 3 Deductive Argum.pdf
Indian Institute of Management Kashipur Executive Post Graduate Pro.pdf
implemement the game.cpp by the header file given. And create main.c.pdf
Ad

Recently uploaded (20)

PDF
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
PDF
TR - Agricultural Crops Production NC III.pdf
PDF
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PPTX
Renaissance Architecture: A Journey from Faith to Humanism
PDF
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
PPTX
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
PDF
VCE English Exam - Section C Student Revision Booklet
PDF
Sports Quiz easy sports quiz sports quiz
PDF
Microbial disease of the cardiovascular and lymphatic systems
PPTX
GDM (1) (1).pptx small presentation for students
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PPTX
Microbial diseases, their pathogenesis and prophylaxis
PPTX
Institutional Correction lecture only . . .
PPTX
master seminar digital applications in india
PDF
Classroom Observation Tools for Teachers
PDF
01-Introduction-to-Information-Management.pdf
PPTX
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
PDF
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student
The Lost Whites of Pakistan by Jahanzaib Mughal.pdf
TR - Agricultural Crops Production NC III.pdf
Black Hat USA 2025 - Micro ICS Summit - ICS/OT Threat Landscape
Module 4: Burden of Disease Tutorial Slides S2 2025
Renaissance Architecture: A Journey from Faith to Humanism
Physiotherapy_for_Respiratory_and_Cardiac_Problems WEBBER.pdf
BOWEL ELIMINATION FACTORS AFFECTING AND TYPES
VCE English Exam - Section C Student Revision Booklet
Sports Quiz easy sports quiz sports quiz
Microbial disease of the cardiovascular and lymphatic systems
GDM (1) (1).pptx small presentation for students
human mycosis Human fungal infections are called human mycosis..pptx
Pharmacology of Heart Failure /Pharmacotherapy of CHF
Microbial diseases, their pathogenesis and prophylaxis
Institutional Correction lecture only . . .
master seminar digital applications in india
Classroom Observation Tools for Teachers
01-Introduction-to-Information-Management.pdf
IMMUNITY IMMUNITY refers to protection against infection, and the immune syst...
grade 11-chemistry_fetena_net_5883.pdf teacher guide for all student

Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf

  • 1. //Ifgqueue.h #ifndef LFGQUEUE_H #define LFGQUEUE_H #include "player.h" class LFGQueue { public: LFGQueue(int scrimmage_threshold); void add_player(Player* p); bool remove_next_group(Player** players); bool remove_next_scrimmage(Player** players); int player_count(); int position(Player* p); private: class Node { public: Player* p; Node* next; Node* prev; }; void remove_node(Node* n); Node* head; Node* tail; int scrimmage_threshold; int count; }; #endif //************************************************************************** //main.cpp #include #include #include #include #include
  • 2. #include "lfgqueue.h" using namespace std; void permute(Player** players, int len) { for (int i = 0; i < len; ++i) swap(players[i], players[i + rand() % (len-i)]); } int main() { // Setup for testing srand(2017); Player* group[3]; Player* scrimmage[6]; Player daria("Daria", Player::Defender); Player daniela("Daniela", Player::Defender); Player diego("Diego", Player::Defender); Player hector("Hector", Player::Hunter); Player hugo("Hugo", Player::Hunter); Player henri("Henri", Player::Hunter); Player berta("Berta", Player::Bard); Player bernardo("Bernardo", Player::Bard); Player brigida("Brigida", Player::Bard); // Test that everything compiles and queues // construct without issue. LFGQueue q1(3); // Test when queue contains a single complete group in // in an undesired order (Bard, Hunter, Defender) q1.add_player(&bernardo); q1.add_player(&hugo); q1.add_player(&daria); assert(q1.player_count() == 3); assert(q1.position(&bernardo) == 1); assert(q1.position(&hugo) == 2); assert(q1.position(&daria) == 3);
  • 3. group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daria); assert(group[0]->name == "Daria"); assert(group[0]->role == Player::Defender); assert(group[1] == &hugo); assert(group[1]->name == "Hugo"); assert(group[1]->role == Player::Hunter); assert(group[2] == &bernardo); assert(group[2]->name == "Bernardo"); assert(group[2]->role == Player::Bard); assert(q1.player_count() == 0); cout << "20% earned." << endl; // Test what happens when not enough group group[0] = group[1] = group[2] = 0; assert(!q1.remove_next_group(group)); assert(group[0] == 0); assert(group[1] == 0); assert(group[2] == 0); for (int i = 0; i < 6; ++i) scrimmage[i] = 0; assert(!q1.remove_next_scrimmage(scrimmage)); for (int i = 0; i < 6; ++i) assert(scrimmage[i] == 0); cout << "25% earned." << endl; // Test what happens when two full groups of players // not in the right order (Def, Hunt, Hunt, Bard, Bard, Def) q1.add_player(&daria); q1.add_player(&hector); q1.add_player(&hugo); q1.add_player(&bernardo); q1.add_player(&berta); q1.add_player(&daniela); assert(q1.player_count() == 6);
  • 4. assert(q1.position(&daria) == 1); assert(q1.position(&hector) == 2); assert(q1.position(&hugo) == 3); assert(q1.position(&bernardo) == 4); assert(q1.position(&berta) == 5); assert(q1.position(&daniela) == 6); group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daria); assert(group[1] == &hector); assert(group[2] == &bernardo); assert(q1.player_count() == 3); assert(q1.position(&hugo) == 1); assert(q1.position(&berta) == 2); assert(q1.position(&daniela) == 3); group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daniela); assert(group[1] == &hugo); assert(group[2] == &berta); assert(q1.player_count() == 0); group[0] = group[1] = group[2] = 0; assert(!q1.remove_next_group(group)); assert(group[0] == 0); assert(group[1] == 0); assert(group[2] == 0); cout << "40% earned." << endl; // Test what happens when queue reaches enough for a scrimmage // (6 players past max size of 3) q1.add_player(&daria); q1.add_player(&daniela); q1.add_player(&diego); q1.add_player(&hector);
  • 5. q1.add_player(&hugo); q1.add_player(&henri); q1.add_player(&berta); q1.add_player(&bernardo); assert(q1.player_count() == 8); for (int i = 0; i < 6; ++i) scrimmage[i] = 0; assert(!q1.remove_next_scrimmage(scrimmage)); for (int i = 0; i < 6; ++i) assert(scrimmage[i] == 0); q1.add_player(&brigida); assert(q1.position(&daria) == 1); assert(q1.position(&daniela) == 2); assert(q1.position(&diego) == 3); assert(q1.position(&hector) == 4); assert(q1.position(&hugo) == 5); assert(q1.position(&henri) == 6); assert(q1.position(&berta) == 7); assert(q1.position(&bernardo) == 8); assert(q1.position(&brigida) == 9); assert(q1.player_count() == 9); assert(q1.remove_next_scrimmage(scrimmage)); assert(scrimmage[0] == &hector); assert(scrimmage[1] == &hugo); assert(scrimmage[2] == &henri); assert(scrimmage[3] == &berta); assert(scrimmage[4] == &bernardo); assert(scrimmage[5] == &brigida); assert(q1.player_count() == 3); assert(q1.position(&daria) == 1); assert(q1.position(&daniela) == 2); assert(q1.position(&diego) == 3); cout << "65% earned." << endl; // Make a queue with 3000 players: // 1000xDefenders, 1000xHunters,
  • 6. // 1000xBards in a nice order // and max size of 2000 players. LFGQueue q2(2000); Player** all = new Player*[3000]; ostringstream oss; for (int i = 0; i < 3000; i += 3) { oss.str(""); oss << "Defender_" << i+1; all[i] = new Player(oss.str(), Player::Defender); oss.str(""); oss << "Hunter_" << i+2; all[i+1] = new Player(oss.str(), Player::Hunter); oss.str(""); oss << "Bard_" << i+3; all[i+2] = new Player(oss.str(), Player::Bard); } for (int i = 0; i < 3000; ++i) { q2.add_player(all[i]); assert(q2.player_count() == i+1); } // First, remove 1 scrimmage. for (int j = 0; j < 6; ++j) scrimmage[j] = 0; assert(q2.remove_next_scrimmage(scrimmage)); assert(q2.player_count() == 3000 - 6); assert(scrimmage[0]->name == "Defender_2995"); assert(scrimmage[0]->role == Player::Defender); assert(scrimmage[1]->name == "Hunter_2996"); assert(scrimmage[1]->role == Player::Hunter); assert(scrimmage[2]->name == "Bard_2997"); assert(scrimmage[2]->role == Player::Bard); assert(scrimmage[3]->name == "Defender_2998"); assert(scrimmage[3]->role == Player::Defender); assert(scrimmage[4]->name == "Hunter_2999");
  • 7. assert(scrimmage[4]->role == Player::Hunter); assert(scrimmage[5]->name == "Bard_3000"); assert(scrimmage[5]->role == Player::Bard); cout << "70% earned." << endl; // Now remove 165 more scrimmages for (int i = 0; i < 165; ++i) { for (int j = 0; j < 6; ++j) scrimmage[j] = 0; assert(q2.remove_next_scrimmage(scrimmage)); assert(q2.player_count() == 3000 - 6 - 6*(i+1)); assert(scrimmage[0]->role == Player::Defender); assert(scrimmage[1]->role == Player::Hunter); assert(scrimmage[2]->role == Player::Bard); assert(scrimmage[3]->role == Player::Defender); assert(scrimmage[4]->role == Player::Hunter); assert(scrimmage[5]->role == Player::Bard); } // Now 3000 - 166 * 6 = 2004 players remain assert(!q2.remove_next_scrimmage(scrimmage)); // Now remove the rest of the queue as groups group[0] = group[1] = group[2] = 0; assert(q2.remove_next_group(group)); assert(q2.player_count() == 2001); assert(group[0]->name == "Defender_1"); assert(group[0]->role == Player::Defender); assert(group[1]->name == "Hunter_2"); assert(group[1]->role == Player::Hunter); assert(group[2]->name == "Bard_3"); assert(group[2]->role == Player::Bard); // (1 + 667) * 3 = 2004 for (int i = 0; i < 667; ++i) { group[0] = group[1] = group[2] = 0; assert(q2.remove_next_group(group));
  • 8. assert(q2.player_count() == 2001 - 3 * (i+1)); assert(group[0]->role == Player::Defender); assert(group[1]->role == Player::Hunter); assert(group[2]->role == Player::Bard); } assert(!q2.remove_next_group(group)); cout << "80% earned." << endl; // Timing test. Make a queue with 3000000 players: // 1000000xDefender, 1000000xHunter, 1000000xBard, // in collections of shuffled 30 complete groups. LFGQueue qt(100000); const int timing_player_count = 1000000; all = new Player*[timing_player_count]; for (int i = 0; i < timing_player_count; i += 3) { all[i] = new Player("Defender_???", Player::Defender); all[i+1] = new Player("Hunter_???", Player::Hunter); all[i+2] = new Player("Bard_???", Player::Bard); } for (int i = 0; i < timing_player_count; i += 30) permute(&(all[i]), 30); // Time how long it takes to add all players clock_t start = clock(); for (int i = 0; i < timing_player_count; ++i) qt.add_player(all[i]); float duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count); assert(duration < 2.0); // Time how long it takes to form 10000 scrimmages start = clock(); for (int i = 0; i < 10000; ++i) assert(qt.remove_next_scrimmage(scrimmage)); duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count - 60000);
  • 9. assert(duration < 0.1); // Time how long it takes to form 10000 groups start = clock(); for (int i = 0; i < 10000; ++i) assert(qt.remove_next_group(group)); duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count - 60000 - 30000); assert(duration < 0.1); // Test removing a group correctly group[0] = group[1] = group[2] = 0; assert(qt.remove_next_group(group)); assert(group[0]->role == Player::Defender); assert(group[1]->role == Player::Hunter); assert(group[2]->role == Player::Bard); cout << "100% earned." << endl; } //************************************************************************ //player.h #ifndef PLAYER_H #define PLAYER_H #include using namespace std; class Player { public: enum Role {Defender, Hunter, Bard}; Player(string name, Role role) { this->name = name; this->role = role; } string name; Role role; };
  • 10. #endif //*********************************************************************** /* Long queuing times are common in many games, leading to player boredom as they wait idly. As a solution, many games have a “scrimmage” mode where players at the end of a long queue are placed into large, unstructured groups to play a casual game. Here you’ll add such a scrimmage feature to a “looking for group” queue. Whenever more than 6 additional players past the queue’s specified “threshold” size have joined the queue, the last such 6 players are removed from the queue and placed into a scrimmage (group) with no role requirements. Since reducing wait times is the entire purpose of this feature, it must run extremely quick and a doubly linked list is needed. Since the feature is triggered only when the queue is larger than a specified maximum size, the number of players in the queue must also be computed extremely fast. */ Solution Given below is the implementation of lfgqueue.cpp. Please use it along with other files from question - lfgqueue.h, main.cpp, player.h. These files are not modified. The only new file is lfgqueue.cpp. Output shown in the end. Please don't forget to rate the answer if it helped. Thank you very much. player.h //************************************************************************ //player.h #ifndef PLAYER_H #define PLAYER_H #include using namespace std; class Player { public: enum Role {Defender, Hunter, Bard}; Player(string name, Role role) {
  • 11. this->name = name; this->role = role; } string name; Role role; }; #endif //*********************************************************************** /* Long queuing times are common in many games, leading to player boredom as they wait idly. As a solution, many games have a “scrimmage” mode where players at the end of a long queue are placed into large, unstructured groups to play a casual game. Here you’ll add such a scrimmage feature to a “looking for group” queue. Whenever more than 6 additional players past the queue’s specified “threshold” size have joined the queue, the last such 6 players are removed from the queue and placed into a scrimmage (group) with no role requirements. Since reducing wait times is the entire purpose of this feature, it must run extremely quick and a doubly linked list is needed. Since the feature is triggered only when the queue is larger than a specified maximum size, the number of players in the queue must also be computed extremely fast. */ lfgqueue.h //Ifgqueue.h #ifndef LFGQUEUE_H #define LFGQUEUE_H #include "player.h" class LFGQueue { public: LFGQueue(int scrimmage_threshold); void add_player(Player* p);
  • 12. bool remove_next_group(Player** players); bool remove_next_scrimmage(Player** players); int player_count(); int position(Player* p); private: class Node { public: Player* p; Node* next; Node* prev; }; void remove_node(Node* n); Node* head; Node* tail; int scrimmage_threshold; int count; }; #endif lfgqueue.cpp #include "lfgqueue.h" LFGQueue::LFGQueue(int scr_threshold) { head = NULL; tail = NULL; count = 0; scrimmage_threshold = scr_threshold; } void LFGQueue::add_player(Player* p) { Node *n = new Node; n->p = p; n->next = NULL; n->prev = NULL;
  • 13. if(head == NULL) head = tail = n; else { n->prev = tail; tail->next = n; tail = n; } count++; } bool LFGQueue::remove_next_group(Player** group) { if(count < 3) return false; Node *gp[3] = { NULL, NULL, NULL}; Node *curr = head; while(curr != NULL) { if(gp[0] == NULL && curr->p->role == Player::Defender) gp[0] = curr; else if(gp[1] == NULL && curr->p->role == Player::Hunter) gp[1] = curr; else if(gp[2] == NULL && curr->p->role == Player::Bard) gp[2] = curr; if(gp[0] != NULL && gp[1] != NULL && gp[2] != NULL) { for(int i = 0; i < 3; i++) { group[i] = gp[i]->p; remove_node(gp[i]); } return true; } curr = curr->next;
  • 14. } return false; } //simliar to remove_next_group, but removing players from tail bool LFGQueue::remove_next_scrimmage(Player** players) { if(count < 6 + scrimmage_threshold) return false; for(int i = 5; i >= 0; i--) { players[i] = tail->p; remove_node(tail); } return true; } int LFGQueue::player_count() { return count; } int LFGQueue::position(Player* p) { Node *curr = head; int position = 1; while(curr != NULL) { if(curr->p->name == p->name && curr->p->role == p->role) return position; position++; curr = curr->next; } return -1; } void LFGQueue::remove_node(Node* n) { if(n == NULL || head == NULL) return;
  • 15. if(n->prev == NULL) //deleteing head node { head = n->next; if(head != NULL) //make head's previous as NULL, if queue si not empty head->prev = NULL; else //head is NULL , so no more nodes in queue tail = NULL; } else { //make previous node to point to a node after the node to be deleted n->prev->next = n->next; if(n->next != NULL) //not deleting tail node n->next->prev = n->prev; else //deleting tail node tail = n->prev; } delete n; count --; } main.cpp //************************************************************************** //main.cpp #include #include #include #include #include #include "lfgqueue.h" using namespace std; void permute(Player** players, int len) { for (int i = 0; i < len; ++i) swap(players[i], players[i + rand() % (len-i)]); }
  • 16. int main() { // Setup for testing srand(2017); Player* group[3]; Player* scrimmage[6]; Player daria("Daria", Player::Defender); Player daniela("Daniela", Player::Defender); Player diego("Diego", Player::Defender); Player hector("Hector", Player::Hunter); Player hugo("Hugo", Player::Hunter); Player henri("Henri", Player::Hunter); Player berta("Berta", Player::Bard); Player bernardo("Bernardo", Player::Bard); Player brigida("Brigida", Player::Bard); // Test that everything compiles and queues // construct without issue. LFGQueue q1(3); // Test when queue contains a single complete group in // in an undesired order (Bard, Hunter, Defender) q1.add_player(&bernardo); q1.add_player(&hugo); q1.add_player(&daria); assert(q1.player_count() == 3); assert(q1.position(&bernardo) == 1); assert(q1.position(&hugo) == 2); assert(q1.position(&daria) == 3); group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daria);
  • 17. assert(group[0]->name == "Daria"); assert(group[0]->role == Player::Defender); assert(group[1] == &hugo); assert(group[1]->name == "Hugo"); assert(group[1]->role == Player::Hunter); assert(group[2] == &bernardo); assert(group[2]->name == "Bernardo"); assert(group[2]->role == Player::Bard); assert(q1.player_count() == 0); cout << "20% earned." << endl; // Test what happens when not enough group group[0] = group[1] = group[2] = 0; assert(!q1.remove_next_group(group)); assert(group[0] == 0); assert(group[1] == 0); assert(group[2] == 0); for (int i = 0; i < 6; ++i) scrimmage[i] = 0; assert(!q1.remove_next_scrimmage(scrimmage)); for (int i = 0; i < 6; ++i) assert(scrimmage[i] == 0); cout << "25% earned." << endl; // Test what happens when two full groups of players // not in the right order (Def, Hunt, Hunt, Bard, Bard, Def) q1.add_player(&daria); q1.add_player(&hector); q1.add_player(&hugo); q1.add_player(&bernardo); q1.add_player(&berta); q1.add_player(&daniela); assert(q1.player_count() == 6);
  • 18. assert(q1.position(&daria) == 1); assert(q1.position(&hector) == 2); assert(q1.position(&hugo) == 3); assert(q1.position(&bernardo) == 4); assert(q1.position(&berta) == 5); assert(q1.position(&daniela) == 6); group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daria); assert(group[1] == &hector); assert(group[2] == &bernardo); assert(q1.player_count() == 3); assert(q1.position(&hugo) == 1); assert(q1.position(&berta) == 2); assert(q1.position(&daniela) == 3); group[0] = group[1] = group[2] = 0; assert(q1.remove_next_group(group)); assert(group[0] == &daniela); assert(group[1] == &hugo); assert(group[2] == &berta); assert(q1.player_count() == 0); group[0] = group[1] = group[2] = 0; assert(!q1.remove_next_group(group)); assert(group[0] == 0); assert(group[1] == 0); assert(group[2] == 0); cout << "40% earned." << endl; // Test what happens when queue reaches enough for a scrimmage // (6 players past max size of 3) q1.add_player(&daria);
  • 19. q1.add_player(&daniela); q1.add_player(&diego); q1.add_player(&hector); q1.add_player(&hugo); q1.add_player(&henri); q1.add_player(&berta); q1.add_player(&bernardo); assert(q1.player_count() == 8); for (int i = 0; i < 6; ++i) scrimmage[i] = 0; assert(!q1.remove_next_scrimmage(scrimmage)); for (int i = 0; i < 6; ++i) assert(scrimmage[i] == 0); q1.add_player(&brigida); assert(q1.position(&daria) == 1); assert(q1.position(&daniela) == 2); assert(q1.position(&diego) == 3); assert(q1.position(&hector) == 4); assert(q1.position(&hugo) == 5); assert(q1.position(&henri) == 6); assert(q1.position(&berta) == 7); assert(q1.position(&bernardo) == 8); assert(q1.position(&brigida) == 9); assert(q1.player_count() == 9); assert(q1.remove_next_scrimmage(scrimmage)); assert(scrimmage[0] == &hector); assert(scrimmage[1] == &hugo); assert(scrimmage[2] == &henri); assert(scrimmage[3] == &berta); assert(scrimmage[4] == &bernardo); assert(scrimmage[5] == &brigida);
  • 20. assert(q1.player_count() == 3); assert(q1.position(&daria) == 1); assert(q1.position(&daniela) == 2); assert(q1.position(&diego) == 3); cout << "65% earned." << endl; // Make a queue with 3000 players: // 1000xDefenders, 1000xHunters, // 1000xBards in a nice order // and max size of 2000 players. LFGQueue q2(2000); Player** all = new Player*[3000]; ostringstream oss; for (int i = 0; i < 3000; i += 3) { oss.str(""); oss << "Defender_" << i+1; all[i] = new Player(oss.str(), Player::Defender); oss.str(""); oss << "Hunter_" << i+2; all[i+1] = new Player(oss.str(), Player::Hunter); oss.str(""); oss << "Bard_" << i+3; all[i+2] = new Player(oss.str(), Player::Bard); } for (int i = 0; i < 3000; ++i) { q2.add_player(all[i]); assert(q2.player_count() == i+1); } // First, remove 1 scrimmage. for (int j = 0; j < 6; ++j) scrimmage[j] = 0;
  • 21. assert(q2.remove_next_scrimmage(scrimmage)); assert(q2.player_count() == 3000 - 6); assert(scrimmage[0]->name == "Defender_2995"); assert(scrimmage[0]->role == Player::Defender); assert(scrimmage[1]->name == "Hunter_2996"); assert(scrimmage[1]->role == Player::Hunter); assert(scrimmage[2]->name == "Bard_2997"); assert(scrimmage[2]->role == Player::Bard); assert(scrimmage[3]->name == "Defender_2998"); assert(scrimmage[3]->role == Player::Defender); assert(scrimmage[4]->name == "Hunter_2999"); assert(scrimmage[4]->role == Player::Hunter); assert(scrimmage[5]->name == "Bard_3000"); assert(scrimmage[5]->role == Player::Bard); cout << "70% earned." << endl; // Now remove 165 more scrimmages for (int i = 0; i < 165; ++i) { for (int j = 0; j < 6; ++j) scrimmage[j] = 0; assert(q2.remove_next_scrimmage(scrimmage)); assert(q2.player_count() == 3000 - 6 - 6*(i+1)); assert(scrimmage[0]->role == Player::Defender); assert(scrimmage[1]->role == Player::Hunter); assert(scrimmage[2]->role == Player::Bard); assert(scrimmage[3]->role == Player::Defender); assert(scrimmage[4]->role == Player::Hunter); assert(scrimmage[5]->role == Player::Bard); } // Now 3000 - 166 * 6 = 2004 players remain assert(!q2.remove_next_scrimmage(scrimmage)); // Now remove the rest of the queue as groups group[0] = group[1] = group[2] = 0;
  • 22. assert(q2.remove_next_group(group)); assert(q2.player_count() == 2001); assert(group[0]->name == "Defender_1"); assert(group[0]->role == Player::Defender); assert(group[1]->name == "Hunter_2"); assert(group[1]->role == Player::Hunter); assert(group[2]->name == "Bard_3"); assert(group[2]->role == Player::Bard); // (1 + 667) * 3 = 2004 for (int i = 0; i < 667; ++i) { group[0] = group[1] = group[2] = 0; assert(q2.remove_next_group(group)); assert(q2.player_count() == 2001 - 3 * (i+1)); assert(group[0]->role == Player::Defender); assert(group[1]->role == Player::Hunter); assert(group[2]->role == Player::Bard); } assert(!q2.remove_next_group(group)); cout << "80% earned." << endl; // Timing test. Make a queue with 3000000 players: // 1000000xDefender, 1000000xHunter, 1000000xBard, // in collections of shuffled 30 complete groups. LFGQueue qt(100000); const int timing_player_count = 1000000; all = new Player*[timing_player_count]; for (int i = 0; i < timing_player_count; i += 3) { all[i] = new Player("Defender_???", Player::Defender); all[i+1] = new Player("Hunter_???", Player::Hunter); all[i+2] = new Player("Bard_???", Player::Bard); } for (int i = 0; i < timing_player_count; i += 30)
  • 23. permute(&(all[i]), 30); // Time how long it takes to add all players clock_t start = clock(); for (int i = 0; i < timing_player_count; ++i) qt.add_player(all[i]); float duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count); assert(duration < 2.0); // Time how long it takes to form 10000 scrimmages start = clock(); for (int i = 0; i < 10000; ++i) assert(qt.remove_next_scrimmage(scrimmage)); duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count - 60000); assert(duration < 0.1); // Time how long it takes to form 10000 groups start = clock(); for (int i = 0; i < 10000; ++i) assert(qt.remove_next_group(group)); duration = static_cast(clock() - start) / CLOCKS_PER_SEC; assert(qt.player_count() == timing_player_count - 60000 - 30000); assert(duration < 0.1); // Test removing a group correctly group[0] = group[1] = group[2] = 0; assert(qt.remove_next_group(group)); assert(group[0]->role == Player::Defender); assert(group[1]->role == Player::Hunter); assert(group[2]->role == Player::Bard); cout << "100% earned." << endl; } output 20% earned.
  • 24. 25% earned. 40% earned. 65% earned. 70% earned. 80% earned. 100% earned.