Jelajahi Sumber

schnitstelle für ki hinzugefügt

Kolja Strohm 5 tahun lalu
induk
melakukan
e436ba0acf
5 mengubah file dengan 522 tambahan dan 218 penghapusan
  1. 136 4
      Fangen/Einstieg.cpp
  2. 335 210
      Fangen/Map.cpp
  3. 18 0
      Fangen/Map.h
  4. 29 4
      Fangen/Spieler.cpp
  5. 4 0
      Fangen/Spieler.h

+ 136 - 4
Fangen/Einstieg.cpp

@@ -1,9 +1,141 @@
 #include "Game.h"
+#include <InitDatei.h>
+#include <TastaturEreignis.h>
+#include <Globals.h>
+#include <iostream>
+
+int gameCount = 0;
 
 extern "C"
 {
-	__declspec( dllexport ) MiniGameV *GetMiniGame()
-	{
-		return new Game();
-	}
+    __declspec( dllexport ) MiniGameV *GetMiniGame()
+    {
+        return new Game();
+    }
+
+    __declspec( dllexport ) void *InitializeFromPython()
+    {
+        initFramework();
+        gameCount++;
+        Map *map = new Map( 0 );
+        InitDatei *opd = new InitDatei( "optionen.ini" );
+        if( !opd->laden() )
+            DateiPfadErstellen( "optionen.ini" );
+        Text optionen = "Width=";
+        if( opd->wertExistiert( "Breite" ) )
+            optionen += (int)* opd->zWert( "Breite" );
+        else
+        {
+            opd->addWert( "Breite", "800" );
+            optionen += 800;
+        }
+        optionen += ",Height=";
+        if( opd->wertExistiert( "Höhe" ) )
+            optionen += (int)* opd->zWert( "Höhe" );
+        else
+        {
+            opd->addWert( "Höhe", "500" );
+            optionen += 500;
+        }
+        optionen += ",Ziele=";
+        if( opd->wertExistiert( "Ziele" ) )
+            optionen += (int)* opd->zWert( "Ziele" );
+        else
+        {
+            opd->addWert( "Ziele", "1" );
+            optionen += 1;
+        }
+        optionen += ",Gegner=";
+        if( opd->wertExistiert( "+Gegner" ) )
+            optionen += (int)* opd->zWert( "+Gegner" );
+        else
+        {
+            opd->addWert( "+Gegner", "3" );
+            optionen += 3;
+        }
+        optionen += ",Speed=";
+        if( opd->wertExistiert( "Geschwindigkeit" ) )
+            optionen += (int)* opd->zWert( "Geschwindigkeit" );
+        else
+        {
+            opd->addWert( "Geschwindigkeit", "1000" );
+            optionen += 1000;
+        }
+        bool fortsetzen = 0;
+        optionen += ",Fortsetzen=";
+        if( opd->wertExistiert( "Fortsetzen" ) )
+            optionen += (int)* opd->zWert( "Fortsetzen" ) != 0;
+        else
+        {
+            opd->addWert( "Fortsetzen", "0" );
+            optionen += 0;
+        }
+        opd->speichern();
+        opd->release();
+        RandomGenerator *rGen = new RandomGenerator();
+        optionen += Text( ",Seed=" ) + rGen->getSeed();
+        rGen->release();
+        map->reset( &optionen );
+        Sleep( rand() % 1000 );
+        return map;
+    }
+
+    __declspec( dllexport ) bool CanGoDown( void *game )
+    {
+        return ( (Map *)game )->canGoDown();
+    }
+
+    __declspec( dllexport ) bool CanGoLeft( void *game )
+    {
+        return ( (Map *)game )->canGoLeft();
+    }
+
+    __declspec( dllexport ) bool CanGoUp( void *game )
+    {
+        return ( (Map *)game )->canGoUp();
+    }
+
+    __declspec( dllexport ) bool CanGoRight( void *game )
+    {
+        return ( (Map *)game )->canGoRight();
+    }
+
+    __declspec( dllexport ) void GetBestOption( void *game, bool *left, bool *right, bool *up, bool *down )
+    {
+        ( (Map *)game )->getBestOption( left, up, right, down, 4 );
+    }
+
+    __declspec( dllexport ) bool NextFrameFromPython( void *game, char left, char right, char top, char down, int *frame )
+    {
+        TastaturEreignis te;
+        te.taste = T_Links;
+        te.verarbeitet = 0;
+        te.id = left ? TE_Press : TE_Release;
+        ( (Map *)game )->doTastaturEreignis( te );
+        te.taste = T_Oben;
+        te.verarbeitet = 0;
+        te.id = top ? TE_Press : TE_Release;
+        ( (Map *)game )->doTastaturEreignis( te );
+        te.taste = T_Rechts;
+        te.verarbeitet = 0;
+        te.id = right ? TE_Press : TE_Release;
+        ( (Map *)game )->doTastaturEreignis( te );
+        te.taste = T_Unten;
+        te.verarbeitet = 0;
+        te.id = down ? TE_Press : TE_Release;
+        ( (Map *)game )->doTastaturEreignis( te );
+        ( (Map *)game )->tick( 0.05 );
+        Bild *b = new Bild( 1 );
+        b->setPixelBuffer( frame, 0, 800, 500 );
+        ( (Map *)game )->render( *b );
+        b->release();
+        return !( (Map *)game )->istBeendet();
+    }
+
+    __declspec( dllexport ) void ReleaseFromPython( void *game )
+    {
+        ( (Map *)game )->release();
+        if( !gameCount-- )
+            releaseFramework();
+    }
 }

