-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathItemsManager.cpp
More file actions
365 lines (304 loc) · 11.7 KB
/
ItemsManager.cpp
File metadata and controls
365 lines (304 loc) · 11.7 KB
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
// Blake Berry
// 03/08/2022
// Homework 4
// This file is an implimentation for the ItemManager class. The ItemManager
// class has a collectible Factory and stores a sorted inventory seperated
// by collectible type. The ItemManager class is responsible for making sure
// an item to be acted on is valid or in the store. It is reponsible for
// filling in the stores initial inventory
//-----------------------------------------------------------------------------
#include "ItemsManager.h"
//------------------------ getItemType ------------------------------------
// Processes a line of instructions getting the item type from them and
// returning it
// Postconditions: The item type must be 1 char and must be the first char
// in the instructions
std::string ItemsManager::getItemType(std::string& instructions) const
{
char collectibleTypeChar = instructions[0];
std::string type = "";
type.push_back(collectibleTypeChar);
instructions.erase(0, 1);
return type;
}
//------------------------ getQuantity -------------------------------------
// Processes a line of input instructions extracting the quantity of a given
// item
// Preconditions : The instructions must lead with ", "
// Postconditions: returns the quantity if valid and returns -1
// if invalid
int ItemsManager::getQuantity(std::string& instructions) const
{
// get rid of the leading ", "
instructions.erase(0, 2);
int numberStart = 0;
int numberEnd = 0;
bool validNumber = false;
// if its valid mark it so
while (std::isdigit(instructions[numberEnd])) {
validNumber = true;
numberEnd++;
}
if (!validNumber) {
// invalid inventory
return -1;
}
else {
std::string stringCopies = instructions.substr(numberStart, numberEnd);
int copies = std::stoi(stringCopies);
instructions.erase(numberStart, numberEnd);
return copies;
}
}
//------------------------ getItemShell ------------------------------------
// Takes a given string and checks the item factory for a collectible of
// that type.
// Postconditions: returns a pointer to a dummy item of the correct type
// otherwise an error is thrown
const Collectible* ItemsManager::getItemShell(std::string& type) const
{
const Collectible* itemShell = makeCollectibles_.create(type);
if (itemShell == nullptr) {
throw CollectiblesStoreError("Invalid Item Type");
}
else {
return itemShell;
}
}
int ItemsManager::getInventoryAmount(std::string& item) const
{
int number = getQuantity(item);
if (number <= 0) {
throw CollectiblesStoreError("Invalid Item Quantity");
}
else {
return number;
}
}
//------------------------ hashStoreInventory ------------------------------
// Creates an index in the invertory for a given item type
// Preconditions : Each collectible must have a unique item type
// the first char must between 'A' and 'Z' inclusive
// Postconditions: returns a hash for an item type
int ItemsManager::hashStoreInventory(std::string itemType) const
{
return itemType[0] - 'A';
}
//-------------------------- Default Constructor ---------------------------
// Creates an Item manager with a fully working factory and an empty
// inventory
// Preconditions : The factory must be intialized with the items that are
// allowed in the collections store
// Postconditions: a new item manager is created
ItemsManager::ItemsManager() :
makeCollectibles_(CollectionFactory()),
betterInventory_(nullptr)
{
// really need to make a size variable
betterInventory_ = new SearchTree * [NUM_ITEM_TYPES];
for (int i = 0; i < NUM_ITEM_TYPES; i++) {
betterInventory_[i] = new SearchTree();
}
}
//-------------------------- Destructor -----------------------------------
// Frees any dynamic memory associated with the items manager class
// Preconditions : The factory must be capable to freeing its dynamic memory
//
// the items inventory must be capable of freeing its
// dynamic memory
//
// Postconditions: frees the memory associated with the items manager
ItemsManager::~ItemsManager()
{
for (int i = 0; i < NUM_ITEM_TYPES; i++) {
delete betterInventory_[i];
betterInventory_[i] = nullptr;
}
delete[] betterInventory_;
}
//-------------------------- FillInventory ---------------------------------
// Fills the inventory from a file, Coins are index 0, Comics are index 2,
// and SportsCards are index 3
// Preconditions : The factory must be initialized
//
// The file must be formatted correctly
//
// Postconditions: The ItemManagers inventory is filled, exceptions are
// thrown if invalid data is attempted
void ItemsManager::fillInventory(std::ifstream& inFile)
{
std::vector<std::string> errorList;
bool errorFound = false;
std::string curItem = "";
int lineItem = 1;
while (inFile.peek() != EOF) {
std::getline(inFile, curItem);
// we have the type
std::string collectibleType = getItemType(curItem);
// creates a itemShell (does not create memory)
const Collectible* itemShell = nullptr;
try {
itemShell = getItemShell(collectibleType);
}
catch (CollectiblesStoreError err) {
errorFound = true;
std::string message = err.what();
std::string onLine = " on Line ";
errorList.push_back(err.what() + onLine + std::to_string(lineItem));
lineItem++;
continue;
}
int inventoryAmount = 0;
try {
inventoryAmount = getInventoryAmount(curItem);
}
catch (CollectiblesStoreError err) {
errorFound = true;
std::string message = err.what();
std::string onLine = " on Line ";
errorList.push_back(err.what() + onLine + std::to_string(lineItem));
lineItem++;
continue;
}
const Collectible* itemToAdd = nullptr;
try {
// new memory
itemToAdd = itemShell->create(curItem);
}
catch (CollectiblesStoreError err) {
errorFound = true;
delete itemToAdd;
std::string message = err.what();
std::string onLine = " on Line ";
errorList.push_back(err.what() + onLine + std::to_string(lineItem));
lineItem++;
continue;
}
int numAdded = 0;
const Comparable* comparableToAdd = nullptr;
comparableToAdd = static_cast<const Comparable*>(itemToAdd);
// add the item to the invetory to meet quanitity
while (numAdded < inventoryAmount) {
int inventoryIndex = hashStoreInventory(itemToAdd->getID());
betterInventory_[inventoryIndex]->insert(comparableToAdd);
numAdded++;
}
lineItem++;
}
// if there are errors print
if (errorFound) {
std::string boarder1 = "------------";
std::string boarder2 = "-------------------";
std::cout << boarder1 + " Filling Inventory Errors" + boarder2
<< std::endl;
int size = errorList.size();
for (int i = 0; i < size; i++) {
std::cout << errorList[i] << std::endl;
}
std::cout << std::endl;
}
}
//-------------------------- ManageBuying ---------------------------------
// Given the ID of an item them method handles the purchase of an item
// if the item is present its inventory count is decrimented appropriately
// Preconditions : the hashable object frees its own dynamically allocated
// memory
//
// The factory must be initalized
//
// Postconditions: An item is sold and the inventory is updated and true
// is returned. Throws an error if an invalid item is
// attempted to be purchased
const Collectible* ItemsManager::manageBuying(std::string collectible)
{
// we have the type
std::string collectibleType = getItemType(collectible);
// we know the first is the customer number
const Collectible* itemShell = makeCollectibles_.create(collectibleType);
if (itemShell == nullptr) {
throw CollectiblesStoreError("Cannot Process Purchase " + collectible);
}
// this statement will throw bc create throws makes new
const Collectible* itemToBuy = itemShell->create(collectible);
const Comparable* comparableToBuy = nullptr;
comparableToBuy = static_cast<const Comparable*>(itemToBuy);
// assured to be valid
int inventoryIndex = hashStoreInventory(itemToBuy->getID());
if (!(betterInventory_[inventoryIndex]->insert(comparableToBuy))) {
const Comparable* actedOn = nullptr;
actedOn = betterInventory_[inventoryIndex]->retrieve(*comparableToBuy);
delete itemToBuy;
return static_cast<const Collectible*>(actedOn);
}
else {
return itemToBuy;
}
}
//-------------------------- ManageSelling ---------------------------------
// Given the ID of an item them method handles the sale of an item
// if the item is present its inventory count is incrimented appropriately
// Preconditions : the hashable object frees its own dynamically allocated
// memory
//
// The factory must be initalized
//
// Postconditions: An item is sold and the inventory is updated and true
// is returned. Throws an error if an invalid item is
// attempted to be sold
const Collectible* ItemsManager::manageSelling(std::string collectible)
{
std::string origin = collectible;
std::string err1 = "Cannot Process Sale";
// we have the type
std::string collectibleType = getItemType(collectible);
// we know the first is the customer number
//try
// creates a itemShell (does not create memory)
const Collectible* itemShell = makeCollectibles_.create(collectibleType);
//catch
if (itemShell == nullptr) {
throw CollectiblesStoreError(err1+" Invalid Item Type " + collectible);
}
// throws its own errors makes new memory
const Collectible* itemToBuy = itemShell->create(collectible);
const Comparable* comparableToBuy = nullptr;
comparableToBuy = static_cast<const Comparable*>(itemToBuy);
int inventoryIndex = hashStoreInventory(itemToBuy->getID());
// if it fails to remove an item free the memory and report back
if (!betterInventory_[inventoryIndex]->remove(*comparableToBuy)) {
delete itemToBuy;
throw CollectiblesStoreError(origin+" is out of stock cannot be sold\n");
}
// if the item is removed successfully then go ahead and return it
else {
const Comparable* actedOn = nullptr;
actedOn = betterInventory_[inventoryIndex]->retrieve(*comparableToBuy);
delete itemToBuy;
return static_cast<const Collectible*>(actedOn);
}
}
//-------------------------- showInventory ---------------------------------
// Shows the inventory in a specified ordered, coins, comics, then
// sports cards
// Preconditions : the search tree and comparables must be printable
//
// Postconditions: prints the items to the console in the above order.
void ItemsManager::showInventory() const
{
std::string boarder1 = "----------------------";
std::string boarder2 = "----------------------------";
std::cout << boarder1 + " Inventory " + boarder2 << std::endl;
std::vector<Collectible*> printInOrder;
Coin first;
Comic second;
SportsCard third;
printInOrder.push_back(static_cast<Collectible*>(&first));
printInOrder.push_back(static_cast<Collectible*>(&second));
printInOrder.push_back(static_cast<Collectible*>(&third));
int printInOrderSize = printInOrder.size();
for (int i = 0; i < printInOrderSize; i++) {
int index = hashStoreInventory(printInOrder[i]->getID());
std::cout << *betterInventory_[index];
}
std::cout << "\n" << std::endl;
}