-
Notifications
You must be signed in to change notification settings - Fork 0
/
Supermarket.cpp
185 lines (168 loc) · 4.9 KB
/
Supermarket.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
* Supermarket.cpp
*
* Created on: 09/05/2014
* Author: arthurhortmannerpen
*/
#include <iostream>
#include <sstream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include "cashier/Cashier.h"
#include "client/makeRandomClient.h"
#include "Supermarket.h"
#include "cashier/GoodProcessment.h"
#include "dataStructures/CircularList.h"
Supermarket::Supermarket(const std::string& name, const Queue<Cashier>& cashiers, int averageTimeNewClients, int totalRuntimeHours, int maxQueueSize) :
_name(name),
_cashiers(cashiers),
_currentTime(),
_timeNextClient(),
_averageTimeNewClients(averageTimeNewClients),
_totalRuntime(totalRuntimeHours * 3600),
_lostClients(),
_lostIncome(),
_maxQueueSize(maxQueueSize)
{}
Supermarket::~Supermarket() {}
/**
* @brief loop de funcionamento. Rodara o programa ate o tempo atual ser igual ao tempo total de simulacao
*/
void Supermarket::run() {
while (_currentTime < _totalRuntime) {
lookForNextClient();
updateCashiers();
_currentTime++;
}
}
/**
* @brief Pesquisa se um novo cliente entrara no supermercado no tempo atual.
*
* @details Alem de criar um novo cliente, se esta no momento certo, o metodo tambem prepara o proximo tempo de um cliente
* entrar no supermercado
*/
void Supermarket::lookForNextClient() {
if (_currentTime == _timeNextClient) {
Client newClient = makeRandomClient(_currentTime);
try {
newClient.chooseCashier(_cashiers);
}
catch (int e) {
++_lostClients;
_lostIncome += newClient.cartValue() * 3;
}
int randomFactor = rand() % 3 - 1; //valores de -1 a 1
int total = randomFactor + _averageTimeNewClients;
if (total < 1) {
_timeNextClient = _currentTime + 1;
} else {
_timeNextClient += total;
}
}
}
/**
* @brief Atualiza todos os caixas com o tempo atual. Adicionando tambem um caixa extra, caso todas as filas estejam "cheias"
*
* @details Adiciona um caixa extra caso todas as filas estejam com mais clientes que o maximo setado para as filas
*/
void Supermarket::updateCashiers() {
for (int i = 0; i < _cashiers.size(); ++i) {
_cashiers.at(i).update(_currentTime);
}
for (int i = 0; i < _cashiers.size(); ++i) {
if (_cashiers.at(i).queueSize() <= _maxQueueSize) {
return;
}
}
callNewCashier();
}
/**
* @brief Cria um caixa extra
*
* @details Cria um caixa extra com salario 200, processamento bom e trabalhando hora extra
*/
void Supermarket::callNewCashier() {
_cashiers.push_back(Cashier("Extra Cashier", 200, GoodProcessment(), _currentTime, true));
}
/**
* @brief Cria texto que representa o total de dinheiro que aquele caixa recebeu de seus clientes
*
* @return String com nome do caixa + o total de dinheiro recebido pelo caixa
*/
std::string Supermarket::incomeOfCashiers() const {
std::stringstream string;
for (int i = 0; i < _cashiers.size(); ++i) {
string << _cashiers.at(i).id() << "\t\t\tR$ " << _cashiers.at(i).totalIncome() << std::endl;
}
return string.str();
}
/**
* @brief Cria texto que representa o lucro do caixa no mes
*
* @details lucro do caixa = salarioDoCaixa * tempoDeTrabalho / mes
*
* @return String com nome do caixa + lucro do caixa
*/
std::string Supermarket::profitOfCashiers() const {
std::stringstream string;
for (Queue<Cashier>::const_iterator cashier = _cashiers.begin(); cashier != _cashiers.end(); ++cashier) {
double cashierCost = cashier->salary() * (_totalRuntime - cashier->timeOfArrival()) / 756000;
if (cashier->overTime()) {
cashierCost *= 2;
}
string << cashier->id() << "\t\t\t" << cashier->totalIncome() - cashierCost << std::endl;
}
return string.str();
}
/**
* @brief Calcula o total do dinheiro recebido por todos os caixas
*
* @return A soma do dinheiro recebido por todos os caixas
*/
double Supermarket::totalIncome() const {
double totalIncome = 0;
for (int i = 0; i < _cashiers.size(); ++i) {
totalIncome += _cashiers.at(i).totalIncome();
}
return totalIncome;
}
/**
* @brief Calcula a media do dinheiro recebido por cada caixa
* @details Divide o dinheiro recebido total pelo numero de caixas
* @return A media recebida de dinheiro por caixa
*/
double Supermarket::averageIncomePerCashier() const {
return totalIncome() / _cashiers.size();
}
/**
* @brief Calcula o tempo medio de espera por cliente
* @return A media do tempo de espera por cliente
*/
double Supermarket::averageWaitingTime() const {
double totalWaitingTime = 0;
int totalClientsServed = 0;
for (int i = 0; i < _cashiers.size(); ++i) {
totalWaitingTime += _cashiers.at(i).totalWaitingTime();
totalClientsServed += _cashiers.at(i).clientsServed();
}
return totalWaitingTime / totalClientsServed;
}
/**
* @brief Retorna o nome do supermercado
*/
std::string Supermarket::name() const {
return _name;
}
/**
* @brief Retorna o numero de clientes perdidos
*/
int Supermarket::lostClients() const {
return _lostClients;
}
/**
* @brief Retorna o faturamento perdido total
*/
double Supermarket::lostIncome() const {
return _lostIncome;
}