+ 335 - 210
Fangen/Map.cpp

@@ -5,41 +5,42 @@
 #include <Zeit.h>
 #include <KSGTDatei.h>
 #include <AsynchronCall.h>
+#include <iostream>
 
 // Inhalt der Map Klasse aus Map.h
 // Konstruktor
 Map::Map( KSGClient::MinigameServerClient *klient )
 {
     this->klient = klient;
-	gegner = new RCArray< Spieler >();
-	ziele = new RCArray< Spieler >();
-	spieler = 0;
-	feld = new LRahmen();
-	feld->setFarbe( 0xFFFFFFFF );
-	kam = new LRahmen();
-	kam->setFarbe( 0xFF777777 );
-	map = new LRahmen();
-	map->setFarbe( 0xFFFFFFFF );
-	map->setPosition( 10, 10 );
-	map->setSize( 200, 200 );
-	beendet = 1;
+    gegner = new RCArray< Spieler >();
+    ziele = new RCArray< Spieler >();
+    spieler = 0;
+    feld = new LRahmen();
+    feld->setFarbe( 0xFFFFFFFF );
+    kam = new LRahmen();
+    kam->setFarbe( 0xFF777777 );
+    map = new LRahmen();
+    map->setFarbe( 0xFFFFFFFF );
+    map->setPosition( 10, 10 );
+    //map->setSize( 200, 200 );
+    beendet = 1;
     gameTime = 0;
     tastenStände = 0;
     rGen = 0;
-	ref = 1;
+    ref = 1;
 }
 
 // Destruktor
 Map::~Map()
 {
-	speichern();
-	gegner->release();
-	ziele->release();
-	if( spieler )
-		spieler->release();
-	feld->release();
-	kam->release();
-	map->release();
+    speichern();
+    gegner->release();
+    ziele->release();
+    if( spieler )
+        spieler->release();
+    feld->release();
+    kam->release();
+    map->release();
     if( rGen )
         rGen->release();
     if( klient )
@@ -53,14 +54,14 @@ void Map::reset( Text *zOptionen )
     tastenStände = 0;
     if( rGen )
         rGen = rGen->release();
-	beendet = 0;
-	score = 0;
+    beendet = 0;
+    score = 0;
     scoreCheck = score * 11197;
-	gegner->leeren();
-	ziele->leeren();
-	if( spieler )
-		spieler = spieler->release();
-	ziele->leeren();
+    gegner->leeren();
+    ziele->leeren();
+    if( spieler )
+        spieler = spieler->release();
+    ziele->leeren();
     Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
     breite = *tmp;
     tmp->release();
@@ -77,48 +78,48 @@ void Map::reset( Text *zOptionen )
     geschwindigkeit = *tmp;
     tmp->release();
     tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) );
