resourceplacement.cpp

Go to the documentation of this file.
00001 // C++ Implementation: resourceplacement
00002 //
00003 // Description:
00004 //
00005 //
00006 // Author: Martin Bickel <bickel@asc-hq.org>, (C) 2004
00007 //
00008 // Copyright: See COPYING file that comes with this distribution
00009 //
00010 //
00011 #include <cstdlib>
00012 #include <ctime>
00013 #include <cmath>
00014 #include <iostream>
00015 
00016 #include "resourceplacement.h"
00017 
00018 const int ResourcePlacement::MAXFUELVALUE = 255;
00019 const int ResourcePlacement::MAXMATERIALVALUE = 255;
00020 const int ResourcePlacement::MINFUELVALUE = 0;
00021 const int ResourcePlacement::MINMATERIALVALUE = 0;
00022 
00023 ResourcePlacement::ResourcePlacement(GameMap& m,double fr, double mr, unsigned short maxFOffset, unsigned short maxMOffset, int addFreeFieldsPercFuel, int addFreeFieldsPercMaterial):
00024       map(m), fuelRoughness(fr), materialRoughness(fr), maxFuelOffset(maxFOffset), maxMaterialOffset(maxMOffset), 
00025       additionalResourceFreeFieldsPercentageFuel(addFreeFieldsPercFuel), additionalResourceFreeFieldsPercentageMaterial(addFreeFieldsPercMaterial), stepCount(0)
00026 {
00027   double depth = 0.0;
00028   srand(static_cast<unsigned>(time(0)));
00029   if(map.xsize > map.ysize) {
00030     depth = map.ysize;
00031   } else {
00032     depth = map.xsize ;
00033   }
00034   if(fuelRoughness > 4.0)
00035     fuelRoughness = 4.0;
00036   else if(fuelRoughness < 0.1)
00037     fuelRoughness = 0.1;
00038 
00039   if(materialRoughness > 4.0)
00040     materialRoughness = 4.0;
00041   else if(materialRoughness < 0.1)
00042     materialRoughness = 0.1;
00043          
00044 }
00045 
00046 
00047 ResourcePlacement::~ResourcePlacement() {}
00048 
00049 void ResourcePlacement::placeResources() {
00050   placeFuel = true;
00051   placeMaterial = true;
00052   runDS();
00053 }
00054 
00055 void ResourcePlacement::placeFuelResources() {
00056   placeFuel = true;
00057   placeMaterial = false;
00058   runDS();
00059 }
00060 
00061 void ResourcePlacement::placeMaterialResources() {
00062   placeFuel = false;
00063   placeMaterial = true;
00064   runDS();
00065 }
00066 
00067 
00068 void ResourcePlacement::runDS() {
00069   tfield* a = map.getField(0,0);
00070   tfield* b = map.getField( map.xsize -1, 0 );
00071   tfield* c = map.getField(map.xsize -1, map.ysize -1);
00072   // tfield* e = map.getField((map.xsize -1)/2, (map.ysize -1)/2);  //First diamond point
00073   tfield* d = map.getField(0, map.ysize -1 );
00074   if(placeFuel) {   
00075     a->temp3 = createRandomValue(MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel/100 ));    
00076     b->temp3 = createRandomValue(MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel/100 ));    
00077     c->temp3 = createRandomValue(MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel/100 ));    
00078     d->temp3 = createRandomValue(MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel/100 ));
00079     
00080     
00081     setFieldValueFuel(a);    
00082     setFieldValueFuel(b);
00083     setFieldValueFuel(c);
00084     setFieldValueFuel(d);
00085   }
00086   if(placeMaterial) {
00087     c->temp4 = createRandomValue(MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial/100 ));
00088     d->temp4 = createRandomValue(MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial/100 ));
00089     a->temp4 = createRandomValue(MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial/100 ));
00090     b->temp4 = createRandomValue(MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial/100 ));
00091     
00092     setFieldValueMaterial(a);    
00093     setFieldValueMaterial(b);
00094     setFieldValueMaterial(c);
00095     setFieldValueMaterial(d);
00096   }
00097   Rect r ={a, b, c, d};
00098   step(r);
00099 }
00100 
00101 
00102 
00103 
00104 tfield* ResourcePlacement::calculateCornerPoint(tfield* a, tfield* b, tfield* diamondPoint) {
00105   int x = 0;
00106   int y = 0;  
00107   if((a->getx() == b->getx())) {
00108     x = a->getx();
00109     
00110   } else {    
00111     x = diamondPoint->getx();     
00112   }  
00113   if(a->gety() == b->gety()){
00114     y = a->gety();
00115   }else{
00116      y = diamondPoint->gety();
00117   }
00118   tfield* cornerPoint = map.getField(x,y);
00119   if(placeFuel) {
00120     cornerPoint->temp3  = calculateCornerValueFuel(a, b, diamondPoint);
00121     setFieldValueFuel(cornerPoint);
00122   }
00123   if(placeMaterial) {
00124     cornerPoint->temp4  = calculateCornerValueMaterial(a, b, diamondPoint);
00125     setFieldValueMaterial(cornerPoint);
00126   }
00127   return cornerPoint;
00128 }
00129 
00130 void ResourcePlacement::step(Rect r) { 
00131   ++stepCount;
00132   tfield* diamondPoint = calculateDiamondPoint(r.a, r.b, r.c, r.d);
00133   tfield* f = calculateCornerPoint(r.a, r.b, diamondPoint);
00134   tfield* g = calculateCornerPoint(r.b, r.c, diamondPoint);
00135   tfield* h = calculateCornerPoint(r.d, r.c, diamondPoint);
00136   tfield* i = calculateCornerPoint(r.a, r.d, diamondPoint);
00137 
00138   Rect r1 ={r.a, f, diamondPoint, i};
00139   Rect r2 ={f, r.b, g, diamondPoint};
00140   Rect r3 ={diamondPoint, g, r.c, h};
00141   Rect r4 ={i, diamondPoint, h, r.d};
00142 
00143   if(!((f->getx()- r.a->getx()<2)&& (diamondPoint->gety()-f->gety()<2))) {
00144     //cout << "r.a: " << r.a->getx() << "," << r.a->gety() << " f: " << f->getx() << "," << f->gety() << " diamondPoint: " << diamondPoint->getx() << "," << diamondPoint->gety() << "i: " << i->getx() << "," << i->gety() << endl;
00145     step(r1);
00146   }
00147   if(!((r.b->getx()-f->getx()<2)&&(diamondPoint->gety() - r.b->gety() <2))) {
00148     //cout << " f: " << f << "r.b: " << r.b << "g: " << g  <<" diamondPoint: " << diamondPoint <<  endl;
00149     step(r2);
00150   }
00151   if(!((g->getx() - diamondPoint->getx() < 2) && (r.c->gety()-g->gety()<2))) {
00152     //cout << "g: " << g->getx() << "," << g->gety()<< " diamond: " << diamondPoint->getx()<< "," << diamondPoint->gety() << " c: " << r.c->getx()<< "," << r.c->gety() << " h: " << h->getx() << "," << h->gety() << endl;
00153     step(r3);
00154   }
00155   if(!((diamondPoint->getx()-i->getx()<2)&&(r.d->gety()-diamondPoint->gety()<2))) {
00156     step(r4);
00157   }  
00158   --stepCount;
00159 }
00160 
00161 
00162 tfield* ResourcePlacement::calculateDiamondPoint(tfield* a, tfield* b, tfield* c, tfield* d) {
00163   int x = 0;
00164   int y = 0;
00165   double xd = (b->getx() - a->getx())/2;
00166   double yd = (d->gety() - a->gety())/2;
00167   x =  static_cast<int>(xd) + a->getx();
00168   y = static_cast<int>(yd)  + a->gety();
00169   tfield* e = map.getField(x, y);
00170   if(placeFuel) {
00171     e->temp3 = calculateDiamondValueFuel(a, b, c, d);
00172     setFieldValueFuel(e);
00173     
00174   }
00175   if(placeMaterial) {
00176     e->temp4  = calculateDiamondValueMaterial(a, b, c, d);
00177     setFieldValueMaterial(e);
00178   }
00179   return e;
00180 }
00181 
00182 unsigned short ResourcePlacement::createRandomValue(int limit) {
00183   if(limit == 0){
00184     return 1;
00185   }
00186   int random_integer = rand();
00187   return (random_integer % limit);
00188 }
00189 
00190 short ResourcePlacement::createAlgebraicSign() {
00191   int random_integer = rand();
00192   random_integer = random_integer % 2;
00193   if(random_integer == 0)
00194     return -1;
00195   else
00196     return 1;
00197 }
00198 
00199 int ResourcePlacement::calculateCornerValueFuel(tfield* a, tfield* b, tfield* c) {
00200   int value = (a->temp3 + b->temp3 + c->temp3)/3 + createRandomValue(static_cast<int>(calculateCurrentOffset(maxFuelOffset) * fuelRoughness))* createAlgebraicSign();
00201   if(value > MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel / 100)) {
00202     value = MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel /100);
00203   } else if( value < MINFUELVALUE) {
00204     value = MINFUELVALUE;
00205   }  
00206   return value;
00207 }
00208 
00209 
00210 int ResourcePlacement::calculateDiamondValueFuel(tfield* a, tfield* b, tfield* c, tfield* d) {
00211   int value = static_cast<int>((a->temp3 + b->temp3 + c->temp3 + d->temp3)/4 + createRandomValue(static_cast<int>(calculateCurrentOffset(maxFuelOffset) * fuelRoughness)) * createAlgebraicSign());
00212   if(value > MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel / 100)) {
00213     value = MAXFUELVALUE * (1 + additionalResourceFreeFieldsPercentageFuel /100);
00214   } else if( value < MINFUELVALUE) {
00215     value = MINFUELVALUE;
00216   }
00217   return value;
00218 }
00219 
00220 int ResourcePlacement::calculateCornerValueMaterial(tfield* a, tfield* b, tfield* c) {
00221   int value = (a->temp4 + b->temp4 + c->temp4)/3 + createRandomValue(static_cast<int>(calculateCurrentOffset(maxMaterialOffset) * materialRoughness ) * createAlgebraicSign());
00222   if(value > MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial / 100)) {
00223     value = MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial / 100);
00224   } else if( value < MINMATERIALVALUE) {
00225     value = MINMATERIALVALUE;
00226   }
00227   return value;
00228 }
00229 
00230 int ResourcePlacement::calculateDiamondValueMaterial(tfield* a, tfield* b, tfield* c, tfield* d) {
00231   int value = (a->temp4 + b->temp4 + c->temp4 + d->temp4)/4 + createRandomValue(static_cast<int>(calculateCurrentOffset(maxMaterialOffset)* materialRoughness)) * createAlgebraicSign();
00232   if(value > MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial / 100)) {
00233     value = MAXMATERIALVALUE * (1 + additionalResourceFreeFieldsPercentageMaterial / 100);
00234   } else if( value < MINMATERIALVALUE) {
00235     value = MINMATERIALVALUE;
00236   }
00237   return value;
00238 }
00239 
00240 int ResourcePlacement::calculateCurrentOffset(int currentOffset) {
00241   return  currentOffset / stepCount;
00242 }
00243 
00244 void ResourcePlacement::setFieldValueFuel(tfield* f){   
00245    int value = f->temp3 -( MAXFUELVALUE * additionalResourceFreeFieldsPercentageFuel/100);
00246    if(value < MINFUELVALUE) {    
00247      f->fuel = MINFUELVALUE;
00248    }else{
00249      f->fuel = value;
00250    }                
00251 }
00252 
00253 void ResourcePlacement::setFieldValueMaterial(tfield* f){   
00254    int value = f->temp4 -( MAXMATERIALVALUE * additionalResourceFreeFieldsPercentageMaterial/100);
00255    if(value < MINMATERIALVALUE) {    
00256      f->material = MINMATERIALVALUE;
00257    }else{
00258      f->material = value;
00259    }                
00260 }
00261 

Generated on Mon Jan 5 01:28:24 2009 for Advanced Strategic Command by  doxygen 1.5.1