00001
00005 #include "schemaGameUtility.h"
00006
00008 const unsigned int numericBase= 10;
00009
00012 const unsigned int maxValueOfNumericBase= 9;
00013
00014
00015
00016
00017 currentGameState initializeCurrentGameState()
00018 {
00019 D1(printf("\nSCHEMAGAMEUTILITY.initializeCurrentGameState() - START\n"));
00020
00021 currentGameState gameState;
00022
00023 gameState.currentRow = 0;
00024
00025 gameState.currentCol = 0;
00026
00027 gameState.bestrouteweight = 0;
00028
00029 gameState.iters = 0;
00030
00031 gameState.currentlevel = 1;
00032
00033 gameState.totalpoints = 0;
00034
00035 gameState.starttime = 0;
00036
00037 gameState.playing = false;
00038
00039 gameState.numOfRound = 1;
00040
00041 return gameState;
00042
00043 D1(printf("\nSCHEMAGAMEUTILITY.initializeCurrentGameState() - END\n"));
00044 }
00045
00046
00047 double newgame( char schemafilename[],
00048 unsigned int *bestrouteweight
00049 )
00050 {
00051 D1(printf("\nSCHEMAGAMEUTILITY.newgame() - START\n"));
00052
00053 unsigned short int errnum = 0;
00054
00055
00056 errnum = loadCheckGame(schemafilename);
00057 D4(printf("\n'returns': errnum=%u\n",errnum));
00058
00059 if(errnum > 0){
00060 D1(printf("\nSCHEMAGAMEUTILITY.newgame() - Error & END\n"));
00061 return -1;
00062 }
00063
00064
00065 printschema();
00066
00067 clock_t tStart, tEnd;
00068 tStart=clock();
00069
00070
00071 unsigned int *doorsRow = (unsigned int *)malloc(sizeof(unsigned int)*
00072 (schemaData.numRow*schemaData.numCol));
00073
00074 unsigned int *doorsCol = (unsigned int *)malloc(sizeof(unsigned int)*
00075 (schemaData.numRow*schemaData.numCol));
00076
00077
00078 unsigned int numOfDoors = getdoors( doorsRow,doorsCol );
00079
00080
00081 unsigned int *doorsRowExact = (unsigned int *)malloc(sizeof(unsigned int)*
00082 numOfDoors );
00083
00084 unsigned int *doorsColExact = (unsigned int *)malloc(sizeof(unsigned int)*
00085 numOfDoors );
00086
00087 unsigned int i=0;
00088
00089 for(i=0;i<numOfDoors;i++)
00090 {
00091 doorsRowExact[i] = doorsRow[i];
00092 doorsColExact[i] = doorsCol[i];
00093 }
00094
00095
00096 free(doorsRow);
00097 free(doorsCol);
00098 D1(printf("\nSCHEMAGAMEUTILITY.newgame() - after deallocation\n"));
00099
00100
00101 unsigned int bestdoorid = numOfDoors+1;
00102 (*bestrouteweight) = bestroute( doorsRowExact,doorsColExact,
00103 numOfDoors, &bestdoorid );
00104
00105 D4(printf("(returns -> %u)\n",*bestrouteweight));
00106
00107 if( ( bestdoorid > numOfDoors ) || ( *bestrouteweight < 1 ) ){
00108 D2(printf("\nSchema error! Need at least one reachable door."));
00109 D1(printf("\nSCHEMAGAMEUTILITY.newgame() - Error & END\n"));
00110 free(doorsRowExact);
00111 free(doorsColExact);
00112 return -1;
00113 }
00114
00115 assert(!(( bestdoorid > numOfDoors ) || (*bestrouteweight < 1 )));
00116
00117 D2(printf("\nBest route (%u,%u)->(%u,%u) has weight %u.",
00118 schemaData.startRow,schemaData.startCol,doorsRowExact[bestdoorid],
00119 doorsColExact[bestdoorid],*bestrouteweight ));
00120
00121 free(doorsRowExact);
00122 free(doorsColExact);
00123
00124 tEnd=clock();
00125
00126 double elapsed = (double)(tEnd-tStart)/CLOCKS_PER_SEC;
00127
00128 D2(printf("\nSchema dimension(%uX%u):",
00129 schemaData.startRow,schemaData.startCol));
00130 D5(printf("\nClock at start: %lu",tStart));
00131 D5(printf("\nClock at end: %lu",tEnd));
00132 D5(printf("\nCPU clock per second: %lu",CLOCKS_PER_SEC));
00133 D1(printf("\nElapsed time: %f second(s)",elapsed));
00134 D1(printf("\nSCHEMAGAMEUTILITY.newgame() - END\n"));
00135 return elapsed;
00136 }
00137
00138 bool checkRowColValues(unsigned short int *errnum, char *err)
00139 {
00140 D1(printf("\nSCHEMAGAMEUTILITY.checkRowColValues() - START\n"));
00141
00142 bool schema_ok = true;
00143
00144
00145 if((schemaData.numRow)<MINR){
00146 strcat(err,"\nNumber of rows lower then minimum allowed.");
00147 *errnum = *errnum + 1;
00148 schema_ok = false;
00149 }
00150
00151 if((schemaData.numRow)>MAXR){
00152 strcat(err,"\nNumber of rows more then maximum allowed.");
00153 *errnum = *errnum + 1;
00154 schema_ok = false;
00155 }
00156
00157
00158
00159 if((schemaData.numCol)<MINC){
00160 strcat(err,"\nNumber of columns lower then minimum allowed.");
00161 *errnum = *errnum + 1;
00162 schema_ok = false;
00163 }
00164
00165 if((schemaData.numCol)>MAXC){
00166 strcat(err,"\nNumber of columns more then maximum allowed.");
00167 *errnum = *errnum + 1;
00168 schema_ok = false;
00169 }
00170
00171
00172
00173 D1(printf("\nSCHEMAGAMEUTILITY.checkRowColValues() - END\n"));
00174 return schema_ok;
00175 }
00176
00177 void setSchemaDataStructures(char **schema_propr)
00178 {
00179 D1(printf("\nSCHEMAGAMEUTILITY.setSchemaDataStructures() - START\n"));
00180
00181 unsigned int i = 0, j = 0;
00182
00183 schemaData.gameMap = (char **)
00184 malloc(sizeof(char *)*(schemaData.numRow));
00185
00186 schemaData.visitedCellInfo = (unsigned short int **)
00187 malloc(sizeof(unsigned short int *)*(schemaData.numRow));
00188
00189 for(i=0; i<(schemaData.numRow); i++)
00190 {
00191 schemaData.gameMap[i] = (char *)
00192 malloc(sizeof(char)*(schemaData.numCol));
00193
00194 schemaData.visitedCellInfo[i] = (unsigned short int *)
00195 malloc(sizeof(unsigned short int)*(schemaData.numCol));
00196
00197 for(j=0; j<(schemaData.numCol); j++)
00198 {
00199 schemaData.gameMap[i][j] = schema_propr[i][j];
00200 schemaData.visitedCellInfo[i][j] = UNVISITED;
00201 }
00202 }
00203
00204 D1(printf("\nSCHEMAGAMEUTILITY.setSchemaDataStructures() - END\n"));
00205 }
00206
00207 void checkDoorStartPoint(unsigned short int *errnum, char *err)
00208 {
00209 D1(printf("\nSCHEMAGAMEUTILITY.checkDoorStartPoint() - START\n"));
00210
00211 unsigned int i = 0, j = 0;
00212 bool doorok = false;
00213 unsigned int startok = 0;
00214 for(i=0; (i<(schemaData.numRow)) && (startok<=1); i++)
00215 for(j=0; (j<(schemaData.numCol)) && (startok<=1) ;j++)
00216 {
00217 if( (!doorok) && (schemaData.gameMap[i][j]==DOOR) )
00218 doorok = true;
00219
00220 if(schemaData.gameMap[i][j]==START)
00221 {
00222 startok++;
00223 schemaData.startRow = i;
00224 schemaData.startCol = j;
00225 }
00226 }
00227
00228 if(!doorok) { strcat(err,"\nNo doors in the schema.\n");
00229 *errnum = *errnum + 1; }
00230
00231 if(startok != 1){
00232 strcat(err,"\nWrong number of start point in the schema.\n");
00233 *errnum = *errnum + 1; }
00234
00235 D1(printf("\nSCHEMAGAMEUTILITY.checkDoorStartPoint() - END\n"));
00236 }
00237
00238 unsigned short int loadCheckGame( char *file_name )
00239 {
00240 D1(printf("\nSCHEMAGAMEUTILITY.loadCheckGame() - START\n"));
00241 D6(printf("\nparams: file_name=%s ",file_name));
00242
00243 unsigned short int errnum = 0;
00244
00245
00246 char err[MAX_ERR_BUFFER_LEN];
00247 strcpy(err,"\0");
00248
00249 char **schema_propr = NULL;
00250
00251
00252 bool schema_ok = false;
00253 schemaData.numRow=0;
00254 schemaData.numCol=0;
00255 schema_propr = readfile( file_name,
00256 &schema_ok,
00257 &schemaData.numRow,
00258 &schemaData.numCol,
00259 MAXR,
00260 MAXC,
00261 true
00262 );
00263
00264
00265 if ( ! schema_ok )
00266 {
00267 strcat(err,"\nAn error occurred in file reading before.");
00268 errnum = errnum + 1;
00269 }
00270 else
00271 schema_ok = checkRowColValues(&errnum, (err));
00272
00273 if( schema_ok )
00274 {
00275 setSchemaDataStructures(schema_propr);
00276 checkDoorStartPoint(&errnum, (err));
00277 }
00278
00279 free(schema_propr);
00280
00281
00282 if(errnum != 0)
00283 {
00284 D1(printf("\nError in file %s : %s\n",file_name,err));
00285 schemaData.numRow = 0;
00286 schemaData.numCol = 0;
00287 schemaData.gameMap = (char **)malloc(sizeof(char *));
00288
00289 }
00290
00291
00292 D1(printf("\nSCHEMAGAMEUTILITY.loadCheckGame() - END\n"));
00293
00294
00295 return errnum;
00296 }
00297
00298
00299 unsigned int getdoors( unsigned int *doorsRow,
00300 unsigned int *doorsCol
00301 )
00302 {
00303 D1(printf("\nSCHEMAGAMEUTILITY.getdoors() - START\n"));
00304
00305 unsigned int i = 0, j = 0;
00306 unsigned int numOfDoor = 0;
00307
00308 for( i=0; i<schemaData.numRow; i++ )
00309 for( j=0; j<schemaData.numCol; j++ )
00310 if( schemaData.gameMap[i][j] == DOOR )
00311 {
00312 doorsRow[numOfDoor] = i;
00313 doorsCol[numOfDoor] = j;
00314 numOfDoor++;
00315 }
00316
00317 D1(printf("\nSCHEMAGAMEUTILITY.getdoors() - END\n"));
00318
00319 return numOfDoor;
00320 }
00321
00322
00323 bool isDirectory( char const *path )
00324 {
00325 D5(printf("\nSCHEMAGAMEUTILITY.isDirectory() - START\n"));
00326
00327 bool retvalue = true;
00328
00329 struct stat st;
00330 if ( lstat( path, &st ) == -1 )
00331 retvalue = false;
00332 else
00333 retvalue = S_ISDIR(st.st_mode);
00334
00335 D5(printf("\nPath %s is%s a directory\n", path,(retvalue)?(""):(" not") ));
00336 D5(printf("\nSCHEMAGAMEUTILITY.isDirectory() - END\n"));
00337 return retvalue;
00338 }
00339
00340
00341
00342 char *get_schema_name( unsigned short int level)
00343 {
00344 D1(printf("\nSCHEMAGAMEUTILITY.get_schema_name() - START\n"));
00345
00346 struct dirent **eps;
00347 int numElemDir;
00348
00349 unsigned int digitlen = countDigits( level );
00350
00351 const unsigned short int separatorLen = 5;
00352 char generateddir[ strlen(GAMES_DIR) +
00353 strlen(GAMES_LEVEL_DIR) +
00354 digitlen + separatorLen ];
00355
00356 sprintf(generateddir,"./%s/%s%u/",GAMES_DIR,GAMES_LEVEL_DIR,level);
00357
00358 numElemDir = scandir (generateddir, &eps, 0, 0);
00359
00360 D2(printf("\nScandir() returns %i elements.\n", numElemDir));
00361
00362
00363 unsigned int i = 0;
00364 bool atleast1file = false;
00365 if( numElemDir > 0)
00366 for( ; (i<numElemDir) && (!atleast1file); i++)
00367 {
00368 assert( (i < numElemDir) && (!atleast1file) );
00369
00370 char *tmppath = (char *)malloc( sizeof(char) *
00371 ( strlen(eps[i]->d_name) +
00372 strlen(generateddir) + 1 ) );
00373
00374 sprintf(tmppath,"%s%s",generateddir,eps[i]->d_name);
00375
00376 atleast1file = ! isDirectory( tmppath );
00377
00378 free(tmppath);
00379 }
00380
00381 if(!atleast1file)
00382 {
00383 D1(printf("\nNo such file in %s\n", generateddir));
00384 char *filename = (char *)malloc(sizeof(char));
00385 filename[0] = NULLCHAR;
00386 D1(printf("\nSCHEMAGAMEUTILITY.get_schema_name() - error & END\n"));
00387 return filename;
00388 }
00389 assert( atleast1file );
00390
00391
00392 unsigned int rd = 0;
00393 srand((unsigned)time(0));
00394 char *tmppath = NULL;
00395 do{
00396 rd = rand() % (numElemDir);
00397
00398 tmppath = (char *)malloc(sizeof(char)*( strlen(eps[rd]->d_name) +
00399 strlen(generateddir)
00400 + 1 ) );
00401
00402 sprintf(tmppath,"%s%s",generateddir,eps[rd]->d_name);
00403
00404 }while( isDirectory( tmppath ) );
00405 free(tmppath);
00406
00407
00408 char *filename = (char *)malloc(sizeof(char)*( strlen(eps[rd]->d_name) +
00409 strlen(generateddir) ));
00410
00411 sprintf(filename,"%s%s",generateddir,eps[rd]->d_name);
00412
00413 D1(printf("\nSCHEMAGAMEUTILITY.get_schema_name() - END\n"));
00414
00415 return filename;
00416 }
00417
00418
00419
00420 bool isallowedchar(unsigned short int typeCharSel ,
00421 char char2check
00422 )
00423 {
00424 D1(printf("\nSCHEMAGAMEUTILITY.isallowedchar() - START\n"));
00425 D5(printf("\nSelected:"));
00426 D5(printf("\nLowercase letter [%c]",(typeCharSel&LOWERCASE)?'Y':'N'));
00427 D5(printf("\nUppercase letter [%c]",(typeCharSel&UPPERCASE)?'Y':'N'));
00428 D5(printf("\nDigit [%c]",(typeCharSel&DIGITS)?'Y':'N'));
00429
00430
00431 if ((char2check>='a') && (char2check<='z') && (typeCharSel & LOWERCASE))
00432 {
00433 D4(printf("\nAllowed character %c is a lowercase letter.\n"
00434 ,char2check));
00435 D1(printf("\nSCHEMAGAMEUTILITY.isallowedchar() - END\n"));
00436 return true;
00437 }
00438
00439
00440 if ((char2check>='A') && (char2check<='Z') && (typeCharSel & UPPERCASE))
00441 {
00442 D4(printf("\nAllowed character %c is an uppercase letter.\n"
00443 ,char2check ));
00444 D1(printf("\nSCHEMAGAMEUTILITY.isallowedchar() - END\n"));
00445 return true;
00446 }
00447
00448
00449 if ((char2check>='0') && (char2check<='9') && (typeCharSel & DIGITS))
00450 {
00451 D4(printf("\nAllowed character %c is a digit.\n",char2check));
00452 D1(printf("\nSCHEMAGAMEUTILITY.isallowedchar() - END\n"));
00453 return true;
00454 }
00455
00456 D4(printf("\nCharacter %c (ASCII %i) is not allowed.\n",
00457 char2check, (int)char2check ));
00458 D1(printf("\nSCHEMAGAMEUTILITY.isallowedchar() - END\n"));
00459
00460 return false;
00461 }
00462
00463
00464 inline unsigned int countDigits(unsigned int number)
00465 {
00466 unsigned int numDigit = 1;
00467
00468 while( number > maxValueOfNumericBase ){
00469 number /= numericBase;
00470 numDigit++;
00471 }
00472
00473 return numDigit;
00474 }
00475
00476
00477 inline bool check_if_text_is_number( const bool runme,
00478 const char *text,
00479 char *err_buff,
00480 const char *err_label
00481 )
00482 {
00483 if( !runme )
00484 return false;
00485
00486 bool returnValue = true;
00487
00488 unsigned int i;
00489 for(i = 0; i<strlen(text); i++ )
00490 if( ! isallowedchar( DIGITS , text[i] ) )
00491 {
00492 sprintf(err_buff,"Error in %s:\n\n", err_label );
00493 sprintf(err_buff,"%s Character position is %u\n", err_buff, i);
00494 sprintf(err_buff,"%s Display character is %c\n", err_buff,text[i]);
00495 sprintf(err_buff,"%s ASCII value is %i\n", err_buff, (int)text[i]);
00496
00497 returnValue = false;
00498 }
00499
00500 return returnValue;
00501 }
00502
00503 unsigned int calcSchemaResults( char *labeltxt,
00504 currentGameState gameState
00505 )
00506 {
00507 D1(printf("\nGUIHANDLER.calcSchemaResults() - START\n"));
00508
00509 unsigned int totalpoints = gameState.totalpoints;
00510
00511 time_t *tmpend=NULL;
00512 unsigned long endtime = time(tmpend);
00513 free(tmpend);
00514
00515
00516 unsigned long elapsedtime = endtime - gameState.starttime;
00517
00518 D2(printf("\nElapsed time ( %lu - %lu ) = %lu second(s)\n",
00519 endtime,gameState.starttime,elapsedtime ));
00520
00521 double correctperc = ((double)gameState.bestrouteweight
00522 /
00523 (double)gameState.iters)*100;
00524
00525 D2(printf("\nCorrect prec. ( %u / %u ) = %.2lf\n",
00526 gameState.bestrouteweight,gameState.iters,correctperc ));
00527
00528 unsigned int bonus = (correctperc>=GIVE_BONUS_PERC) ?
00529 (BONUS_POINTS) : (NO_BONUS_POINTS) ;
00530
00531 D2(printf("\nBonus = %u points (min. correct perc. is %i)\n",
00532 bonus, GIVE_BONUS_PERC ));
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 unsigned long points = ceil (gameState.currentlevel * (bonus + correctperc)
00543 /
00544 ( elapsedtime /
00545 ( 1 + SEC_PER_LEVEL * gameState.currentlevel )
00546 + 1 ) );
00547
00548 D2(printf("\nPoints round(%u*(%u+%lf)/(%lu/(1+%i*%u)+1)) = %lu \n",
00549 gameState.currentlevel,bonus,correctperc,elapsedtime,
00550 SEC_PER_LEVEL,gameState.currentlevel,points ));
00551
00552 totalpoints += points;
00553
00554
00555 sprintf(labeltxt, "- Current schema results:\n\n");
00556 sprintf(labeltxt,"%s Correctness: %.2lf%c\n",labeltxt,correctperc,'%');
00557 sprintf(labeltxt,"%s Bonus: %u points\n",labeltxt,bonus);
00558 sprintf(labeltxt,"%s Time: %lu second(s)\n",labeltxt,elapsedtime);
00559 sprintf(labeltxt,"%s Points: %lu\n\n",labeltxt,points);
00560 sprintf(labeltxt,"%s- Total points: %u\n\n",labeltxt,totalpoints);
00561 sprintf(labeltxt,"%s- Level %u of %u",labeltxt,
00562 gameState.currentlevel,
00563 gameState.numOfRound);
00564
00565 D1(printf("\nGUIHANDLER.calcSchemaResults() - END\n"));
00566 return totalpoints;
00567 }
00568
00569
00570
00571