-    bool fortsetzen = (int)*tmp != 0;
+    bool fortsetzen = (int)* tmp != 0;
     tmp->release();
-	kamX = 0;
-	kamY = 0;
-	if( breite > 80 )
-		kamX = breite / 2 - 400;
-	if( höhe > 50 )
-		kamY = höhe / 2 - 250;
-	if( fortsetzen && DateiExistiert( "data/Minigames/Fangen/data/game.save" ) && klient )
-	{
+    kamX = 0;
+    kamY = 0;
+    if( breite > 80 )
+        kamX = breite / 2 - 400;
+    if( höhe > 50 )
+        kamY = höhe / 2 - 250;
+    if( fortsetzen && DateiExistiert( "data/Minigames/Fangen/data/game.save" ) && klient )
+    {
         if( capture.istOffen() )
             capture.close();
         capture.setDatei( "data/Minigames/Fangen/data/game.mgc" );
         capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
-        Datei *save = new Datei();
-		save->setDatei( "data/Minigames/Fangen/data/game.save" );
-		save->open( Datei::Style::lesen );
-		int br = 0;
-		int hö = 0;
+        Datei * save = new Datei();
+        save->setDatei( "data/Minigames/Fangen/data/game.save" );
+        save->open( Datei::Style::lesen );
+        int br = 0;
+        int hö = 0;
         __int64 seed;
-        save->lese( (char*)&seed, 8 );
+        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 );
+        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;
-			spieler = new Spieler( SPIELER, save );
-			int anz = 0;
-			save->lese( (char*)&anz, 4 );
-			for( int i = 0; i < anz; i++ )
-				gegner->add( new Spieler( GEGNER, save ) );
-			save->lese( (char*)&anz, 4 );
-			for( int i = 0; i < anz; i++ )
-				ziele->add( new Spieler( ZIEL, save ) );
-		}
-		save->close();
-		save->release();
-	}
+            spieler = new Spieler( SPIELER, save );
+            int anz = 0;
+            save->lese( (char *)& anz, 4 );
+            for( int i = 0; i < anz; i++ )
+                gegner->add( new Spieler( GEGNER, save ) );
+            save->lese( (char *)& anz, 4 );
+            for( int i = 0; i < anz; i++ )
+                ziele->add( new Spieler( ZIEL, save ) );
+        }
+        save->close();
+        save->release();
+    }
     else
     {
         rGen = new RandomGenerator();
@@ -131,35 +132,35 @@ void Map::reset( Text *zOptionen )
             capture.erstellen();
             capture.open( Datei::Style::schreiben );
             __int64 seed = rGen->getSeed();
-            capture.schreibe( (char*)&seed, 8 );
+            capture.schreibe( (char *)& seed, 8 );
         }
         else
         {
             tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 6 ) + 1 );
-            rGen->setSeed( (__int64)*tmp );
+            rGen->setSeed( (__int64)* tmp );
             tmp->release();
         }
     }
-	if( !spieler )
-		spieler = new Spieler( SPIELER, breite, höhe, rGen );
-	if( !gegner->getEintragAnzahl() )
-	{
-		for( int i = 0; i < neuGegner; i++ )
-			gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
-	}
-	if( !ziele->getEintragAnzahl() )
-	{
-		for( int i = 0; i < zAnzahl; i++ )
-			ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
-	}
+    if( !spieler )
+        spieler = new Spieler( SPIELER, breite, höhe, rGen );
+    if( !gegner->getEintragAnzahl() )
+    {
+        for( int i = 0; i < neuGegner; i++ )
+            gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
+    }
+    if( !ziele->getEintragAnzahl() )
+    {
+        for( int i = 0; i < zAnzahl; i++ )
+            ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
+    }
 }
 
