src/Cargo.cpp

Go to the documentation of this file.
00001 /* Crown and Cutlass
00002  * Cargo Object Code
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   // Nothing really needs to happen
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   // Loop through all but last
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     // If it's full, there's no sense in keeping going
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     // Should throw exception
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     // Should throw exception
00187     Log::s_log->Message("Warning: filled attribute missing in cargo node");
00188     return;
00189   }
00190 
00191   if (filled > size) {
00192     // Should throw an exception
00193     Log::s_log->Message("Warning: filled > size");
00194     return;
00195   }
00196 
00197   // Load the actual products
00198   prodsElem = selfNode->FirstChildElement("Products");
00199   if (prodsElem == NULL) {
00200     // Should throw an exception
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       // Should throw exception
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       // It's not the product we expected
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       // Should throw exception
00220       Log::s_log->Message("Warning: qty attribute missing in cargo product node");
00221       return;
00222     }
00223 
00224     products[prodIndex] = tempQty;
00225 
00226     // Increment the sum
00227     sumQty += tempQty;
00228 
00229     // Move on to the next product
00230     prodIndex++;
00231   }
00232 
00233   // Make sure the actual qty matches the expected qty
00234   if (sumQty != filled) {
00235     // Should throw an exception
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 }

Generated on Mon Jan 8 22:34:12 2007 for CrownandCutlass by  doxygen 1.4.7