00001
00002
00003
00004
00005 #include <vector>
00006 #include <string>
00007 #include "Log.h"
00008 #include "ccmath.h"
00009 #include "Economy.h"
00010 #include "ISaveObject.h"
00011 #include "Cargo.h"
00012
00013 Cargo::Cargo(string nameIn, unsigned int sizeIn): ISaveObject("Cargo") {
00014 size = sizeIn;
00015
00016 name = nameIn;
00017
00018 Clear();
00019 }
00020
00021 Cargo::~Cargo() {
00022 Log::s_log->Message("Deleting " + name);
00023
00024 products.clear();
00025 }
00026
00027 void Cargo::Clear() {
00028 filled = 0;
00029
00030 products.resize(Economy::s_economy->ProductCount());
00031
00032 for (unsigned int i = 0; i < products.size(); i++) {
00033 products[i] = 0;
00034 }
00035 }
00036
00037 unsigned int Cargo::GetFilled() {
00038 return filled;
00039 }
00040
00041 unsigned int Cargo::GetSize() {
00042 return size;
00043 }
00044
00045 void Cargo::SetSize(unsigned int sizeIn) {
00046 size = sizeIn;
00047 }
00048
00049 unsigned int Cargo::GetAvailQty() {
00050 return size - filled;
00051 }
00052
00053 unsigned int Cargo::GetQty(unsigned int product) throw ( const char *) {
00054 if (product >= products.size()) {
00055 throw "Invalid product";
00056 }
00057
00058 return products[product];
00059 }
00060
00061 void Cargo::SetQty(unsigned int product, unsigned int qty) throw ( const char *) {
00062 unsigned int oldQty;
00063
00064 if (product >= products.size()) {
00065 throw "Invalid product";
00066 }
00067
00068 oldQty = products[product];
00069 products[product] = qty;
00070
00071 filled = filled + (qty - oldQty);
00072 }
00073
00074 unsigned int Cargo::AddQty(unsigned int product, int qty) throw ( const char *) {
00075 if (product >= products.size()) {
00076 throw "Invalid product";
00077 }
00078 if ((qty < 0) && (-1*qty > products[product])) {
00079 throw "Result would be negative";
00080 }
00081
00082 products[product] = products[product] + qty;
00083 filled += qty;
00084
00085 return products[product];
00086 }
00087
00088 void Cargo::AddCargo(shared_ptr<Cargo> cargo) throw ( const char *) {
00089 int i;
00090 unsigned int qty;
00091
00092 if (cargo->products.size() != products.size()) {
00093 throw "Could not AddCargo (sizes do not match)";
00094 }
00095
00096 Log::s_log->Message("Prod.size: %d", products.size());
00097
00098 for (i = products.size() - 1; i >= 0; i--) {
00099 if (GetAvailQty() == 0) break;
00100
00101
00102 Log::s_log->Message("Avail: %d", GetAvailQty());
00103 Log::s_log->Message("i: %d", i);
00104
00105 qty = min(cargo->GetQty(i), GetAvailQty());
00106 cargo->AddQty(i, -1 * qty);
00107 AddQty(i, qty);
00108 }
00109 }
00110
00111 void Cargo::FillRandom() throw ( const char*) {
00112 FillRandom((int) (size * randBellCurve()));
00113 }
00114
00115 void Cargo::FillRandom(unsigned int qty) throw ( const char *) {
00116 unsigned int avgQty;
00117 unsigned int tempQty;
00118
00119 if (qty > size) {
00120 throw "Qty greater than size";
00121 }
00122
00123 avgQty = qty / products.size();
00124 Log::s_log->Message("AvgQty: %u", avgQty);
00125
00126
00127 for (unsigned int i = 0; i < (products.size() - 1); i++) {
00128 tempQty = (int) ((randBellCurve() + .5) * avgQty);
00129 if (tempQty > GetAvailQty()) {
00130 tempQty = GetAvailQty();
00131 }
00132
00133 products[i] = tempQty;
00134
00135 filled += tempQty;
00136
00137
00138 if (GetAvailQty() == 0) {
00139 break;
00140 }
00141 }
00142
00143 products[products.size()-1] = qty - filled;
00144 filled = qty;
00145 }
00146
00147 void Cargo::Save(TiXmlElement *parent) {
00148 unsigned int i;
00149 TiXmlElement selfNode(m_XMLName);
00150 TiXmlElement prodsElem("Products");
00151 TiXmlElement tElement("Product");
00152
00153 for (i = 0; i < products.size(); i++) {
00154 tElement.Clear();
00155 tElement.SetAttribute("name", Economy::s_economy->ProdList[i]);
00156 tElement.SetAttribute("qty", products[i]);
00157 prodsElem.InsertEndChild(tElement);
00158 }
00159
00160 selfNode.SetAttribute("size", size);
00161 selfNode.SetAttribute("filled", filled);
00162 selfNode.InsertEndChild(prodsElem);
00163
00164 parent->InsertEndChild(selfNode);
00165 }
00166
00167 void Cargo::Load(TiXmlElement *parent) {
00168 TiXmlElement *selfNode;
00169 TiXmlElement *prodsElem;
00170 TiXmlElement *node;
00171 unsigned int sumQty = 0;
00172 unsigned int prodIndex = 0;
00173 unsigned int tempQty;
00174
00175 Clear();
00176
00177 selfNode = parent->FirstChildElement(m_XMLName);
00178
00179 if (selfNode->QueryIntAttribute("size", (int *) &size) != TIXML_SUCCESS) {
00180
00181 Log::s_log->Message("Warning: size attribute missing in cargo node");
00182 return;
00183 }
00184
00185 if (selfNode->QueryIntAttribute("filled", (int *) &filled) != TIXML_SUCCESS) {
00186
00187 Log::s_log->Message("Warning: filled attribute missing in cargo node");
00188 return;
00189 }
00190
00191 if (filled > size) {
00192
00193 Log::s_log->Message("Warning: filled > size");
00194 return;
00195 }
00196
00197
00198 prodsElem = selfNode->FirstChildElement("Products");
00199 if (prodsElem == NULL) {
00200
00201 Log::s_log->Message("Warning: Could not find Products node");
00202 return;
00203 }
00204
00205 for (node = prodsElem->FirstChildElement("Product"); node; node = node->NextSiblingElement("Product")) {
00206 if (prodIndex >= products.size()) {
00207
00208 Log::s_log->Message("Warning: Too many products in cargo node");
00209 return;
00210 }
00211
00212 if (string(node->Attribute("name")) != Economy::s_economy->ProdList[prodIndex]) {
00213
00214 Log::s_log->Message("Warning: expected product \"%s\", found \"%s\"", Economy::s_economy->ProdList[prodIndex].c_str(), node->Attribute("name"));
00215 return;
00216 }
00217
00218 if (node->QueryIntAttribute("qty", (int *) &tempQty) != TIXML_SUCCESS) {
00219
00220 Log::s_log->Message("Warning: qty attribute missing in cargo product node");
00221 return;
00222 }
00223
00224 products[prodIndex] = tempQty;
00225
00226
00227 sumQty += tempQty;
00228
00229
00230 prodIndex++;
00231 }
00232
00233
00234 if (sumQty != filled) {
00235
00236 Log::s_log->Message("Warning: Filled qty (%d) does not equal sum of products (%d)", filled, sumQty);
00237 return;
00238 }
00239 }
00240
00241 void Cargo::Dump() {
00242 Log::s_log->Message("%s", name.c_str());
00243 Log::s_log->Message("Size:\t%u", size);
00244 Log::s_log->Message("Filled:\t%u", filled);
00245
00246 for (unsigned int i = 0; i < products.size(); i++) {
00247 Log::s_log->Message("%s:\t%u", Economy::s_economy->ProdList[i].c_str(), products[i]);
00248 }
00249 }