-void Map::doPublicMausEreignis( MausEreignis &me )
+void Map::doPublicMausEreignis( MausEreignis & me )
 {
 
 }
 
-void Map::doTastaturEreignis( TastaturEreignis &te )
+void Map::doTastaturEreignis( TastaturEreignis & te )
 {
     cs.lock();
     bool ok = 1;
@@ -198,7 +199,7 @@ void Map::doTastaturEreignis( TastaturEreignis &te )
         {
             if( klient )
             {
-                capture.schreibe( (char*)&gameTime, 8 );
+                capture.schreibe( (char *)& gameTime, 8 );
                 capture.schreibe( &tastenStände, 1 );
             }
         }
@@ -208,8 +209,8 @@ void Map::doTastaturEreignis( TastaturEreignis &te )
 
 bool Map::tick( double tickVal )
 {
-	if( beendet || !spieler )
-		return 0;
+    if( beendet || !spieler )
+        return 0;
     if( score * 11197 != scoreCheck )
     {
         beendet = 1;
@@ -218,48 +219,48 @@ bool Map::tick( double tickVal )
     }
     cs.lock();
     gameTime += tickVal;
-	double t = tickVal * geschwindigkeit / 1000;
-	spieler->tick( t, breite, höhe, tastenStände );
-	int anz = gegner->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		gegner->z( i )->tick( t, breite, höhe, tastenStände );
-		if( gegner->z( i )->berührt( spieler->getX(), spieler->getY() ) )
-			beendet = 1;
-	}
-	anz = ziele->getEintragAnzahl();
-	for( int i = 0; i < anz; i++ )
-	{
-		ziele->z( i )->tick( t, breite, höhe, tastenStände );
-		if( ziele->z( i )->berührt( spieler->getX(), spieler->getY() ) )
-		{
-			score++;
+    double t = tickVal * geschwindigkeit / 1000;
+    spieler->tick( t, breite, höhe, tastenStände );
+    int anz = gegner->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        gegner->z( i )->tick( t, breite, höhe, tastenStände );
+        if( gegner->z( i )->berührt( spieler->getX(), spieler->getY() ) )
+            beendet = 1;
+    }
+    anz = ziele->getEintragAnzahl();
+    for( int i = 0; i < anz; i++ )
+    {
+        ziele->z( i )->tick( t, breite, höhe, tastenStände );
+        if( ziele->z( i )->berührt( spieler->getX(), spieler->getY() ) )
+        {
+            score++;
             scoreCheck = score * 11197;
-			ziele->leeren();
-			for( int i = 0; i < zAnzahl; i++ )
-				ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
-			for( int i = 0; i < neuGegner; i++ )
-				gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
-		}
-	}
-	if( breite > 800 )
-	{
-		kamX = (int)spieler->getX() - 400;
-		if( kamX < 0 )
-			kamX = 0;
-		if( kamX + 800 > breite )
-			kamX = breite - 800;
-	}
-	if( höhe > 500 )
-	{
-		kamY = (int)spieler->getY() - 250;
-		if( kamY < 0 )
-			kamY = 0;
-		if( kamY + 500 > höhe )
-			kamY = höhe - 500;
-	}
-	if( beendet && klient )
-	{
+            ziele->leeren();
+            for( int i = 0; i < zAnzahl; i++ )
+                ziele->add( new Spieler( ZIEL, breite, höhe, rGen ) );
+            for( int i = 0; i < neuGegner; i++ )
+                gegner->add( new Spieler( GEGNER, breite, höhe, rGen ) );
+        }
+    }
+    if( breite > 800 )
+    {
+        kamX = (int)spieler->getX() - 400;
+        if( kamX < 0 )
+            kamX = 0;
+        if( kamX + 800 > breite )
+            kamX = breite - 800;
+    }
+    if( höhe > 500 )
+    {
+        kamY = (int)spieler->getY() - 250;
+        if( kamY < 0 )
+            kamY = 0;
+        if( kamY + 500 > höhe )
+            kamY = höhe - 500;
+    }
+    if( beendet && klient )
+    {
         capture.close();
         DateiRemove( "data/Minigames/Fangen/data/upload.mgc" );
         DateiUmbenennen( "data/Minigames/Fangen/data/game.mgc", "data/Minigames/Fangen/data/upload.mgc" );
@@ -286,85 +287,85 @@ bool Map::tick( double tickVal )
             DateiRemove( "data/Minigames/Fangen/data/upload.mgc" );
             tmpKlient->release();
         } );
