Map.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. #include "Teile.h"
  2. #include "Map.h"
  3. #include <InitDatei.h>
  4. #include <Datei.h>
  5. #include <KSGTDatei.h>
  6. #include <Text.h>
  7. #include <TastaturEreignis.h>
  8. #include <Zeit.h>
  9. #include <Rahmen.h>
  10. #include <AsynchronCall.h>
  11. // Inhalt der Map Klasse aus Map.h
  12. // Konstruktor
  13. Map::Map( MinigameKlientV *klient )
  14. {
  15. this->klient = klient;
  16. map = new RCArray< Array< int > >();
  17. feld = new LRahmen();
  18. feld->setFarbe( 0xFFFFFFFF );
  19. t = { 0, 0, 0, 0 };
  20. beendet = 1;
  21. sr = 1;
  22. rend = 0;
  23. gameTime = 0;
  24. rGen = 0;
  25. ref = 1;
  26. }
  27. // Destruktor
  28. Map::~Map()
  29. {
  30. speichern();
  31. map->release();
  32. feld->release();
  33. if( rGen )
  34. rGen->release();
  35. if( klient )
  36. klient->release();
  37. }
  38. // nicht constant
  39. void Map::reset( Text *zOptionen )
  40. {
  41. gameTime = 0;
  42. if( rGen )
  43. rGen = rGen->release();
  44. next = 0;
  45. score = 0;
  46. map->leeren();
  47. t = { -1, 0, 0, 0 };
  48. Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
  49. breite = *tmp;
  50. tmp->release();
  51. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) );
  52. höhe = *tmp;
  53. tmp->release();
  54. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) );
  55. neuTempo = *tmp;
  56. tmp->release();
  57. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) );
  58. geschwindigkeit = *tmp;
  59. tmp->release();
  60. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) );
  61. bool fortsetzen = (int)*tmp != 0;
  62. tmp->release();
  63. if( fortsetzen && DateiExistiert( "data/Minigames/Tetris/data/game.save" ) && klient )
  64. {
  65. if( capture.istOffen() )
  66. capture.close();
  67. capture.setDatei( "data/Minigames/Tetris/data/game.mgc" );
  68. capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
  69. Datei *save = new Datei();
  70. save->setDatei( "data/Minigames/Tetris/data/game.save" );
  71. save->open( Datei::Style::lesen );
  72. int br = 0;
  73. int hö = 0;
  74. __int64 seed;
  75. save->lese( (char*)&seed, 8 );
  76. rGen = new RandomGenerator();
  77. rGen->setSeed( seed );
  78. save->lese( (char*)&gameTime, 8 );
  79. save->lese( (char*)&br, 4 );
  80. save->lese( (char*)&hö, 4 );
  81. if( br == breite && hö == höhe )
  82. {
  83. save->lese( (char*)&score, 4 );
  84. save->lese( (char*)&t, sizeof( Tile ) );
  85. for( int y = 0; y < höhe; y++ )
  86. {
  87. map->set( new Array< int >(), y );
  88. for( int x = 0; x < breite; x++ )
  89. {
  90. int f = 0;
  91. save->lese( (char*)&f, 4 );
  92. map->z( y )->set( f, x );
  93. }
  94. }
  95. geschwindigkeit -= score * neuTempo;
  96. if( geschwindigkeit < 100 )
  97. geschwindigkeit = 100;
  98. next = geschwindigkeit / 1000.0;
  99. }
  100. save->close();
  101. save->release();
  102. }
  103. else
  104. {
  105. rGen = new RandomGenerator();
  106. if( klient )
  107. {
  108. if( capture.istOffen() )
  109. capture.close();
  110. DateiRemove( "data/Minigames/Tetris/data/game.mgc" );
  111. capture.setDatei( "data/Minigames/Tetris/data/game.mgc" );
  112. capture.erstellen();
  113. capture.open( Datei::Style::schreiben );
  114. __int64 seed = rGen->getSeed();
  115. capture.schreibe( (char*)&seed, 8 );
  116. }
  117. else
  118. {
  119. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1 );
  120. rGen->setSeed( (__int64)*tmp );
  121. tmp->release();
  122. }
  123. }
  124. if( t.id < 0 )
  125. {
  126. t.id = (int)( rGen->rand() * 7 );
  127. t.grad = (int)( rGen->rand() * 4 );
  128. t.xPos = breite / 2 - 2;
  129. t.yPos = 0;
  130. }
  131. if( !map->getEintragAnzahl() )
  132. {
  133. for( int i = 0; i < höhe; i++ )
  134. {
  135. Array< int > *line = new Array< int >();
  136. for( int j = 0; j < breite; j++ )
  137. line->add( 0 );
  138. map->add( line );
  139. }
  140. }
  141. if( breite < 40 || höhe < 25 )
  142. {
  143. int br = breite * 20;
  144. if( br > 800 )
  145. br = 800;
  146. int hö = höhe * 20;
  147. if( hö > 500 )
  148. hö = 500;
  149. feld->setPosition( 400 - br / 2, 250 - hö / 2 );
  150. feld->setSize( br, hö );
  151. }
  152. beendet = 0;
  153. }
  154. void Map::doMausEreignis( MausEreignis &me )
  155. {
  156. }
  157. void Map::doTastaturEreignis( TastaturEreignis &te )
  158. {
  159. if( beendet )
  160. return;
  161. cs.lock();
  162. bool ok = 1;
  163. if( !beendet && te.id == TE_Press )
  164. {
  165. int g = t.grad;
  166. int xPos = t.xPos;
  167. int yPos = t.yPos;
  168. bool save = 0;
  169. if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben )
  170. {
  171. g++;
  172. if( g >= 4 )
  173. g = 0;
  174. save = 1;
  175. }
  176. if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts )
  177. {
  178. xPos++;
  179. save = 1;
  180. }
  181. if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links )
  182. {
  183. xPos--;
  184. save = 1;
  185. }
  186. if( te.taste == 's' || te.taste == 'S' || te.taste == T_Unten )
  187. {
  188. yPos++;
  189. save = 1;
  190. }
  191. if( save && klient )
  192. {
  193. capture.schreibe( (char*)&gameTime, 8 );
  194. capture.schreibe( (char*)&te.taste, 1 );
  195. }
  196. bool ok = 1;
  197. for( int x = xPos; x < xPos + 4; x++ )
  198. {
  199. for( int y = yPos; y < yPos + 4; y++ )
  200. {
  201. if( tiles[ t.id ][ g ][ y - yPos ][ x - xPos ] )
  202. {
  203. ok &= x >= 0 && x < breite && y >= 0 && y < höhe;
  204. ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0;
  205. }
  206. }
  207. }
  208. if( ok )
  209. {
  210. t.grad = g;
  211. t.xPos = xPos;
  212. t.yPos = yPos;
  213. rend = 1;
  214. }
  215. }
  216. cs.unlock();
  217. }
  218. bool Map::tick( double tickVal )
  219. {
  220. bool ret = rend;
  221. rend = 0;
  222. if( beendet )
  223. return ret;
  224. cs.lock();
  225. gameTime += tickVal;
  226. next -= tickVal;
  227. if( next < 0 )
  228. {
  229. next = geschwindigkeit / 1000.0;
  230. bool ok = 1;
  231. for( int x = t.xPos; x < t.xPos + 4; x++ )
  232. {
  233. for( int y = t.yPos + 1; y < t.yPos + 5; y++ )
  234. {
  235. if( tiles[ t.id ][ t.grad ][ y - t.yPos - 1 ][ x - t.xPos ] )
  236. {
  237. ok &= x >= 0 && x < breite && y >= 0 && y < höhe;
  238. ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0;
  239. }
  240. }
  241. }
  242. if( ok )
  243. t.yPos++;
  244. else
  245. {
  246. for( int x = t.xPos; x < t.xPos + 4; x++ )
  247. {
  248. for( int y = t.yPos; y < t.yPos + 4; y++ )
  249. {
  250. if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] )
  251. map->z( y )->set( tileFarbe[ t.id ], x );
  252. }
  253. }
  254. for( int y = 0; y < höhe; y++ )
  255. {
  256. bool rm = 1;
  257. for( int x = 0; x < breite; x++ )
  258. rm &= map->z( y )->get( x ) != 0;
  259. if( rm )
  260. {
  261. Array< int > *line = new Array< int >();
  262. for( int i = 0; i < breite; i++ )
  263. line->add( 0 );
  264. map->remove( y );
  265. map->add( line, 0 );
  266. score++;
  267. geschwindigkeit -= neuTempo;
  268. }
  269. }
  270. t.id = (int)( rGen->rand() * 7 );
  271. t.grad = (int)( rGen->rand() * 4 );
  272. t.xPos = breite / 2 - 2;
  273. t.yPos = 0;
  274. for( int x = t.xPos; x < t.xPos + 4; x++ )
  275. {
  276. for( int y = t.yPos; y < t.yPos + 4; y++ )
  277. {
  278. if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] )
  279. beendet |= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) != 0;
  280. }
  281. }
  282. if( beendet && klient )
  283. {
  284. capture.close();
  285. DateiRemove( "data/Minigames/Tetris/data/upload.mgc" );
  286. DateiUmbenennen( "data/Minigames/Tetris/data/game.mgc", "data/Minigames/Tetris/data/upload.mgc" );
  287. int tmpScore = score;
  288. MinigameKlientV *tmpKlient = klient->getThis();
  289. new AsynchronCall( [ tmpScore, tmpKlient ]()
  290. {
  291. InitDatei *opd = new InitDatei( "data/Minigames/Tetris/data/optionen.ini" );
  292. opd->laden();
  293. Text optionen = "Width=";
  294. optionen += opd->zWert( "Breite" )->getText();
  295. optionen += ",Height=";
  296. optionen += opd->zWert( "Höhe" )->getText();
  297. optionen += ",NSpeed=";
  298. optionen += opd->zWert( "+Geschwindigkeit" )->getText();
  299. optionen += ",Speed=";
  300. optionen += opd->zWert( "Geschwindigkeit" )->getText();
  301. opd->release();
  302. int status = tmpKlient->reportEndOfGame( "Tetris", optionen, tmpScore );
  303. if( status == 2 )
  304. {
  305. Datei d;
  306. d.setDatei( "data/Minigames/Tetris/data/upload.mgc" );
  307. tmpKlient->uploadGameCapture( &d );
  308. }
  309. DateiRemove( "data/Minigames/Tetris/data/upload.mgc" );
  310. tmpKlient->release();
  311. } );
  312. DateiRemove( "data/Minigames/Tetris/data/game.save" );
  313. KSGTDatei *stb = new KSGTDatei( "data/Minigames/Tetris/data/score.ksgt" );
  314. if( !stb->laden() )
  315. DateiPfadErstellen( "data/Minigames/Tetris/data/score.ksgt" );
  316. RCArray< Text > *zeile = new RCArray< Text >();
  317. Zeit *zeit = getZeit();
  318. zeile->add( zeit->getZeit( "y-m-d h:i:s" ) );
  319. zeit->release();
  320. Text *scoreT = new Text();
  321. scoreT->append( score );
  322. zeile->add( scoreT );
  323. Text *breiteT = new Text();
  324. breiteT->append( breite );
  325. zeile->add( breiteT );
  326. Text *höheT = new Text();
  327. höheT->append( höhe );
  328. zeile->add( höheT );
  329. Text *geschwindigkeitT = new Text();
  330. geschwindigkeitT->append( geschwindigkeit );
  331. zeile->add( geschwindigkeitT );
  332. Text *neuTempoT = new Text();
  333. neuTempoT->append( neuTempo );
  334. zeile->add( neuTempoT );
  335. stb->addZeile( 6, zeile );
  336. zeile->release();
  337. stb->speichern();
  338. stb->release();
  339. }
  340. }
  341. ret = 1;
  342. }
  343. cs.unlock();
  344. return ret;
  345. }
  346. void Map::render( Bild &zRObj )
  347. {
  348. int xS = feld->getX();
  349. int yS = feld->getY();
  350. int blockBr = 800 / breite;
  351. if( blockBr > 20 )
  352. blockBr = 20;
  353. int blockHö = 500 / höhe;
  354. if( blockHö > 20 )
  355. blockHö = 20;
  356. for( int x = 0; x < breite; x++ )
  357. {
  358. for( int y = 0; y < höhe; y++ )
  359. zRObj.fillRegion( xS + x * blockBr, yS + y * blockHö, blockBr - 1, blockHö - 1, map->z( y )->get( x ) );
  360. }
  361. for( int x = 0; x < 4; x++ )
  362. {
  363. for( int y = 0; y < 4; y++ )
  364. {
  365. if( tiles[ t.id ][ t.grad ][ y ][ x ] )
  366. zRObj.fillRegion( xS + ( x + t.xPos ) * blockBr, yS + ( y + t.yPos ) * blockHö, blockBr - 1, blockHö - 1, tileFarbe[ t.id ] );
  367. }
  368. }
  369. feld->render( zRObj );
  370. }
  371. void Map::speichern()
  372. {
  373. if( !beendet )
  374. {
  375. if( capture.istOffen() )
  376. capture.close();
  377. Datei *d = new Datei();
  378. d->setDatei( "data/Minigames/Tetris/data/game.save" );
  379. d->erstellen();
  380. d->open( Datei::Style::schreiben );
  381. __int64 seed = rGen->getSeed();
  382. d->schreibe( (char*)&seed, 8 );
  383. d->schreibe( (char*)&gameTime, 8 );
  384. d->schreibe( (char*)&breite, 4 );
  385. d->schreibe( (char*)&höhe, 4 );
  386. d->schreibe( (char*)&score, 4 );
  387. d->schreibe( (char*)&t, sizeof( Tile ) );
  388. for( int y = 0; y < höhe; y++ )
  389. {
  390. for( int x = 0; x < breite; x++ )
  391. {
  392. int f = map->z( y )->get( x );
  393. d->schreibe( (char*)&f, 4 );
  394. }
  395. }
  396. d->close();
  397. d->release();
  398. }
  399. else if( klient )
  400. DateiRemove( "data/Minigames/Tetris/data/game.save" );
  401. }
  402. // constant
  403. int Map::getScore() const
  404. {
  405. return score;
  406. }
  407. bool Map::istBeendet() const
  408. {
  409. return beendet;
  410. }
  411. // Reference Counting
  412. Map *Map::getThis()
  413. {
  414. ref++;
  415. return this;
  416. }
  417. Map *Map::release()
  418. {
  419. ref--;
  420. if( !ref )
  421. delete this;
  422. return 0;
  423. }