#include "Teile.h" #include "Map.h" #include #include #include #include #include #include #include #include // Inhalt der Map Klasse aus Map.h // Konstruktor Map::Map( KSGClient::MinigameServerClient *klient ) { this->klient = klient; map = new RCArray< Array< int > >(); feld = new LRahmen(); feld->setFarbe( 0xFFFFFFFF ); t = { 0, 0, 0, 0 }; beendet = 1; sr = 1; rend = 0; gameTime = 0; rGen = 0; ref = 1; } // Destruktor Map::~Map() { speichern(); map->release(); feld->release(); if( rGen ) rGen->release(); if( klient ) klient->release(); } // nicht constant void Map::reset( Text *zOptionen ) { gameTime = 0; if( rGen ) rGen = rGen->release(); next = 0; score = 0; scoreCheck = score * 11197; map->leeren(); t = { -1, 0, 0, 0 }; Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) ); breite = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 1 ) + 1, zOptionen->positionVon( ',', 1 ) ); höhe = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 2 ) + 1, zOptionen->positionVon( ',', 2 ) ); neuTempo = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 3 ) + 1, zOptionen->positionVon( ',', 3 ) ); geschwindigkeit = *tmp; tmp->release(); tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 4 ) + 1, zOptionen->positionVon( ',', 4 ) ); bool fortsetzen = (int)*tmp != 0; tmp->release(); if( fortsetzen && DateiExistiert( "data/Minigames/Tetris/data/game.save" ) && klient ) { if( capture.istOffen() ) capture.close(); capture.setDatei( "data/Minigames/Tetris/data/game.mgc" ); capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen ); Datei *save = new Datei(); save->setDatei( "data/Minigames/Tetris/data/game.save" ); save->open( Datei::Style::lesen ); int br = 0; int hö = 0; __int64 seed; save->lese( (char*)&seed, 8 ); rGen = new RandomGenerator(); rGen->setSeed( seed ); save->lese( (char*)&gameTime, 8 ); save->lese( (char*)&br, 4 ); save->lese( (char*)&hö, 4 ); if( br == breite && hö == höhe ) { save->lese( (char*)&score, 4 ); scoreCheck = score * 11197; save->lese( (char*)&t, sizeof( Tile ) ); for( int y = 0; y < höhe; y++ ) { map->set( new Array< int >(), y ); for( int x = 0; x < breite; x++ ) { int f = 0; save->lese( (char*)&f, 4 ); map->z( y )->set( f, x ); } } geschwindigkeit -= score * neuTempo; if( geschwindigkeit < 100 ) geschwindigkeit = 100; next = geschwindigkeit / 1000.0; } save->close(); save->release(); } else { rGen = new RandomGenerator(); if( klient ) { if( capture.istOffen() ) capture.close(); DateiRemove( "data/Minigames/Tetris/data/game.mgc" ); capture.setDatei( "data/Minigames/Tetris/data/game.mgc" ); capture.erstellen(); capture.open( Datei::Style::schreiben ); __int64 seed = rGen->getSeed(); capture.schreibe( (char*)&seed, 8 ); } else { tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1 ); rGen->setSeed( (__int64)*tmp ); tmp->release(); } } if( t.id < 0 ) { t.id = (int)( rGen->rand() * 7 ); t.grad = (int)( rGen->rand() * 4 ); t.xPos = breite / 2 - 2; t.yPos = 0; } if( !map->getEintragAnzahl() ) { for( int i = 0; i < höhe; i++ ) { Array< int > *line = new Array< int >(); for( int j = 0; j < breite; j++ ) line->add( 0 ); map->add( line ); } } if( breite < 40 || höhe < 25 ) { int br = breite * 20; if( br > 800 ) br = 800; int hö = höhe * 20; if( hö > 500 ) hö = 500; feld->setPosition( 400 - br / 2, 250 - hö / 2 ); feld->setSize( br, hö ); } beendet = 0; } void Map::doMausEreignis( MausEreignis &me ) { } void Map::doTastaturEreignis( TastaturEreignis &te ) { if( beendet ) return; cs.lock(); bool ok = 1; if( !beendet && te.id == TE_Press ) { int g = t.grad; int xPos = t.xPos; int yPos = t.yPos; bool save = 0; if( te.taste == 'w' || te.taste == 'W' || te.taste == T_Oben ) { g++; if( g >= 4 ) g = 0; save = 1; } if( te.taste == 'd' || te.taste == 'D' || te.taste == T_Rechts ) { xPos++; save = 1; } if( te.taste == 'a' || te.taste == 'A' || te.taste == T_Links ) { xPos--; save = 1; } if( te.taste == 's' || te.taste == 'S' || te.taste == T_Unten ) { yPos++; save = 1; } if( save && klient ) { capture.schreibe( (char*)&gameTime, 8 ); capture.schreibe( (char*)&te.taste, 1 ); } bool ok = 1; for( int x = xPos; x < xPos + 4; x++ ) { for( int y = yPos; y < yPos + 4; y++ ) { if( tiles[ t.id ][ g ][ y - yPos ][ x - xPos ] ) { ok &= x >= 0 && x < breite && y >= 0 && y < höhe; ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0; } } } if( ok ) { t.grad = g; t.xPos = xPos; t.yPos = yPos; rend = 1; } } cs.unlock(); } bool Map::tick( double tickVal ) { bool ret = rend; rend = 0; if( beendet ) return ret; cs.lock(); gameTime += tickVal; next -= tickVal; if( next < 0 ) { next = geschwindigkeit / 1000.0; bool ok = 1; for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos + 1; y < t.yPos + 5; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos - 1 ][ x - t.xPos ] ) { ok &= x >= 0 && x < breite && y >= 0 && y < höhe; ok &= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) == 0; } } } if( ok ) t.yPos++; else { for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos; y < t.yPos + 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] ) map->z( y )->set( tileFarbe[ t.id ], x ); } } for( int y = 0; y < höhe; y++ ) { bool rm = 1; for( int x = 0; x < breite; x++ ) rm &= map->z( y )->get( x ) != 0; if( rm ) { Array< int > *line = new Array< int >(); for( int i = 0; i < breite; i++ ) line->add( 0 ); map->remove( y ); map->add( line, 0 ); score++; scoreCheck = score * 11197; geschwindigkeit -= neuTempo; } } t.id = (int)( rGen->rand() * 7 ); t.grad = (int)( rGen->rand() * 4 ); t.xPos = breite / 2 - 2; t.yPos = 0; for( int x = t.xPos; x < t.xPos + 4; x++ ) { for( int y = t.yPos; y < t.yPos + 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y - t.yPos ][ x - t.xPos ] ) beendet |= ( ( x >= 0 && x < breite && y >= 0 && y < höhe ) ? map->z( y )->get( x ) : -1 ) != 0; } } if( score * 11197 != scoreCheck ) { score = 0; scoreCheck = 0; beendet = 1; } if( beendet && klient ) { capture.close(); DateiRemove( "data/Minigames/Tetris/data/upload.mgc" ); DateiUmbenennen( "data/Minigames/Tetris/data/game.mgc", "data/Minigames/Tetris/data/upload.mgc" ); int tmpScore = score; KSGClient::MinigameServerClient *tmpKlient = klient->getThis(); new AsynchronCall( [ tmpScore, tmpKlient ]() { InitDatei *opd = new InitDatei( "data/Minigames/Tetris/data/optionen.ini" ); opd->laden(); Text optionen = "Width="; optionen += opd->zWert( "Breite" )->getText(); optionen += ",Height="; optionen += opd->zWert( "Höhe" )->getText(); optionen += ",NSpeed="; optionen += opd->zWert( "+Geschwindigkeit" )->getText(); optionen += ",Speed="; optionen += opd->zWert( "Geschwindigkeit" )->getText(); opd->release(); Datei d; d.setDatei( "data/Minigames/Tetris/data/upload.mgc" ); tmpKlient->reportEndOfGame( "Tetris", optionen, tmpScore, &d ); DateiRemove( "data/Minigames/Tetris/data/upload.mgc" ); tmpKlient->release(); } ); DateiRemove( "data/Minigames/Tetris/data/game.save" ); KSGTDatei *stb = new KSGTDatei( "data/Minigames/Tetris/data/score.ksgt" ); if( !stb->laden() ) DateiPfadErstellen( "data/Minigames/Tetris/data/score.ksgt" ); RCArray< Text > *zeile = new RCArray< Text >(); Zeit *zeit = getZeit(); zeile->add( zeit->getZeit( "y-m-d h:i:s" ) ); zeit->release(); Text *scoreT = new Text(); scoreT->append( score ); zeile->add( scoreT ); Text *breiteT = new Text(); breiteT->append( breite ); zeile->add( breiteT ); Text *höheT = new Text(); höheT->append( höhe ); zeile->add( höheT ); Text *geschwindigkeitT = new Text(); geschwindigkeitT->append( geschwindigkeit ); zeile->add( geschwindigkeitT ); Text *neuTempoT = new Text(); neuTempoT->append( neuTempo ); zeile->add( neuTempoT ); stb->addZeile( 6, zeile ); zeile->release(); stb->speichern(); stb->release(); } } ret = 1; } cs.unlock(); return ret; } void Map::render( Bild &zRObj ) { int xS = feld->getX(); int yS = feld->getY(); int blockBr = 800 / breite; if( blockBr > 20 ) blockBr = 20; int blockHö = 500 / höhe; if( blockHö > 20 ) blockHö = 20; for( int x = 0; x < breite; x++ ) { for( int y = 0; y < höhe; y++ ) zRObj.fillRegion( xS + x * blockBr, yS + y * blockHö, blockBr - 1, blockHö - 1, map->z( y )->get( x ) ); } for( int x = 0; x < 4; x++ ) { for( int y = 0; y < 4; y++ ) { if( tiles[ t.id ][ t.grad ][ y ][ x ] ) zRObj.fillRegion( xS + ( x + t.xPos ) * blockBr, yS + ( y + t.yPos ) * blockHö, blockBr - 1, blockHö - 1, tileFarbe[ t.id ] ); } } feld->render( zRObj ); } void Map::speichern() { if( !beendet ) { if( capture.istOffen() ) capture.close(); Datei *d = new Datei(); d->setDatei( "data/Minigames/Tetris/data/game.save" ); d->erstellen(); d->open( Datei::Style::schreiben ); __int64 seed = rGen->getSeed(); d->schreibe( (char*)&seed, 8 ); d->schreibe( (char*)&gameTime, 8 ); d->schreibe( (char*)&breite, 4 ); d->schreibe( (char*)&höhe, 4 ); d->schreibe( (char*)&score, 4 ); d->schreibe( (char*)&t, sizeof( Tile ) ); for( int y = 0; y < höhe; y++ ) { for( int x = 0; x < breite; x++ ) { int f = map->z( y )->get( x ); d->schreibe( (char*)&f, 4 ); } } d->close(); d->release(); } else if( klient ) DateiRemove( "data/Minigames/Tetris/data/game.save" ); } // constant int Map::getScore() const { return score; } bool Map::istBeendet() const { return beendet; } // Reference Counting Map *Map::getThis() { ref++; return this; } Map *Map::release() { ref--; if( !ref ) delete this; return 0; }