-		KSGTDatei *stb = new KSGTDatei( "data/Minigames/Fangen/data/score.ksgt" );
-		if( !stb->laden() )
-			DateiPfadErstellen( "data/Minigames/Fangen/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 *zAnzahlT = new Text();
-		zAnzahlT->append( zAnzahl );
-		zeile->add( zAnzahlT );
-		Text *nAnzahlT = new Text();
-		nAnzahlT->append( neuGegner );
-		zeile->add( nAnzahlT );
-		stb->addZeile( 7, zeile );
-		zeile->release();
-		stb->speichern();
-		stb->release();
+        KSGTDatei *stb = new KSGTDatei( "data/Minigames/Fangen/data/score.ksgt" );
+        if( !stb->laden() )
+            DateiPfadErstellen( "data/Minigames/Fangen/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 *zAnzahlT = new Text();
+        zAnzahlT->append( zAnzahl );
+        zeile->add( zAnzahlT );
+        Text *nAnzahlT = new Text();
+        nAnzahlT->append( neuGegner );
+        zeile->add( nAnzahlT );
+        stb->addZeile( 7, zeile );
+        zeile->release();
+        stb->speichern();
+        stb->release();
         DateiRemove( "data/Minigames/Fangen/data/game.save" );
-	}
+    }
     cs.unlock();
-	return 1;
+    return 1;
 }
 
