00001
00002
00003
00004
00005
00006
00007
00008
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
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
00145 step(r1);
00146 }
00147 if(!((r.b->getx()-f->getx()<2)&&(diamondPoint->gety() - r.b->gety() <2))) {
00148
00149 step(r2);
00150 }
00151 if(!((g->getx() - diamondPoint->getx() < 2) && (r.c->gety()-g->gety()<2))) {
00152
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