-
Notifications
You must be signed in to change notification settings - Fork 0
/
Drone.cpp
151 lines (129 loc) · 4.4 KB
/
Drone.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
#include <climits>
#include "Drone.h"
#include "Warehouse.h"
#include "Order.h"
Drone::Drone(int id, Point starting_location, int capacity) : m_id(id), m_location(starting_location), m_capacity(capacity) {}
int Drone::getId() const { return m_id; }
Point Drone::getLocation() const { return m_location; }
int Drone::getCapacity() const { return m_capacity; }
// Simulation
void tick() {
//TODO
}
// Order Processing
void Drone::announce(std::vector<Order> &orders) {
// Only Free Drones offer
if(m_state != FREE) {
return;
}
m_costs.clear();
int min_cost = INT_MAX;
int optimal_order_id = -1;
OrderPlan optimal_plan;
// Loop over each order
// If the order is not CLAIMED, keep track of personal cost to complete that order
for(auto it : orders) {
if(it.isClaimed()) {
continue;
}
int cost;
OrderPlan plan;
std::tie(cost,plan) = determineCost(&it);
if(cost < min_cost) {
min_cost = cost;
optimal_order_id = it.getId();
optimal_plan = plan;
}
m_costs.insert({&it,cost});
}
// Make the offer to the best order
for(auto it : orders) {
if(it.getId() == optimal_order_id) {
it.makeOffer(this, m_costs.at(&it));
m_order_plan = optimal_plan;
// Remove from cost map
m_costs.erase(&it);
break;
}
}
}
void Drone::reannounce() {
// Only Free Drones reannounce
if(m_state != FREE) {
return;
}
// Remove next optimal order from map
int min_cost = INT_MAX;
int optimal_order_id = -1;
for(auto e : m_costs) {
if(e.second < min_cost) {
min_cost = e.second;
optimal_order_id = e.first->getId();
}
}
// Make offer to that order
for(auto e : m_costs) {
if(e.first->getId() == optimal_order_id) {
m_order_plan = determineCost(e.first).second;
e.first->makeOffer(this, min_cost);
// Remove from cost map
m_costs.erase(e.first);
break;
}
}
}
void Drone::makeReservations() {
//TODO take weight into account
std::vector<std::pair<Warehouse*, Product>> history;
// Loop over the plan
for(auto e : m_order_plan) {
for(auto it : e.second) {
try {
// At each warehouse, make reservations for its products
e.first->reserveProduct(it);
history.push_back({e.first,it});
} catch(OutOfStockException e) {
// If reservation fails, rollback previous reservations and cancel OFFER at order
for(auto it : history) {
it.first->addProduct(it.second);
}
m_accepted_order->reject();
m_accepted_order = nullptr;
m_order_plan.clear();
m_state = FREE;
}
}
}
}
void Drone::accept(Order *order) {
// Only FREE drones can ACCEPT
if(m_state == FREE) {
m_state = ACCEPTED;
m_accepted_order = order;
}
}
void Drone::cancel() {
// Only an ACCEPTED drone can be cancelled
if(m_state == ACCEPTED) {
m_state = FREE;
}
}
bool Drone::hasUnaccepted(std::vector<Drone> &drones) {
for(auto it : drones) {
if(it.m_state != ACCEPTED) {
return true;
}
}
return false;
}
bool Drone::hasFree(std::vector<Drone> &drones) {
for(auto it : drones) {
if(it.m_state == FREE) {
return true;
}
}
return false;
}
std::pair<int,OrderPlan> Drone::determineCost(Order * order) {
// TODO
}