-void Map::render( Bild &zRObj )
+void Map::render( Bild & zRObj )
 {
-	if( !spieler )
-		return;
-	int xStart = 0;
-	int yStart = 0;
-	if( breite < 800 )
-		xStart = 400 - breite / 2;
-	else
-		xStart -= kamX;
-	if( höhe < 500 )
-		yStart = 250 - höhe / 2;
-	else
-		yStart -= kamY;
-	feld->setPosition( xStart, yStart );
-	feld->setSize( breite, höhe );
-	feld->render( zRObj );
-	bool rMap = breite > 800 || höhe > 500;
-	zRObj.addScrollOffset( -xStart, -yStart );
-	spieler->render( zRObj );
-	int gAnz = gegner->getEintragAnzahl();
-	for( int i = 0; i < gAnz; i++ )
-		gegner->z( i )->render( zRObj );
-	int zAnz = ziele->getEintragAnzahl();
-	for( int i = 0; i < zAnz; i++ )
-		ziele->z( i )->render( zRObj );
-	zRObj.addScrollOffset( xStart, yStart );
-	if( rMap )
-	{
-		const Punkt &dOff = zRObj.getDrawOff();
-		map->render( zRObj );
-		zRObj.setPixelDP( 10 + ( 200 * spieler->getX() ) / breite + dOff.x, 10 + ( 200 * spieler->getY() ) / höhe + dOff.y, 0xFF00FF00 );
-		for( int i = 0; i < gAnz; i++ )
-			zRObj.setPixelDP( 10 + ( 200 * gegner->z( i )->getX() ) / breite + dOff.x, 10 + ( 200 * gegner->z( i )->getY() ) / höhe + dOff.y, 0xFFFF0000 );
-		for( int i = 0; i < zAnz; i++ )
-			zRObj.setPixelDP( 10 + ( 200 * ziele->z( i )->getX() ) / breite + dOff.x, 10 + ( 200 * ziele->z( i )->getY() ) / höhe + dOff.y, 0xFF00FFFF );
-		kam->setPosition( 10 + ( 200 * kamX ) / breite, 10 + ( 200 * kamY ) / höhe );
-		kam->setSize( ( 200 * 800 ) / breite, ( 200 * 500 ) / höhe );
-		if( kam->getBreite() > 200 )
-			kam->setSize( 200, kam->getHeight() );
-		if( kam->getHeight() > 200 )
-			kam->setSize( kam->getBreite(), 200 );
-		kam->render( zRObj );
-	}
+    if( !spieler )
+        return;
+    int xStart = 0;
+    int yStart = 0;
+    if( breite < 800 )
+        xStart = 400 - breite / 2;
+    else
+        xStart -= kamX;
+    if( höhe < 500 )
+        yStart = 250 - höhe / 2;
+    else
+        yStart -= kamY;
+    feld->setPosition( xStart, yStart );
+    feld->setSize( breite, höhe );
+    feld->render( zRObj );
+    bool rMap = breite > 800 || höhe > 500;
+    zRObj.addScrollOffset( -xStart, -yStart );
+    spieler->render( zRObj );
+    int gAnz = gegner->getEintragAnzahl();
+    for( int i = 0; i < gAnz; i++ )
+        gegner->z( i )->render( zRObj );
+    int zAnz = ziele->getEintragAnzahl();
+    for( int i = 0; i < zAnz; i++ )
+        ziele->z( i )->render( zRObj );
+    zRObj.addScrollOffset( xStart, yStart );
+    if( rMap )
+    {
+        const Punkt &dOff = zRObj.getDrawOff();
+        map->render( zRObj );
+        zRObj.setPixelDP( 10 + ( 200 * spieler->getX() ) / breite + dOff.x, 10 + ( 200 * spieler->getY() ) / höhe + dOff.y, 0xFF00FF00 );
+        for( int i = 0; i < gAnz; i++ )
+            zRObj.setPixelDP( 10 + ( 200 * gegner->z( i )->getX() ) / breite + dOff.x, 10 + ( 200 * gegner->z( i )->getY() ) / höhe + dOff.y, 0xFFFF0000 );
+        for( int i = 0; i < zAnz; i++ )
+            zRObj.setPixelDP( 10 + ( 200 * ziele->z( i )->getX() ) / breite + dOff.x, 10 + ( 200 * ziele->z( i )->getY() ) / höhe + dOff.y, 0xFF00FFFF );
+        kam->setPosition( 10 + ( 200 * kamX ) / breite, 10 + ( 200 * kamY ) / höhe );
+        kam->setSize( ( 200 * 800 ) / breite, ( 200 * 500 ) / höhe );
+        if( kam->getBreite() > 200 )
+            kam->setSize( 200, kam->getHeight() );
+        if( kam->getHeight() > 200 )
+            kam->setSize( kam->getBreite(), 200 );
+        kam->render( zRObj );
+    }
 }
 
 void Map::speichern()
@@ -378,18 +379,18 @@ void Map::speichern()
         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 *)& seed, 8 );
+        d->schreibe( (char *)& gameTime, 8 );
+        d->schreibe( (char *)& breite, 4 );
+        d->schreibe( (char *)& höhe, 4 );
+        d->schreibe( (char *)& score, 4 );
         spieler->save( d );
         int anz = gegner->getEintragAnzahl();
-        d->schreibe( (char*)&anz, 4 );
+        d->schreibe( (char *)& anz, 4 );
         for( int i = 0; i < anz; i++ )
             gegner->z( i )->save( d );
         anz = ziele->getEintragAnzahl();
-        d->schreibe( (char*)&anz, 4 );
+        d->schreibe( (char *)& anz, 4 );
         for( int i = 0; i < anz; i++ )
             ziele->z( i )->save( d );
         d->close();
