Shadowrun: Awakened 29 September 2011 - Build 871
polymain.cpp
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 Intel Corporation.  All Rights Reserved.
00003 
00004     This file is part of Threading Building Blocks.
00005 
00006     Threading Building Blocks is free software; you can redistribute it
00007     and/or modify it under the terms of the GNU General Public License
00008     version 2 as published by the Free Software Foundation.
00009 
00010     Threading Building Blocks is distributed in the hope that it will be
00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Threading Building Blocks; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 
00019     As a special exception, you may use this file as part of a free software
00020     library without restriction.  Specifically, if other files instantiate
00021     templates or use macros or inline functions from this file, or you compile
00022     this file and link it with other files to produce an executable, this
00023     file does not by itself cause the resulting executable to be covered by
00024     the GNU General Public License.  This exception does not however
00025     invalidate any other reasons why the executable file might be covered by
00026     the GNU General Public License.
00027 */
00028 
00029 // Polygon overlay
00030 //
00031 // Don't want warnings about deprecated sscanf, getenv
00032 #ifndef _CRT_SECURE_NO_DEPRECATE
00033 #define _CRT_SECURE_NO_DEPRECATE
00034 #endif
00035 #define _MAIN_C_ 1
00036 #include <iostream>
00037 #include <iomanip>
00038 #include <algorithm>
00039 #include <cstring>
00040 
00041 #include "tbb/tick_count.h"
00042 #include "tbb/task_scheduler_init.h"
00043 #include "pover_global.h"
00044 #include "polyover.h"
00045 #include "pover_video.h"
00046 #include "polymain.h"
00047 
00048 using namespace std;
00049 
00050 #if _DEBUG
00051 const char *faceNames[] = { "North", "East", "South", "West" };
00052 #endif
00053 
00056 int main( int argc, char **argv) {
00057     pover_video poly;
00058     poly.threaded = true;
00059     gVideo = &poly;
00060 
00061     if(!initializeVideo(argc, argv)) {
00062         return 1;
00063     }
00064 
00065     gIsGraphicalVersion = poly.graphic_display();
00066     if(argc > 1) {
00067         if(!ParseCmdLine(argc, argv)) {
00068             if(gIsGraphicalVersion) rt_sleep(10000);
00069             // if graphical, we haven't opened the console window so all the error messages we
00070             // so carefully wrote out disappeared into the ether.  :(
00071             exit(1);
00072         }
00073     }
00074 
00075     if(gCsvFilename != NULL) {
00076 #define BUFLEN 1000
00077         std::string fname_buf = gCsvFilename;
00078         fname_buf += ".csv";
00079         gCsvFile.open(fname_buf.c_str());
00080     }
00081 
00082     // we have gMapXSize and gMapYSize determining the number of "squares"
00083     // we have g_xwinsize and g_ywinsize the total size of the window
00084     // we also have BORDER_SIZE the size of the border between maps
00085     // we need to determine
00086     //      g_polyBoxSize -- the number of pixels on each size of each square
00087 
00088     if(gIsGraphicalVersion) {
00089         int xpixelsPerMap = (g_xwinsize - 4*BORDER_SIZE) / 3;  // three maps, with borders between and outside
00090         gMapXSize = xpixelsPerMap;   // make the boxes one per pixel
00091         gPolyXBoxSize = xpixelsPerMap / gMapXSize;
00092         int ypixelsPerMap = (g_ywinsize - 2*BORDER_SIZE);       // one map vertically
00093         gMapYSize = ypixelsPerMap;   // one pixel per box, rather.
00094 
00095         gPolyYBoxSize = ypixelsPerMap / gMapYSize;
00096         if((gPolyXBoxSize == 0) || (gPolyYBoxSize == 0)) {
00097             cout << "The display window is not large enough to show the maps" << std::endl;
00098             int minxSize = 4*BORDER_SIZE + 3*gMapXSize;
00099             int minySize = 2*BORDER_SIZE + gMapYSize;
00100             cout << "  Should be at least " << minxSize << " x " << minySize << "." << std::endl;
00101             return 1;
00102         }
00103         map2XLoc = 2*BORDER_SIZE + gMapXSize * gPolyXBoxSize;
00104         maprXLoc = 3*BORDER_SIZE + 2 * gMapXSize * gPolyXBoxSize;
00105 
00106     }
00107     else {  // not gIsGraphicalVersion
00108         // gMapXSize, gMapYSize, gNPolygons defined in pover_global.h
00109     }
00110 
00111     // create two polygon maps
00112     SetRandomSeed(gMyRandomSeed);  // for repeatability
00113 
00114     gVideo->main_loop();
00115 }
00116 
00117 void Usage(int argc, char **argv) {
00118     char *cmdTail = strrchr(*argv, '\\');
00119     if(cmdTail == NULL)  {
00120         cmdTail = *argv;
00121     }
00122     else { 
00123         cmdTail++;
00124     }
00125     cout << cmdTail << " [threads[:threads2]] [--polys npolys] [--size nnnxnnn] [--seed nnn]" << std::endl;
00126     cout << "Create polygon maps and overlay them." << std::endl << std::endl;
00127     cout << "Parameters:" << std::endl;
00128     cout << "   threads[:threads2] - number of threads to run" << std::endl;
00129     cout << "   --polys npolys - number of polygons in each map" << std::endl;
00130     cout << "   --size nnnxnnn - size of each map (X x Y)" << std::endl;
00131     cout << "   --seed nnn - initial value of random number generator" << std::endl;
00132     cout << "   --csv filename - write timing data to CSV-format file" << std::endl;
00133     cout << "   --grainsize n - set grainsize to n" << std::endl;
00134     cout << "   --use_malloc - allocate polygons with malloc instead of scalable allocator" << std::endl;
00135     cout << std::endl;
00136     cout << "npolys must be smaller than the size of the map" << std::endl;
00137     cout << std::endl;
00138     exit(1);
00139 }
00140 
00141 bool ParseCmdLine(int argc, char **argv ) {
00142     bool error_found = false;
00143     bool nPolysSpecified = false;
00144     bool nMapSizeSpecified = false;
00145     bool nSeedSpecified = false;
00146     bool csvSpecified = false;
00147     bool grainsizeSpecified = false;
00148     bool mallocSpecified = false;
00149     int origArgc = argc;
00150     char** origArgv = argv;
00151     unsigned int newnPolygons = gNPolygons;
00152     unsigned int newSeed = gMyRandomSeed;
00153     unsigned int newX = gMapXSize;
00154     unsigned int newY = gMapYSize;
00155     unsigned int newGrainSize = gGrainSize;
00156     argc--; argv++;
00157     if(argc > 0 && isdigit((*argv)[0])) {
00158         // first argument is one or two numbers, specifying how mny threads to run
00159         char* end; gThreadsHigh = gThreadsLow = (int)strtol(argv[0],&end,0);
00160         switch( *end) {
00161             case ':': gThreadsHigh = (int)strtol(end+1,0,0); break;
00162             case '\0': break;
00163             default: cout << "Unexpected character in thread specifier: " << *end << std::endl; break;
00164         }
00165         if(gThreadsLow > gThreadsHigh) {
00166             int t = gThreadsLow;
00167             gThreadsLow = gThreadsHigh;
00168             gThreadsHigh = t;
00169         }
00170         argv++; argc--;
00171     }
00172     while(argc > 0) {
00173         // format 1: --size nnnxnnn, where nnn in {0 .. 9}+ -- size of map in "squares"
00174         if(!strncmp("--size", *argv, (size_t)6)) {
00175             if(nMapSizeSpecified) {
00176                 cout << " Error: map size multiply specified" << std::endl;
00177                 error_found = true;
00178             }
00179             else  {
00180                 argv++; argc--;
00181                 if(argc == 0) {
00182                     error_found = true;
00183                     cout << " Error: --size must have a value" << std::endl;
00184                 }
00185                 if(strchr(*argv, 'x') != strrchr(*argv,'x')) {
00186                     // more than one 'x'
00187                     cout << "Error: map size should be nnnxnnn (" << *argv << ")" << std::endl;
00188                     error_found = true;
00189                 }
00190                 else {
00191                     int rval;
00192                     rval = sscanf(*argv, "%ux%u", &newX, &newY);
00193                     if(rval != 2) {
00194                         cout << "Error parsing map size (format should be nnnxnnn (" << *argv << ")" << std::endl;
00195                         error_found = true;
00196                     }
00197                     if(newX == 0 || newY == 0) {
00198                         cout << "Error: size of map should be greater than 0 (" << *argv << ")" << std::endl;
00199                         error_found = true;
00200                     }
00201                 }
00202             }
00203             argc--; argv++;
00204         }
00205         // format 2: --seed nnn -- initial random number seed
00206         else if(!strncmp("--seed", *argv, (size_t)6)) {
00207             argv++; argc--;
00208             if(nSeedSpecified) {
00209                 cout << "Error: new seed multiply specified" << std::endl;
00210                 error_found = true;
00211             }
00212             else {
00213                 nSeedSpecified = true;
00214                 int rtval = sscanf(*argv, "%u", &newSeed);
00215                 if(rtval == 0) {
00216                     cout << "Error: --seed should be an unsigned number (instead of " << *argv << ")" << std::endl;
00217                     error_found = true;
00218                 }
00219             }
00220             argv++; argc--;
00221         }
00222         // format 3: --polys n[n] -- number of polygons in each map
00223         else if(!strncmp("--polys", *argv, (size_t)7)) {
00224             //unsigned int newnPolygons;
00225             argv++; argc--;
00226             if(nPolysSpecified) {
00227                 cout << "Error: number of polygons multiply-specified" << std::endl;
00228                 error_found = true;
00229             }else {
00230                 int rtval = sscanf(*argv, "%u", &newnPolygons);
00231                 if(newnPolygons == 0) {
00232                     cout << "Error: number of polygons must be greater than 0 (" << *argv << ")" << std::endl;
00233                 }
00234             }
00235             argv++; argc--;
00236         }
00237         // format 4: --csv <fileroot> -- name of CSV output file ("xxx" for "xxx.csv")
00238         else if(!strncmp("--csv", *argv, (size_t)5)) {
00239             argv++; argc--;
00240             if(csvSpecified) {
00241                 cout << "Error: Multiple specification of CSV file" << std::endl;
00242                 error_found = true;
00243             }
00244             else {
00245                 gCsvFilename = *argv;
00246                 argv++; argc--;
00247                 csvSpecified = true;
00248             }
00249         }
00250         else if(!strncmp("--grainsize", *argv, (size_t)11)) {
00251             argv++; argc--;
00252             if(grainsizeSpecified) {
00253                 cout << "Error: Multiple specification of grainsize" << std::endl;
00254                 error_found = true;
00255             }
00256             else {
00257                 int grval = sscanf(*argv, "%u", &newGrainSize);
00258                 grainsizeSpecified = true;
00259                 if(newGrainSize == 0) {
00260                     cout << "Error: grainsize must be greater than 0" << std::endl;
00261                     error_found = true;
00262                 }
00263             }
00264             argv++; argc--;
00265         }
00266         else if(!strncmp("--use_malloc", *argv, (size_t)12)) {
00267             argv++; argc--;
00268             if(mallocSpecified) {
00269                 cout << "Error: --use_malloc multiply-specified" << std::endl;
00270                 error_found = true;
00271             }
00272             else {
00273                 mallocSpecified = true;
00274                 gMBehavior = UseMalloc;
00275             }
00276         }
00277         else {
00278             cout << "Error: unrecognized argument: " << *argv << std::endl;
00279             error_found = true;
00280             argv++; argc--;
00281         }
00282     }
00283     if(!error_found) {
00284         if(newX * newY < newnPolygons) {
00285             error_found = true;
00286             cout << "Error: map size should not be smaller than the number of polygons (gNPolygons = " << newnPolygons << ", map size " << newX << "x" << newY << ")" << std::endl;
00287         }
00288     }
00289     if(!error_found) {
00290         gMapXSize = newX;
00291         gMapYSize = newY;
00292         gNPolygons = newnPolygons;
00293         gMyRandomSeed = newSeed;
00294         gGrainSize = (int)newGrainSize;
00295     }
00296     else {
00297         Usage(origArgc, origArgv);
00298     }
00299     return !error_found;
00300 }
00301 
00302 // create a polygon map with at least gNPolygons polygons.
00303 // Usually more than gNPolygons polygons will be generated, because the
00304 // process of growing the polygons results in holes.
00305 bool GenerateMap(Polygon_map_t **newMap, int xSize, int ySize, int gNPolygons, colorcomp_t maxR, colorcomp_t maxG, colorcomp_t maxB) {
00306     bool error_found = false;
00307     int  *validPolys;
00308     int  *validSide;
00309     int maxSides;
00310     RPolygon *newPoly;
00311 
00312     if(xSize <= 0) {
00313         cout << "xSize (" << xSize << ") should be > 0." << std::endl;
00314         error_found = true;
00315     }
00316     if(ySize <= 0) {
00317         cout << "ySize (" << ySize << ") should be > 0." << std::endl;
00318         error_found = true;
00319     }
00320     if(gNPolygons > (xSize * ySize)) {
00321         cout << "gNPolygons (" << gNPolygons << ") should be less than " << (xSize * ySize) << std::endl;
00322         error_found = true;
00323     }
00324     if(error_found) return false;
00325     // the whole map is [xSize x ySize] squares
00326     // the way we create the map is to
00327     //    1) pick nPolygon discrete squares on an [xSize x ySize] grid
00328     //    2) while there are unused squares on the grid
00329     //        3) pick a polygon with a side that has unused squares on a side
00330     //        4) expand the polygon by 1 to occupy the unused squares
00331     //
00332     // Continue until every square on the grid is occupied by a polygon
00333     int *tempMap;
00334     tempMap = (int *)malloc(xSize * ySize * sizeof(int));
00335     for(int i=0;i < xSize; i++) {
00336         for(int j=0;j < ySize; j++) {
00337             tempMap[i*ySize + j] = 0;
00338         }
00339     }
00340 
00341     // *newMap = new vector<RPolygon>;
00342     *newMap = new Polygon_map_t;
00343     (*newMap)->reserve(gNPolygons + 1);  // how much bigger does this need to be on average?
00344     newPoly = RPolygon::alloc_RPolygon(0,0,xSize-1, ySize-1);
00345     (*newMap)->push_back(newPoly);
00346     for(int i=0; i < gNPolygons; i++) {
00347         int nX;
00348         int nY;
00349         do {    // look for an empty square.
00350             nX = NextRan(xSize);
00351             nY = NextRan(ySize);
00352         } while(tempMap[nX * ySize + nY] != 0);
00353         int nR = (maxR * NextRan(1000)) / 999;
00354         int nG = (maxG * NextRan(1000)) / 999;
00355         int nB = (maxB * NextRan(1000)) / 999;
00356         newPoly = RPolygon::alloc_RPolygon(nX,nY,nX,nY,nR,nG,nB);
00357         (*newMap)->push_back(newPoly);
00358         tempMap[nX * ySize + nY] = i+1;     // index of this polygon + 1
00359     }
00360     // now have to grow polygons to fill the space.
00361     validPolys = (int *)malloc(4*gNPolygons * sizeof(int));
00362     validSide = (int *)malloc(4*gNPolygons * sizeof(int));
00363     for(int i=0;i<gNPolygons;i++) {
00364         validPolys[4*i] = validPolys[4*i + 1] = validPolys[4*i + 2] = validPolys[4*i + 3] = i + 1;
00365         validSide[4*i] = NORTH_SIDE;
00366         validSide[4*i+1] = EAST_SIDE;
00367         validSide[4*i+2] = SOUTH_SIDE;
00368         validSide[4*i+3] = WEST_SIDE;
00369     }
00370     maxSides = 4*gNPolygons;
00371     while(maxSides > 0) {
00372         int indx = NextRan(maxSides);
00373         int polyIndx = validPolys[indx];
00374         int checkSide = validSide[indx];
00375         int xlow, xhigh, ylow, yhigh;
00376         int xlnew, xhnew, ylnew, yhnew;
00377         (**newMap)[polyIndx]->get(&xlow,&ylow,&xhigh,&yhigh);
00378         xlnew = xlow;
00379         xhnew = xhigh;
00380         ylnew = ylow; 
00381         yhnew = yhigh;
00382         // can this polygon be expanded along the chosen side?
00383         switch(checkSide) {
00384         case NORTH_SIDE:
00385             // y-1 from xlow to xhigh
00386             ylow = yhigh = (ylow - 1);
00387             ylnew--;
00388             break;
00389         case EAST_SIDE:
00390             // x+1 from ylow to yhigh
00391             xlow = xhigh = (xhigh + 1);
00392             xhnew++;
00393             break;
00394         case SOUTH_SIDE:
00395             // y+1 from xlow to xhigh
00396             ylow = yhigh = (yhigh+1);
00397             yhnew++;
00398             break;
00399         case WEST_SIDE:
00400             // x-1 from ylow to yhigh
00401             xlow = xhigh = (xlow - 1);
00402             xlnew--;
00403             break;
00404         }
00405         bool okay_to_extend = !(((xlow < 0) || (xlow >= xSize)) || ((ylow < 0) || (ylow >= ySize)));
00406         for(int ii = xlow; (ii <= xhigh) && okay_to_extend; ii++) {
00407             for(int jj=ylow; (jj <= yhigh) && okay_to_extend; jj++) {
00408                 okay_to_extend = tempMap[ii*ySize + jj] == 0;
00409             }
00410         }
00411         if(okay_to_extend) {
00412             (**newMap)[polyIndx]->set(xlnew,ylnew,xhnew,yhnew);
00413             for(int ii = xlow; ii <= xhigh; ii++) {
00414                 for(int jj=ylow; jj <= yhigh && okay_to_extend; jj++) {
00415                     tempMap[ii*ySize + jj] = polyIndx;
00416                 }
00417             }
00418         }
00419         else {
00420             // once we cannot expand along a side, we will never be able to; remove from the list.
00421             for(int i=indx + 1; i < maxSides; i++) {
00422                 validPolys[i-1] = validPolys[i];
00423                 validSide[i-1] = validSide[i];
00424             }
00425             maxSides--;
00426         }
00427     }
00428 
00429     // Once no polygons can be grown, look for unused squares, and fill them with polygons.
00430     for(int j=0;j<ySize;j++) {
00431         for(int i=0;i<xSize;i++) {
00432             if(tempMap[i*ySize+j] == 0) {
00433                 // try to grow in the x direction, then the y direction
00434                 int ilen = i;
00435                 int jlen = j;
00436                 while(ilen < (xSize - 1) && tempMap[(ilen+1)*ySize + jlen] == 0) {
00437                     ilen++;
00438                 }
00439                 bool yok = true;
00440                 while(yok && jlen < (ySize - 1)) {
00441                     for(int ii = i; ii <= ilen && yok; ii++) {
00442                         yok = (tempMap[ii*ySize + jlen + 1] == 0);
00443                     }
00444                     if(yok) {
00445                         jlen++;
00446                     }
00447                 }
00448 
00449                 // create new polygon and push it on our list.
00450                 int nR = (maxR * NextRan(1000)) / 999;
00451                 int nG = (maxG * NextRan(1000)) / 999;
00452                 int nB = (maxB * NextRan(1000)) / 999;
00453                 newPoly = RPolygon::alloc_RPolygon(i,j,ilen,jlen,nR,nG,nB);
00454                 (*newMap)->push_back(newPoly);
00455                 gNPolygons++;
00456                 for(int ii=i; ii<=ilen;ii++) {
00457                     for(int jj=j;jj<=jlen;jj++) {
00458                         tempMap[ii*ySize + jj] = gNPolygons;
00459                     }
00460                 }
00461             }
00462         }
00463     }
00464 
00465 #if _DEBUG
00466     if(!gIsGraphicalVersion) {
00467         cout << std::endl << "Final Map:" << std::endl;
00468         for(int j=0; j < ySize; j++ ) {
00469             cout << "Row " << setw(2) << j << ":";
00470             for(int i=0;i<xSize;i++) {
00471                 int it = tempMap[i*ySize + j];
00472                 if(it<10) {
00473                     cout << setw(2) << it;
00474                 }
00475                 else {
00476                     char ct = (int)'a' + it - 10;
00477                     cout << " " << ct;
00478                 }
00479             }
00480             cout << std::endl;
00481         }
00482     }
00483 #endif  // _DEBUG
00484     free(tempMap);
00485     free(validPolys);
00486     free(validSide);
00487     return true;
00488 }
00489 
00490 void CheckPolygonMap(Polygon_map_t *checkMap) {
00491 #define indx(i,j) (i*gMapYSize + j)
00492 #define rangeCheck(str,n,limit) if(((n)<0)||((n)>=limit)) {cout << "checkMap error: " << str << " out of range (" << n << ")" << std::endl;anError=true;}
00493 #define xRangeCheck(str,n) rangeCheck(str,n,gMapXSize)
00494 #define yRangeCheck(str,n) rangeCheck(str,n,gMapYSize)
00495     // The first polygon is the whole map.
00496     bool anError = false;
00497     int *cArray;
00498     if(checkMap->size() <= 0) {
00499         cout << "checkMap error: no polygons in map" << std::endl;
00500         return;
00501     }
00502     // mapXhigh and mapYhigh are inclusive, that is, if the map is 5x5, those values would be 4.
00503     int mapXhigh, mapYhigh, mapLowX, mapLowY;
00504     int gMapXSize, gMapYSize;
00505     checkMap->at(0)->get(&mapLowX, &mapLowY, &mapXhigh, &mapYhigh);
00506     if((mapLowX !=0) || (mapLowY != 0)) {
00507         cout << "checkMap error: map origin not (0,0) (X=" << mapLowX << ", Y=" << mapLowY << ")" << std::endl;
00508         anError = true;
00509     }
00510     if((mapXhigh < 0) || (mapYhigh < 0)) {
00511         cout << "checkMap error: no area in map (X=" << mapXhigh << ", Y=" << mapYhigh << ")" << std::endl;
00512         anError = true;
00513     }
00514     if(anError) return;
00515     // bounds for array.
00516     gMapXSize = mapXhigh + 1;
00517     gMapYSize = mapYhigh + 1;
00518     cArray = (int *)malloc(sizeof(int)*(gMapXSize*gMapYSize));
00519 
00520     for(int i=0; i<gMapXSize; i++) {
00521         for(int j=0; j< gMapYSize; j++) {
00522             cArray[indx(i,j)] = 0;
00523         }
00524     }
00525 
00526     int xlow, xhigh, ylow, yhigh;
00527     for(int p=1; p < int(checkMap->size()) && !anError; p++) {
00528         checkMap->at(p)->get(&xlow, &ylow, &xhigh, &yhigh);
00529         xRangeCheck("xlow", xlow);
00530         yRangeCheck("ylow", ylow);
00531         xRangeCheck("xhigh", xhigh);
00532         yRangeCheck("yhigh", yhigh);
00533         if(xlow>xhigh) {
00534             cout << "checkMap error: xlow > xhigh (" << xlow << "," << xhigh << ")" << std::endl;
00535             anError = true;
00536         }
00537         if(ylow>yhigh) {
00538             cout << "checkMap error: ylow > yhigh (" << ylow << "," << yhigh << ")" << std::endl;
00539             anError = true;
00540         }
00541         for(int ii = xlow; ii <= xhigh; ii++) {
00542             for(int jj = ylow; jj <= yhigh; jj++) {
00543                 if(cArray[indx(ii,jj)] != 0) {
00544                     cout << "checkMap error: polygons " << cArray[indx(ii,jj)] << " and " << p << " intersect" << std::endl;
00545                     anError = true;
00546                 }
00547                 cArray[indx(ii,jj)] = p;
00548             }
00549         }
00550     }
00551     for(int ii=0; ii < gMapXSize; ii++) {
00552         for(int jj=0; jj < gMapYSize; jj++) {
00553             if(cArray[indx(ii,jj)] == 0) {
00554                 cout << "checkMap error: block(" << ii << ", " << jj << ") not in any polygon" << std::endl;
00555                 anError = true;
00556             }
00557         }
00558     }
00559     free(cArray);
00560 }
00561 
00562 bool CompOnePolygon(RPolygon *p1, RPolygon *p2) {
00563     int xl1, xh1, yl1, yh1;
00564     int xl2, xh2, yl2, yh2;
00565     p1->get(&xl1, &yl1, &xh1, &yh1);
00566     p2->get(&xl2, &yl2, &xh2, &yh2);
00567     if(yl1>yl2) return true;
00568     if(yl1<yl2) return false;
00569     return (xl1 > xl2);
00570 }
00571 
00572 bool PolygonsEqual(RPolygon *p1, RPolygon *p2) {
00573     int xl1, xh1, yl1, yh1;
00574     int xl2, xh2, yl2, yh2;
00575     p1->get(&xl1, &yl1, &xh1, &yh1);
00576     p2->get(&xl2, &yl2, &xh2, &yh2);
00577     return ((xl1 == xl2) && (yl1==yl2) && (xh1 == xh2) && (yh1 == yh2));
00578 }
00579 
00580 bool ComparePolygonMaps(Polygon_map_t *map1, Polygon_map_t *map2) {
00581     // create two new polygon maps, copy the pointers from the original to these.
00582     // we have to skip the first polygon, which is the size of the whole map
00583     Polygon_map_t *t1, *t2;
00584     bool is_ok = true;
00585     t1 = new Polygon_map_t;
00586     t1->reserve(map1->size());
00587     for(unsigned int i=1;i<map1->size(); i++) {
00588         t1->push_back(map1->at(i));
00589     }
00590     t2 = new Polygon_map_t;
00591     t2->reserve(map2->size());
00592     for(unsigned int i=1;i<map2->size();i++) {
00593         t2->push_back(map2->at(i));
00594     }
00595     // sort the two created maps by (xlow, ylow)
00596     sort(t1->begin(), t1->end(), CompOnePolygon);
00597     sort(t2->begin(), t2->end(), CompOnePolygon);
00598     // compare each element of both maps.
00599     if(t1->size() != t2->size()) {
00600         cout << "Error: maps not the same size ( " << int(t1->size()) << " vs " << int(t2->size()) << ")." << std::endl;
00601     }
00602     int maxSize = (int)((t1->size() < t2->size()) ? t1->size() : t2->size());
00603     for(int i=0; i < maxSize; i++) {
00604         if(!PolygonsEqual(t1->at(i), t2->at(i))) {
00605             cout << "Error: polygons unequal (" << *(t1->at(i)) << " vs " << (*t2->at(i)) << std::endl;
00606             is_ok = false;
00607         }
00608     }
00609     delete t1;
00610     delete t2;
00611     return is_ok;
00612 }
00613 
00614 void SetRandomSeed(int newSeed) {
00615     srand((unsigned)newSeed);
00616 }
00617 
00618 int NextRan(int n) {
00619     // assert(n > 1);
00620     // if we are given 1, we will just return 0
00621     //assert(n < RAND_MAX);
00622     int rrand = rand() << 15 | rand();
00623     if(rrand < 0) rrand = -rrand;
00624     return rrand % n;
00625 }
00626 
00627 std::ostream& operator<<(std::ostream& s, const RPolygon &p) {
00628     int xl, yl, xh, yh;
00629     p.get(&xl, &yl, &xh, &yh);
00630     return s << "[(" << xl << "," << yl << ")-(" << xh << "," << yh << ")] ";
00631 }

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net