Map.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #include "Map.h"
  2. #include <InitDatei.h>
  3. #include <Datei.h>
  4. #include <KSGTDatei.h>
  5. #include <Zeit.h>
  6. #include <Text.h>
  7. #include <TastaturEreignis.h>
  8. #include <MausEreignis.h>
  9. #include <AsynchronCall.h>
  10. // Inhalt der Map Klasse aus Map.h
  11. // Konstruktor
  12. Map::Map( KSGClient::MinigameServerClient *klient )
  13. {
  14. this->klient = klient;
  15. map = new RCArray< Array< int > >();
  16. score = 0;
  17. scoreCheck = score * 11197;
  18. breite = 0;
  19. höhe = 0;
  20. geschwindigkeit = 0;
  21. bAnzahl = 0;
  22. next = 0;
  23. beendet = 1;
  24. rend = 0;
  25. rGen = 0;
  26. gameTime = 0;
  27. ref = 1;
  28. }
  29. // Destruktor
  30. Map::~Map()
  31. {
  32. speichern();
  33. map->release();
  34. if( rGen )
  35. rGen->release();
  36. if( klient )
  37. klient->release();
  38. }
  39. // private
  40. void Map::remove( int x, int y )
  41. {
  42. if( !map->z( x ) || !map->z( x )->hat( y ) || !map->z( x )->get( y ) )
  43. return;
  44. int f = map->z( x )->get( y );
  45. map->z( x )->set( 0, y );
  46. if( !f )
  47. return;
  48. if( map->z( x - 1 ) && map->z( x - 1 )->hat( y ) && map->z( x - 1 )->get( y ) == f )
  49. remove( x - 1, y );
  50. if( map->z( x + 1 ) && map->z( x + 1 )->hat( y ) && map->z( x + 1 )->get( y ) == f )
  51. remove( x + 1, y );
  52. if( map->z( x ) && map->z( x )->hat( y - 1 ) && map->z( x )->get( y - 1 ) == f )
  53. remove( x, y - 1 );
  54. if( map->z( x ) && map->z( x )->hat( y + 1 ) && map->z( x )->get( y + 1 ) == f )
  55. remove( x, y + 1 );
  56. }
  57. // nicht constant
  58. void Map::reset( Text *zOptionen )
  59. {
  60. gameTime = 0;
  61. next = 0;
  62. beendet = 0;
  63. score = 0;
  64. scoreCheck = score * 11197;
  65. map->leeren();
  66. Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
  67. breite = *tmp;
  68. tmp->release();
  69. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) );
  70. höhe = *tmp;
  71. tmp->release();
  72. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) );
  73. bAnzahl = *tmp;
  74. tmp->release();
  75. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) );
  76. geschwindigkeit = *tmp;
  77. tmp->release();
  78. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) );
  79. bool fortsetzen = (int)*tmp != 0;
  80. tmp->release();
  81. if( rGen )
  82. rGen = rGen->release();
  83. if( fortsetzen && DateiExistiert( "data/Minigames/Blöcke/data/game.save" ) && klient )
  84. {
  85. if( capture.istOffen() )
  86. capture.close();
  87. capture.setDatei( "data/Minigames/Blöcke/data/game.mgc" );
  88. capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
  89. Datei *save = new Datei();
  90. save->setDatei( "data/Minigames/Blöcke/data/game.save" );
  91. save->open( Datei::Style::lesen );
  92. int br = 0;
  93. int hö = 0;
  94. __int64 seed;
  95. save->lese( (char*)&seed, 8 );
  96. rGen = new RandomGenerator();
  97. rGen->setSeed( seed );
  98. save->lese( (char*)&gameTime, 8 );
  99. save->lese( (char*)&br, 4 );
  100. save->lese( (char*)&hö, 4 );
  101. if( br == breite && hö == höhe )
  102. {
  103. save->lese( (char*)&score, 4 );
  104. scoreCheck = score * 11197;
  105. for( int x = 0; x < breite; x++ )
  106. {
  107. map->set( new Array< int >(), x );
  108. for( int y = 0; y < höhe; y++ )
  109. {
  110. int f = 0;
  111. save->lese( (char*)&f, 4 );
  112. map->z( x )->set( f, y );
  113. }
  114. }
  115. next = geschwindigkeit / 1000.0;
  116. }
  117. save->close();
  118. save->release();
  119. int xOff = 0;
  120. for( int x = 0; x < breite; x++ )
  121. {
  122. if( !map->z( x - xOff ) )
  123. continue;
  124. Array< int > *row = map->z( x - xOff );
  125. int yOff = 0;
  126. for( int y = 0; y < höhe; y++ )
  127. {
  128. if( row->hat( y - yOff ) && !row->get( y - yOff ) )
  129. {
  130. row->remove( y - yOff );
  131. yOff++;
  132. }
  133. }
  134. bool del = 1;
  135. for( int y = 0; y < höhe; y++ )
  136. del &= !row->hat( y - yOff ) || !row->get( y - yOff );
  137. if( del )
  138. {
  139. map->remove( x - xOff );
  140. xOff++;
  141. }
  142. }
  143. }
  144. else
  145. {
  146. rGen = new RandomGenerator();
  147. if( klient )
  148. {
  149. if( capture.istOffen() )
  150. capture.close();
  151. DateiRemove( "data/Minigames/Blöcke/data/game.mgc" );
  152. capture.setDatei( "data/Minigames/Blöcke/data/game.mgc" );
  153. capture.erstellen();
  154. capture.open( Datei::Style::schreiben );
  155. __int64 seed = rGen->getSeed();
  156. capture.schreibe( (char*)&seed, 8 );
  157. }
  158. else
  159. {
  160. tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1 );
  161. rGen->setSeed( (__int64)*tmp );
  162. tmp->release();
  163. }
  164. }
  165. }
  166. void Map::doMausEreignis( MausEreignis &me )
  167. {
  168. if( beendet )
  169. return;
  170. cs.lock();
  171. if( me.id == ME_RRechts )
  172. {
  173. next = 0;
  174. if( klient )
  175. {
  176. capture.schreibe( (char*)&gameTime, 8 );
  177. capture.schreibe( "\x1", 1 );
  178. }
  179. }
  180. if( me.id != ME_RLinks )
  181. {
  182. cs.unlock();
  183. return;
  184. }
  185. if( klient )
  186. {
  187. capture.schreibe( (char*)&gameTime, 8 );
  188. capture.schreibe( "\x0", 1 );
  189. capture.schreibe( (char*)&me.mx, 4 );
  190. capture.schreibe( (char*)&me.my, 4 );
  191. }
  192. int x = (int)( me.mx / ( 800.0 / breite ) );
  193. int y = (int)( höhe - ( me.my / ( 500.0 / höhe ) ) );
  194. if( !map->z( x ) || !map->z( x )->hat( y ) || !map->z( x )->get( y ) )
  195. {
  196. cs.unlock();
  197. return;
  198. }
  199. bool remove = 0;
  200. int f = map->z( x )->get( y );
  201. if( map->z( x - 1 ) && map->z( x - 1 )->hat( y ) && map->z( x - 1 )->get( y ) == f )
  202. remove = 1;
  203. if( map->z( x + 1 ) && map->z( x + 1 )->hat( y ) && map->z( x + 1 )->get( y ) == f )
  204. remove = 1;
  205. if( map->z( x ) && map->z( x )->hat( y - 1 ) && map->z( x )->get( y - 1 ) == f )
  206. remove = 1;
  207. if( map->z( x ) && map->z( x )->hat( y + 1 ) && map->z( x )->get( y + 1 ) == f )
  208. remove = 1;
  209. if( !remove )
  210. {
  211. cs.unlock();
  212. return;
  213. }
  214. rend = 1;
  215. this->remove( x, y );
  216. int xOff = 0;
  217. for( int x = 0; x < breite; x++ )
  218. {
  219. if( !map->z( x - xOff ) )
  220. continue;
  221. Array< int > *row = map->z( x - xOff );
  222. int yOff = 0;
  223. for( int y = 0; y < höhe; y++ )
  224. {
  225. if( row->hat( y - yOff ) && !row->get( y - yOff ) )
  226. {
  227. row->remove( y - yOff );
  228. yOff++;
  229. }
  230. }
  231. bool del = 1;
  232. for( int y = 0; y < höhe; y++ )
  233. del &= !row->hat( y - yOff ) || !row->get( y - yOff );
  234. if( del )
  235. {
  236. score++;
  237. scoreCheck = score * 11197;
  238. map->remove( x - xOff );
  239. xOff++;
  240. }
  241. }
  242. cs.unlock();
  243. }
  244. void Map::doTastaturEreignis( TastaturEreignis &te )
  245. {
  246. cs.lock();
  247. if( te.id == TE_Release )
  248. {
  249. next = 0;
  250. if( klient )
  251. {
  252. capture.schreibe( (char*)&gameTime, 8 );
  253. capture.schreibe( "\x1", 1 );
  254. }
  255. }
  256. cs.unlock();
  257. }
  258. bool Map::tick( double tickVal )
  259. {
  260. bool ret = rend;
  261. rend = 0;
  262. if( beendet )
  263. return ret;
  264. cs.lock();
  265. gameTime += tickVal;
  266. next -= tickVal;
  267. if( next < 0 )
  268. {
  269. next = geschwindigkeit / 1000.0;
  270. Array< int > *n = new Array< int >();
  271. for( int i = 0; i < höhe; i++ )
  272. {
  273. int val = (int)( rGen->rand() * bAnzahl );
  274. switch( val )
  275. {
  276. case 0:
  277. n->set( 0xFFFF0000, i );
  278. break;
  279. case 1:
  280. n->set( 0xFF00FF00, i );
  281. break;
  282. case 2:
  283. n->set( 0xFF0000FF, i );
  284. break;
  285. case 3:
  286. n->set( 0xFFFFFF00, i );
  287. break;
  288. case 4:
  289. n->set( 0xFF00FFFF, i );
  290. break;
  291. case 5:
  292. n->set( 0xFFFF00FF, i );
  293. break;
  294. case 6:
  295. n->set( 0xFFFFFFFF, i );
  296. break;
  297. case 7:
  298. n->set( 0xFFFF5555, i );
  299. break;
  300. case 8:
  301. n->set( 0xFF55FF55, i );
  302. break;
  303. case 9:
  304. n->set( 0xFF5555FF, i );
  305. break;
  306. default:
  307. n->set( 0xFF000000, i );
  308. break;
  309. }
  310. }
  311. map->add( n, 0 );
  312. if( map->z( breite ) )
  313. {
  314. Array< int > *row = map->z( breite );
  315. for( int i = 0; i < höhe; i++ )
  316. {
  317. if( row->hat( i ) )
  318. beendet |= row->get( i ) != 0;
  319. }
  320. beendet |= ( score * 11197 != scoreCheck );
  321. if( score * 11197 != scoreCheck )
  322. {
  323. score = 0;
  324. scoreCheck = 0;
  325. }
  326. if( beendet && klient )
  327. {
  328. capture.close();
  329. DateiRemove( "data/Minigames/Blöcke/data/upload.mgc" );
  330. DateiUmbenennen( "data/Minigames/Blöcke/data/game.mgc", "data/Minigames/Blöcke/data/upload.mgc" );
  331. int tmpScore = score;
  332. KSGClient::MinigameServerClient *tmpKlient = klient->getThis();
  333. new AsynchronCall( [ tmpScore, tmpKlient ]()
  334. {
  335. InitDatei *opd = new InitDatei( "data/Minigames/Blöcke/data/optionen.ini" );
  336. opd->laden();
  337. if( !opd->wertExistiert( "Breite" ) )
  338. opd->addWert( "Breite", "20" );
  339. if( !opd->wertExistiert( "Height" ) )
  340. opd->addWert( "Height", "12" );
  341. if( !opd->wertExistiert( "Farben" ) )
  342. opd->addWert( "Farben", "5" );
  343. if( !opd->wertExistiert( "Geschwindigkeit" ) )
  344. opd->addWert( "Geschwindigkeit", "4000" );
  345. if( !opd->wertExistiert( "Fortsetzen" ) )
  346. opd->addWert( "Fortsetzen", "0" );
  347. Text optionen = "Width=";
  348. optionen += opd->zWert( "Breite" )->getText();
  349. optionen += ",Height=";
  350. optionen += opd->zWert( "Height" )->getText();
  351. optionen += ",Farben=";
  352. optionen += opd->zWert( "Farben" )->getText();
  353. optionen += ",Speed=";
  354. optionen += opd->zWert( "Geschwindigkeit" )->getText();
  355. opd->release();
  356. Datei d;
  357. d.setDatei( "data/Minigames/Blöcke/data/upload.mgc" );
  358. tmpKlient->reportEndOfGame( "Bloecke", optionen, tmpScore, &d );
  359. DateiRemove( "data/Minigames/Blöcke/data/upload.mgc" );
  360. tmpKlient->release();
  361. } );
  362. KSGTDatei *stb = new KSGTDatei( "data/Minigames/Blöcke/data/score.ksgt" );
  363. if( !stb->laden() )
  364. DateiPfadErstellen( "data/Minigames/Blöcke/data/score.ksgt" );
  365. RCArray< Text > *zeile = new RCArray< Text >();
  366. Zeit *zeit = getZeit();
  367. zeile->add( zeit->getZeit( "y-m-d h:i:s" ) );
  368. zeit->release();
  369. Text *scoreT = new Text();
  370. scoreT->append( score );
  371. zeile->add( scoreT );
  372. Text *breiteT = new Text();
  373. breiteT->append( breite );
  374. zeile->add( breiteT );
  375. Text *höheT = new Text();
  376. höheT->append( höhe );
  377. zeile->add( höheT );
  378. Text *geschwindigkeitT = new Text();
  379. geschwindigkeitT->append( geschwindigkeit );
  380. zeile->add( geschwindigkeitT );
  381. Text *bAnzahlT = new Text();
  382. bAnzahlT->append( bAnzahl );
  383. zeile->add( bAnzahlT );
  384. stb->addZeile( 6, zeile );
  385. zeile->release();
  386. stb->speichern();
  387. stb->release();
  388. DateiRemove( "data/Minigames/Blöcke/data/game.save" );
  389. }
  390. }
  391. map->remove( breite );
  392. ret = 1;
  393. }
  394. cs.unlock();
  395. return ret;
  396. }
  397. void Map::render( Bild &zRObj )
  398. {
  399. for( int x = 0; x < breite; x++ )
  400. {
  401. if( !map->z( x ) )
  402. continue;
  403. Array< int > *row = map->z( x );
  404. for( int y = 0; y < höhe; y++ )
  405. {
  406. if( !row->hat( y ) )
  407. continue;
  408. int xs = (int)( x * ( 800.0 / breite ) );
  409. int ys = (int)( ( höhe - y - 1 ) * ( 500.0 / höhe ) );
  410. int xe = (int)( ( x + 1 ) * ( 800.0 / breite ) );
  411. int ye = (int)( ( höhe - y ) * ( 500.0 / höhe ) );
  412. zRObj.fillRegion( xs, ys, xe - xs, ye - ys, row->get( y ) );
  413. }
  414. }
  415. }
  416. void Map::speichern()
  417. {
  418. if( !beendet && klient )
  419. {
  420. if( capture.istOffen() )
  421. capture.close();
  422. Datei *d = new Datei();
  423. d->setDatei( "data/Minigames/Blöcke/data/game.save" );
  424. d->erstellen();
  425. d->open( Datei::Style::schreiben );
  426. __int64 seed = rGen->getSeed();
  427. d->schreibe( (char*)&seed, 8 );
  428. d->schreibe( (char*)&gameTime, 8 );
  429. d->schreibe( (char*)&breite, 4 );
  430. d->schreibe( (char*)&höhe, 4 );
  431. d->schreibe( (char*)&score, 4 );
  432. for( int x = 0; x < breite; x++ )
  433. {
  434. for( int y = 0; y < höhe; y++ )
  435. {
  436. int f = 0;
  437. if( map->z( x ) && map->z( x )->hat( y ) )
  438. f = map->z( x )->get( y );
  439. d->schreibe( (char*)&f, 4 );
  440. }
  441. }
  442. d->close();
  443. d->release();
  444. }
  445. else if( klient )
  446. DateiRemove( "data/Minigames/Blöcke/data/game.save" );
  447. }
  448. // constant
  449. int Map::getScore() const
  450. {
  451. return score;
  452. }
  453. bool Map::istBeendet() const
  454. {
  455. return beendet;
  456. }
  457. // Reference Counting
  458. Map *Map::getThis()
  459. {
  460. ref++;
  461. return this;
  462. }
  463. Map *Map::release()
  464. {
  465. ref--;
  466. if( !ref )
  467. delete this;
  468. return 0;
  469. }