@@ -399,28 +400,152 @@ void Map::speichern()
         DateiRemove( "data/Minigames/Fangen/data/game.save" );
 }
 
+Map::Save *Map::saveState()
+{
+    Save *s = new Save();
+    s->beendet = beendet;
+    s->gameTime = gameTime;
+    s->score = score;
+    s->scoreCheck = scoreCheck;
+    s->gegner = new RCArray<Spieler>();
+    for( auto g = gegner->getIterator(); g; g++ )
+        s->gegner->add( g->copy() );
+    s->ziele = new RCArray<Spieler>();
+    for( auto z = ziele->getIterator(); z; z++ )
+        s->ziele->add( z->copy() );
+    s->spieler = spieler->copy();
+    return s;
+}
+
+void Map::reloadState( Map::Save *s )
+{
+    beendet = s->beendet;
+    gameTime = s->gameTime;
+    score = s->score;
+    scoreCheck = s->scoreCheck;
+    gegner->leeren();
+    for( auto g = s->gegner->getIterator(); g; g++ )
+        gegner->add( g->getThis() );
+    ziele->leeren();
+    for( auto z = s->ziele->getIterator(); z; z++ )
+        ziele->add( z->getThis() );
+    spieler->release();
+    spieler = s->spieler->getThis();
+    s->ziele->release();
+    s->gegner->release();
+    s->spieler->release();
+    delete s;
+}
+
+bool Map::canGoLeft() const
+{
+    return spieler->getX() > 10;
+}
+
+bool Map::canGoUp() const
+{
+    return spieler->getY() > 10;
+}
+
+bool Map::canGoRight() const
+{
+    return spieler->getX() < breite - 10;
+}
+
+bool Map::canGoDown() const
+{
+    return spieler->getY() < höhe - 10;
+}
+
+
+int Map::getBestOption( bool *left, bool *up, bool *right, bool *down, int maxSteps )
+{
+    if( !maxSteps && !beendet )
+        return score;
+    else if( beendet )
+        return -1;
+    int best = 0;
+    int maxScore = -2;
+    int order[] = { 0, 1, 2, 4, 8, 3, 9, 6, 12 };
+    int orderCount = 9;
+    for( int x = 0; x < orderCount; x++ )
+    {
+        int i = order[ x ];
+        Save *save = saveState();
+        TastaturEreignis te;
+        te.taste = T_Links;
+        te.verarbeitet = 0;
+        te.id = ( i | 0x1 ) == i ? TE_Press : TE_Release;
+        doTastaturEreignis( te );
+        te.taste = T_Oben;
+        te.verarbeitet = 0;
+        te.id = ( i | 0x2 ) == i ? TE_Press : TE_Release;
+        doTastaturEreignis( te );
+        te.taste = T_Rechts;
+        te.verarbeitet = 0;
+        te.id = ( i | 0x4 ) == i ? TE_Press : TE_Release;
+        doTastaturEreignis( te );
+        te.taste = T_Unten;
+        te.verarbeitet = 0;
+        te.id = ( i | 0x8 ) == i ? TE_Press : TE_Release;
+        doTastaturEreignis( te );
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        Save *save2 = saveState();
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        tick( 0.05 );
+        if( beendet && !save2->beendet )
+        {
+            reloadState( save2 );
+            save2 = 0;
+        }
+        int score = getBestOption( left, up, right, down, maxSteps - 1 );
+        if( this->score > save->score )
+            score += maxSteps;
+        if( score > maxScore )
+        {
+            maxScore = score;
+            best = i;
+        }
+        if( save2 )
+            reloadState( save2 );
+        reloadState( save );
+    }
+    *left = ( best | 0x1 ) == best;
+    *up = ( best | 0x2 ) == best;
+    *right = ( best | 0x4 ) == best;
+    *down = ( best | 0x8 ) == best;
+    return maxScore;
+}
+
 // constant
 int Map::getScore() const
 {
-	return score;
+    return score;
 }
 
 bool Map::istBeendet() const
 {
-	return beendet;
+    return beendet;
 }
 
 // Reference Counting
 Map *Map::getThis()
 {
-	ref++;
-	return this;
+    ref++;
+    return this;
 }
 
 Map *Map::release()
 {
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    ref--;
+    if( !ref )
+        delete this;
+    return 0;
 }

+ 18 - 0
Fangen/Map.h

@@ -10,6 +10,17 @@ using namespace Framework;
 
 class Map
 {
+public:
+    struct Save
+    {
+        int score;
+        int scoreCheck;
+        bool beendet;
+        double gameTime;
+        RCArray< Spieler > *gegner;
+        RCArray< Spieler > *ziele;
+        Spieler *spieler;
+    };
 private:
 	RCArray< Spieler > *gegner;
 	RCArray< Spieler > *ziele;
@@ -47,9 +58,16 @@ public:
 	bool tick( double tickVal );
 	void render( Bild &zRObj );
     void speichern();
+    Save *saveState();
+    void reloadState( Save *s );
 	// constant
 	int getScore() const;
 	bool istBeendet() const;
+    bool canGoLeft() const;
+    bool canGoUp() const;
+    bool canGoRight() const;
+    bool canGoDown() const;
+    int getBestOption( bool *left, bool *up, bool *right, bool *down, int maxSteps );
 	// Reference Counting
 	Map *getThis();
 	Map *release();

+ 29 - 4
Fangen/Spieler.cpp

@@ -49,12 +49,15 @@ Spieler::Spieler( SpielerTyp typ, Datei *zD )
     ref = 1;
 }
 
-// Destruktor
-Spieler::~Spieler()
+Spieler::Spieler()
 {
-
+    ref = 1;
 }
 
+// Destruktor
+Spieler::~Spieler()
+{}
+
 // nicht constant
 void Spieler::tick( double z, int mapBr, int mapHö, char tastenStände )
 {
@@ -87,7 +90,7 @@ void Spieler::tick( double z, int mapBr, int mapH
         xPos = mapBr - 10;
         xSpeed = -xSpeed;
     }
-    else if( yPos < 10 )
+    if( yPos < 10 )
     {
         yPos = 10;
         ySpeed = -ySpeed;
@@ -127,6 +130,16 @@ int Spieler::getY() const
     return (int)yPos;
 }
 
+float Spieler::getXSpeed() const
+{
+    return xSpeed;
+}
+
+float Spieler::getYSpeed() const
+{
+    return ySpeed;
+}
+
 void Spieler::save( Datei *zD ) const
 {
     zD->schreibe( (char*)&xPos, 8 );
@@ -136,6 +149,18 @@ void Spieler::save( Datei *zD ) const
     zD->schreibe( (char*)&durchlässig, 8 );
 }
 
+Spieler *Spieler::copy() const
+{
+    Spieler *ret = new Spieler();
+    ret->xPos = xPos;
+    ret->yPos = yPos;
+    ret->xSpeed = xSpeed;
+    ret->ySpeed = ySpeed;
+    ret->durchlässig = durchlässig;
+    ret->farbe = farbe;
+    return ret;
+}
+
 // Reference Counting
 Spieler *Spieler::getThis()
 {

+ 4 - 0
Fangen/Spieler.h

@@ -29,6 +29,7 @@ public:
 	// Konstruktor
 	Spieler( SpielerTyp typ, int mapBr, int mapHö, RandomGenerator *zRand );
 	Spieler( SpielerTyp typ, Datei *zD );
+    Spieler();
 	// Destruktor
 	~Spieler();
 	// nicht constant
@@ -38,7 +39,10 @@ public:
 	bool berührt( double px, double py ) const;
 	int getX() const;
 	int getY() const;
+    float getXSpeed() const;
+    float getYSpeed() const;
 	void save( Datei *zD ) const;
+    Spieler *copy() const;
 	// Reference Counting
 	Spieler *getThis();
 	Spieler *release();