Эх сурвалжийг харах

use framework reference counting and ui initialisation

Kolja Strohm 3 жил өмнө
parent
commit
5bd8f9b3b1
8 өөрчлөгдсөн 1115 нэмэгдсэн , 1380 устгасан
  1. 36 62
      Snake/Game.cpp
  2. 2 8
      Snake/Game.h
  3. 64 162
      Snake/Initialisierung.cpp
  4. 11 10
      Snake/Initialisierung.h
  5. 225 240
      Snake/Map.cpp
  6. 35 39
      Snake/Map.h
  7. 634 727
      Snake/Menü.cpp
  8. 108 132
      Snake/Menü.h

+ 36 - 62
Snake/Game.cpp

@@ -4,13 +4,11 @@
 // Inhalt der Game Klasse aus Game.h
 // Konstruktor
 Game::Game()
+    : ReferenceCounter()
 {
-	schrift = 0;
-	screen = 0;
-	alpha = 0;
-	menü = 0;
+    alpha = 0;
+    menü = 0;
     client = 0;
-	ref = 1;
 }
 
 // Destruktor
@@ -18,16 +16,14 @@ Game::~Game()
 {
     if( client )
         client->release();
-	if( schrift )
-		schrift->release();
-	if( menü )
-		menü->release();
+    if( menü )
+        menü->release();
 }
 
 // nicht constant
 bool Game::laden()
 {
-	return 1;
+    return 1;
 }
 
 void Game::setMinigameClientZ( KSGClient::MinigameServerClient *client )
@@ -44,76 +40,54 @@ void Game::setMinigameAPI( MinigameAPI *api )
 
 void Game::doPublicMausEreignis( MausEreignis &me )
 {
-	if( menü )
-		menü->doPublicMausEreignis( me );
+    if( menü )
+        menü->doPublicMausEreignis( me );
 }
 
 void Game::doTastaturEreignis( TastaturEreignis &te )
 {
-	if( menü )
-		menü->doTastaturEreignis( te );
+    if( menü )
+        menü->doTastaturEreignis( te );
 }
 
 bool Game::tick( double zeit )
 {
-	int val = (int)( zeit * 150 );
-	if( menü && !menü->istBeendet() && alpha != 255 )
-	{
-		alpha += val;
-		if( alpha > 255 )
-			alpha = 255;
-		return 1;
-	}
-	if( menü && menü->istBeendet() && alpha )
-	{
-		alpha -= val;
-		if( alpha < 255 )
-			alpha = 0;
-	}
-	if( menü )
-		return menü->tick( zeit );
-	return 0;
+    int val = (int)( zeit * 150 );
+    if( menü && !menü->istBeendet() && alpha != 255 )
+    {
+        alpha += val;
+        if( alpha > 255 )
+            alpha = 255;
+        return 1;
+    }
+    if( menü && menü->istBeendet() && alpha )
+    {
+        alpha -= val;
+        if( alpha < 255 )
+            alpha = 0;
+    }
+    if( menü )
+        return menü->tick( zeit );
+    return 0;
 }
 
 void Game::render( Bild &zRObj )
 {
-	zRObj.setAlpha( alpha );
-	if( menü )
-		menü->render( zRObj );
-	zRObj.releaseAlpha();
+    zRObj.setAlpha( alpha );
+    if( menü )
+        menü->render( zRObj );
+    zRObj.releaseAlpha();
 }
 
-void Game::setSchriftZ( Schrift *schrift )
+void Game::setUIFactory( UIInit &uiFactory )
 {
-	this->schrift = schrift;
-	if( !menü && this->schrift && screen )
-		menü = new Menü( schrift, screen, client->getThis() );
-}
-
-void Game::setBildschirmZ( Bildschirm *zScreen )
-{
-	screen = zScreen;
-	if( !menü && schrift && screen )
-		menü = new Menü( schrift, screen, client->getThis() );
+    this->uiFactory = uiFactory;
+    if( !menü )
+        menü = new Menü( uiFactory, dynamic_cast<KSGClient::MinigameServerClient *>( client->getThis() ) );
 }
 
 // constant
 bool Game::istEnde() const
 {
-	return menü ? ( menü->istBeendet() && !alpha ) : 0;
-}
-
-// Reference Counting
-MiniGameV *Game::getThis()
-{
-	ref++;
-	return this;
-}
-
-MiniGameV *Game::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return menü ? ( menü->istBeendet() && !alpha ) : 0;
 }

+ 2 - 8
Snake/Game.h

@@ -7,12 +7,10 @@
 class Game : public MiniGameV
 {
 private:
-    Schrift *schrift;
-    Bildschirm *screen;
+    UIInit uiFactory;
     Menü *menü;
     KSGClient::MinigameServerClient *client;
     int alpha;
-    int ref;
 
 public:
     // Konstruktor
@@ -27,13 +25,9 @@ public:
     virtual void doTastaturEreignis( TastaturEreignis &te ) override;
     virtual bool tick( double zeit ) override;
     virtual void render( Bild &zRObj ) override;
-    virtual void setSchriftZ( Schrift *schrift ) override;
-    virtual void setBildschirmZ( Bildschirm *zScreen ) override;
+    virtual void setUIFactory( UIInit &uiFactory ) override;
     // constant
     virtual bool istEnde() const override;
-    // Reference Counting
-    virtual MiniGameV *getThis() override;
-    virtual MiniGameV *release() override;
 };
 
 #endif

+ 64 - 162
Snake/Initialisierung.cpp

@@ -3,182 +3,84 @@
 #include <Textfeld.h>
 #include <MausEreignis.h>
 
-Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel )
+Knopf *initKnopf( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *titel )
 {
-	Knopf *ret = new Knopf();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	ret->setText( titel );
-	return ret;
+    Knopf *ret = uiFactory.createKnopf( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    ret->setText( titel );
+    return ret;
 }
 
-KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt )
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *txt )
 {
-	KontrollKnopf *ret = new KontrollKnopf();
-	ret->setMausEreignis( _ret1ME );
-	ret->addStyle( style );
-	ret->setSchriftZ( zSchrift->getThis() );
-	ret->setText( txt );
-	ret->setSText( txt );
-	ret->setSFarbe( 0xFFFFFFFF );
-	ret->setSSize( 12 );
-	if( ret->hatStyle( TextFeld::Style::Buffered ) )
-	{
-		ret->setAlphaFeldFarbe( 0x5500FF00 );
-		ret->setAlphaFeldStrength( -5 );
-	}
-	if( ret->hatStyle( TextFeld::Style::Rahmen ) )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFF00FF00 );
-	}
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	ret->loadData( "data/bilder/system.ltdb" );
-	return ret;
+    KontrollKnopf *ret = uiFactory.createKontrollKnopf( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setText( txt );
+    ret->setSText( txt );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
 }
 
-TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt )
+TextFeld *initTextFeld( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *txt )
 {
-	TextFeld *ret = new TextFeld();
-	ret->setStyle( style );
-	ret->setSchriftZ( zSchrift->getThis() );
-	ret->setText( txt );
-	ret->setSchriftFarbe( 0xFFFFFFFF );
-	ret->setSchriftSize( 12 );
-	if( ret->hatStyle( TextFeld::Style::Buffered ) )
-	{
-		ret->setAlphaFeldFarbe( 0x5500FF00 );
-		ret->setAlphaFeldStrength( -5 );
-	}
-	if( ret->hatStyle( TextFeld::Style::Rahmen ) )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFF00FF00 );
-	}
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	return ret;
+    TextFeld *ret = uiFactory.createTextFeld( uiFactory.initParam );
+    ret->setStyle( style );
+    ret->setText( txt );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    return ret;
 }
 
-AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values )
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< char * > values )
 {
-	AuswahlBox *ret = new AuswahlBox();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( ( style | AuswahlBox::Style::Hintergrund ) == style )
-		ret->setHintergrundFarbe( 0xFF000000 );
-	if( ( style | AuswahlBox::Style::Erlaubt ) == style )
-		ret->setMausEreignis( _ret1ME );
-	if( zSchrift )
-		ret->setSchriftZ( zSchrift->getThis() );
-	if( ( style | AuswahlBox::Style::Rahmen ) == style )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | AuswahlBox::Style::MaxHeight ) == style )
-		ret->setMaxAuskappHeight( 100 );
-	if( ( style | AuswahlBox::Style::MausRahmen ) == style )
-	{
-		ret->setMausRahmenBreite( 1 );
-		ret->setMausRahmenFarbe( 0xFF005500 );
-	}
-	if( ( style | AuswahlBox::Style::MausBuffer ) == style )
-	{
-		ret->setMausAlphaFeldFarbe( 0x00008700 );
-		ret->setMausAlphaFeldStrength( -8 );
-	}
-	if( ( style | AuswahlBox::Style::AuswahlRahmen ) == style )
-	{
-		ret->setAuswRahmenBreite( 1 );
-		ret->setAuswRahmenFarbe( 0xFF00FF00 );
-	}
-	if( ( style | AuswahlBox::Style::AuswahlBuffer ) == style )
-	{
-		ret->setAuswAlphaFeldFarbe( 0x0000FF00 );
-		ret->setAuswAlphaFeldStrength( -8 );
-	}
-	for( auto i = values.begin(); i != values.end(); i++ )
-	{
-		ret->addEintrag( *i );
-	}
-	return ret;
+    AuswahlBox *ret = uiFactory.createAuswahlBox( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    for( auto i = values.begin(); i != values.end(); i++ )
+    {
+        ret->addEintrag( *i );
+    }
+    return ret;
 }
 
-ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe )
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe )
 {
-	ObjTabelle *ret = new ObjTabelle();
-	ret->addStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( ( style | ObjTabelle::Style::Erlaubt ) == style )
-		ret->setMausEreignis( _ret1ME );
-	if( ( style | ObjTabelle::Style::Rahmen ) == style )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | ObjTabelle::Style::Raster ) == style )
-	{
-		ret->setRasterBreite( 1 );
-		ret->setRasterFarbe( 0xFFFFFFFF );
-	}
-	if( ( style | ObjTabelle::Style::VScroll ) == style )
-		ret->setVertikalKlickScroll( 5 );
-	if( ( style | ObjTabelle::Style::HScroll ) == style )
-		ret->setHorizontalKlickScroll( 5 );
-	for( auto i = spalten.begin(); i != spalten.end(); i++ )
-	{
-		ret->addSpalte( i->name );
-		ret->setSpaltenBreite( i->name, i->breite );
-		if( ( style | ObjTabelle::Style::SpaltenBreiteMin ) == style )
-			ret->setMinSpaltenBreite( i->name, i->minBreite );
-		if( ( style | ObjTabelle::Style::SpaltenBreiteMax ) == style )
-			ret->setMaxSpaltenBreite( i->name, i->maxBreite );
-		if( überschriftHöhe )
-		{
-			if( ret->getZeilenNummer( "Überschrift" ) < 0 )
-			{
-				ret->addZeile( 0, "Überschrift" );
-				ret->setZeilenHeight( 0, 20 );
-			}
-			ret->setZeichnungZ( i->name, "Überschrift", initTextFeld( 0, 0, i->breite, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, i->name ) );
-		}
-	}
-	return ret;
+    ObjTabelle *ret = uiFactory.createObjTabelle( uiFactory.initParam );
+    ret->addStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    for( auto i = spalten.begin(); i != spalten.end(); i++ )
+    {
+        ret->addSpalte( i->name );
+        ret->setSpaltenBreite( i->name, i->breite );
+        if( ( style | ObjTabelle::Style::SpaltenBreiteMin ) == style )
+            ret->setMinSpaltenBreite( i->name, i->minBreite );
+        if( ( style | ObjTabelle::Style::SpaltenBreiteMax ) == style )
+            ret->setMaxSpaltenBreite( i->name, i->maxBreite );
+        if( überschriftHöhe )
+        {
+            if( ret->getZeilenNummer( "Überschrift" ) < 0 )
+            {
+                ret->addZeile( 0, "Überschrift" );
+                ret->setZeilenHeight( 0, 20 );
+            }
+            ret->setZeichnungZ( i->name, "Überschrift", initTextFeld( 0, 0, i->breite, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, i->name ) );
+        }
+    }
+    return ret;
 }
 
-LDiag *initLinienDiagramm( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, DiagDaten *data )
+LDiag *initLinienDiagramm( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, DiagDaten *data )
 {
-	LDiag *ret = new LDiag();
-	ret->setStyle( style );
-	ret->setPosition( x, y );
-	ret->setSize( br, hö );
-	if( zSchrift )
-	{
-		ret->setSchriftZ( zSchrift->getThis() );
-		ret->setSchriftSize( 12 );
-	}
-	if( data )
-		ret->setDiagDatenZ( data );
-	if( ret->hatStyle( LDiag::Style::Rahmen ) )
-	{
-		ret->setRahmenBreite( 1 );
-		ret->setRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ret->hatStyle( LDiag::Style::DatenRahmen ) )
-	{
-		ret->setDatenRahmenBreite( 1 );
-		ret->setDatenRahmenFarbe( 0xFFFFFFFF );
-	}
-	if( ret->hatStyle( LDiag::Style::Hintergrund ) )
-		ret->setHintergrundFarbe( 0xFF000000 );
-	if( ret->hatStyle( LDiag::Style::DatenHintergrund ) )
-		ret->setHintergrundFarbe( 0xFF000000 );
-	return ret;
+    LDiag *ret = uiFactory.createLDiag( uiFactory.initParam );
+    ret->setStyle( style );
+    ret->setPosition( x, y );
+    ret->setSize( br, hö );
+    if( data )
+        ret->setDiagDatenZ( data );
+    return ret;
 }

+ 11 - 10
Snake/Initialisierung.h

@@ -7,22 +7,23 @@
 #include <Tabelle.h>
 #include <Diagramm.h>
 #include <initializer_list>
+#include <UIInitialization.h>
 
 using namespace Framework;
 
 struct OBJTabelleSpalteIni
 {
-	char *name;
-	int breite;
-	int minBreite;
-	int maxBreite;
+    char *name;
+    int breite;
+    int minBreite;
+    int maxBreite;
 };
 
-Knopf *initKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *titel );
-KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt );
-TextFeld *initTextFeld( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, char *txt );
-AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< char * > values );
-ObjTabelle *initObjTabelle( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe );
-LDiag *initLinienDiagramm( int x, int y, int br, int hö, Schrift *zSchrift, __int64 style, DiagDaten *data );
+Knopf *initKnopf( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *titel );
+KontrollKnopf *initKontrollKnopf( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *txt );
+TextFeld *initTextFeld( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, char *txt );
+AuswahlBox *initAuswahlBox( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< char * > values );
+ObjTabelle *initObjTabelle( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, std::initializer_list< OBJTabelleSpalteIni > spalten, int überschriftHöhe );
+LDiag *initLinienDiagramm( int x, int y, int br, int hö, UIInit &uiFactory, __int64 style, DiagDaten *data );
 
 #endif

+ 225 - 240
Snake/Map.cpp

@@ -11,36 +11,36 @@
 // Inhalt der Map Klasse aus Map.h
 // Konstruktor
 Map::Map( KSGClient::MinigameServerClient *klient )
+    : ReferenceCounter()
 {
     this->klient = klient;
-	schlange = new Array< Pos >();
-	ziele = new Array< Pos >();
-	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;
+    schlange = new Array< Pos >();
+    ziele = new Array< Pos >();
+    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;
     rGen = 0;
-	move = 1;
-	sr = 1;
-	rend = 0;
-	ref = 1;
+    move = 1;
+    sr = 1;
+    rend = 0;
 }
 
 // Destruktor
 Map::~Map()
 {
-	speichern();
-	schlange->release();
-	ziele->release();
-	feld->release();
-	kam->release();
-	map->release();
+    speichern();
+    schlange->release();
+    ziele->release();
+    feld->release();
+    kam->release();
+    map->release();
     if( rGen )
         rGen->release();
     if( klient )
@@ -52,15 +52,15 @@ void Map::reset( Text *zOptionen )
 {
     gameTime = 0;
     if( rGen )
-        rGen = rGen->release();
-	next = 0;
-	beendet = 0;
-	richtung = 0;
-	addAnzahl = 0;
-	score = 0;
+        rGen = (RandomGenerator *)rGen->release();
+    next = 0;
+    beendet = 0;
+    richtung = 0;
+    addAnzahl = 0;
+    score = 0;
     scoreCheck = score * 11197;
-	schlange->leeren();
-	ziele->leeren();
+    schlange->leeren();
+    ziele->leeren();
     Text *tmp = zOptionen->getTeilText( zOptionen->positionVon( '=' ) + 1, zOptionen->positionVon( ',' ) );
     breite = *tmp;
     tmp->release();
@@ -79,57 +79,57 @@ void Map::reset( Text *zOptionen )
     tmp = zOptionen->getTeilText( zOptionen->positionVon( '=', 5 ) + 1, zOptionen->positionVon( ',', 5 ) );
     bool fortsetzen = (int)*tmp != 0;
     tmp->release();
-	kamPos.x = 0;
-	kamPos.y = 0;
-	if( breite > 80 )
-		kamPos.x = breite / 2 - 40;
-	if( höhe > 50 )
-		kamPos.y = höhe / 2 - 25;
-	if( fortsetzen && DateiExistiert( "data/Minigames/Snake/data/game.save" ) && klient )
-	{
+    kamPos.x = 0;
+    kamPos.y = 0;
+    if( breite > 80 )
+        kamPos.x = breite / 2 - 40;
+    if( höhe > 50 )
+        kamPos.y = höhe / 2 - 25;
+    if( fortsetzen && DateiExistiert( "data/Minigames/Snake/data/game.save" ) && klient )
+    {
         if( capture.istOffen() )
             capture.close();
         capture.setDatei( "data/Minigames/Snake/data/game.mgc" );
         capture.open( Datei::Style::schreiben | Datei::Style::ende | Datei::Style::lesen );
-		Datei *save = new Datei();
-		save->setDatei( "data/Minigames/Snake/data/game.save" );
-		save->open( Datei::Style::lesen );
-		int br = 0;
-		int hö = 0;
+        Datei *save = new Datei();
+        save->setDatei( "data/Minigames/Snake/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;
-			save->lese( (char*)&richtung, 4 );
-			int anz = 0;
-			save->lese( (char*)&anz, 4 );
-			for( int i = 0; i < anz; i++ )
-			{
-				Pos p;
-				save->lese( (char*)&p.x, 2 );
-				save->lese( (char*)&p.y, 2 );
-				schlange->add( p );
-			}
-			save->lese( (char*)&anz, 4 );
-			for( int i = 0; i < anz; i++ )
-			{
-				Pos p;
-				save->lese( (char*)&p.x, 2 );
-				save->lese( (char*)&p.y, 2 );
-				ziele->add( p );
-			}
-			next = 1.0 / geschwindigkeit;
-		}
-		save->close();
-		save->release();
-	}
+            save->lese( (char *)&richtung, 4 );
+            int anz = 0;
+            save->lese( (char *)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                Pos p;
+                save->lese( (char *)&p.x, 2 );
+                save->lese( (char *)&p.y, 2 );
+                schlange->add( p );
+            }
+            save->lese( (char *)&anz, 4 );
+            for( int i = 0; i < anz; i++ )
+            {
+                Pos p;
+                save->lese( (char *)&p.x, 2 );
+                save->lese( (char *)&p.y, 2 );
+                ziele->add( p );
+            }
+            next = 1.0 / geschwindigkeit;
+        }
+        save->close();
+        save->release();
+    }
     else
     {
         rGen = new RandomGenerator();
@@ -142,7 +142,7 @@ 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
         {
@@ -151,8 +151,8 @@ void Map::reset( Text *zOptionen )
             tmp->release();
         }
     }
-	if( !schlange->getEintragAnzahl() )
-		schlange->add( Pos{ (short)( breite / 2 ), (short)( höhe / 2 ) } );
+    if( !schlange->getEintragAnzahl() )
+        schlange->add( Pos{ (short)( breite / 2 ), (short)( höhe / 2 ) } );
 }
 
 void Map::doPublicMausEreignis( MausEreignis &me )
@@ -162,8 +162,8 @@ void Map::doPublicMausEreignis( MausEreignis &me )
 
 void Map::doTastaturEreignis( TastaturEreignis &te )
 {
-	if( !move )
-		return;
+    if( !move )
+        return;
     cs.lock();
     if( !beendet )
     {
@@ -206,8 +206,8 @@ void Map::doTastaturEreignis( TastaturEreignis &te )
         }
         if( klient && save )
         {
-            capture.schreibe( (char*)&gameTime, 8 );
-            capture.schreibe( (char*)&te.taste, 1 );
+            capture.schreibe( (char *)&gameTime, 8 );
+            capture.schreibe( (char *)&te.taste, 1 );
         }
     }
     cs.unlock();
@@ -215,87 +215,87 @@ void Map::doTastaturEreignis( TastaturEreignis &te )
 
 bool Map::tick( double tickVal )
 {
-	if( beendet )
-		return 0;
-	bool ret = rend;
+    if( beendet )
+        return 0;
+    bool ret = rend;
     cs.lock();
     gameTime += tickVal;
-	rend = 0;
-	next -= tickVal;
-	while( next < 0 && !beendet )
-	{
-		move = 1;
-		ret = 1;
-		next += 1.0 / geschwindigkeit;
-		int nx = schlange->get( 0 ).x;
-		int ny = schlange->get( 0 ).y;
-		if( richtung == 0 )
-			ny--;
-		if( richtung == 1 )
-			nx++;
-		if( richtung == 2 )
-			ny++;
-		if( richtung == 3 )
-			nx--;
-		if( breite > 80 )
-		{
-			kamPos.x = nx - 40;
-			if( kamPos.x < 0 )
-				kamPos.x = 0;
-			if( kamPos.x + 80 > breite )
-				kamPos.x = breite - 80;
-		}
-		if( höhe > 50 )
-		{
-			kamPos.y = ny - 25;
-			if( kamPos.y < 0 )
-				kamPos.y = 0;
-			if( kamPos.y + 50 > höhe )
-				kamPos.y = höhe - 50;
-		}
-		int sAnz = schlange->getEintragAnzahl();
-		for( int i = 0; i < sAnz; i++ )
-			beendet |= nx == schlange->get( i ).x && ny == schlange->get( i ).y;
-		beendet |= nx < 0 || nx >= breite;
-		beendet |= ny < 0 || ny >= höhe;
-		int zAnz = ziele->getEintragAnzahl();
-		bool neuZ = !zAnz;
-		for( int i = 0; i < zAnz; i++ )
-			neuZ |= nx == ziele->get( i ).x && ny == ziele->get( i ).y;
-		if( neuZ )
-		{
-			addAnzahl += neuAnzahl;
-			ziele->leeren();
-			for( int i = 0; i < zAnzahl; i++ )
-				ziele->add( Pos{ (short)( rGen->rand() * breite ), (short)( rGen->rand() * höhe ) } );
+    rend = 0;
+    next -= tickVal;
+    while( next < 0 && !beendet )
+    {
+        move = 1;
+        ret = 1;
+        next += 1.0 / geschwindigkeit;
+        int nx = schlange->get( 0 ).x;
+        int ny = schlange->get( 0 ).y;
+        if( richtung == 0 )
+            ny--;
+        if( richtung == 1 )
+            nx++;
+        if( richtung == 2 )
+            ny++;
+        if( richtung == 3 )
+            nx--;
+        if( breite > 80 )
+        {
+            kamPos.x = nx - 40;
+            if( kamPos.x < 0 )
+                kamPos.x = 0;
+            if( kamPos.x + 80 > breite )
+                kamPos.x = breite - 80;
+        }
+        if( höhe > 50 )
+        {
+            kamPos.y = ny - 25;
+            if( kamPos.y < 0 )
+                kamPos.y = 0;
+            if( kamPos.y + 50 > höhe )
+                kamPos.y = höhe - 50;
+        }
+        int sAnz = schlange->getEintragAnzahl();
+        for( int i = 0; i < sAnz; i++ )
+            beendet |= nx == schlange->get( i ).x && ny == schlange->get( i ).y;
+        beendet |= nx < 0 || nx >= breite;
+        beendet |= ny < 0 || ny >= höhe;
+        int zAnz = ziele->getEintragAnzahl();
+        bool neuZ = !zAnz;
+        for( int i = 0; i < zAnz; i++ )
+            neuZ |= nx == ziele->get( i ).x && ny == ziele->get( i ).y;
+        if( neuZ )
+        {
+            addAnzahl += neuAnzahl;
+            ziele->leeren();
+            for( int i = 0; i < zAnzahl; i++ )
+                ziele->add( Pos{ (short)( rGen->rand() * breite ), (short)( rGen->rand() * höhe ) } );
             if( zAnz )
             {
                 score++;
                 scoreCheck = score * 11197;
             }
-		}
+        }
         if( score * 11197 != scoreCheck )
         {
             beendet = 1;
             score = 0;
             scoreCheck = 0;
         }
-		if( !beendet )
-		{
-			schlange->add( Pos{ (short)nx, (short)ny }, 0 );
-			if( !addAnzahl )
-				schlange->remove( sAnz );
-			else
-				addAnzahl--;
-		}
-		else if( klient )
-		{
+        if( !beendet )
+        {
+            schlange->add( Pos{ (short)nx, (short)ny }, 0 );
+            if( !addAnzahl )
+                schlange->remove( sAnz );
+            else
+                addAnzahl--;
+        }
+        else if( klient )
+        {
             capture.close();
             DateiRemove( "data/Minigames/Snake/data/upload.mgc" );
             DateiUmbenennen( "data/Minigames/Snake/data/game.mgc", "data/Minigames/Snake/data/upload.mgc" );
             int tmpScore = score;
-            KSGClient::MinigameServerClient *tmpKlient = klient->getThis();
-            new AsynchronCall( [ tmpScore, tmpKlient ]()
+            KSGClient::MinigameServerClient *tmpKlient = dynamic_cast<KSGClient::MinigameServerClient *>( klient->getThis() );
+            new AsynchronCall( [tmpScore, tmpKlient]()
             {
                 InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
                 opd->laden();
@@ -316,80 +316,80 @@ bool Map::tick( double tickVal )
                 DateiRemove( "data/Minigames/Snake/data/upload.mgc" );
                 tmpKlient->release();
             } );
-			KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
-			if( !stb->laden() )
-				DateiPfadErstellen( "data/Minigames/Snake/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( neuAnzahl );
-			zeile->add( nAnzahlT );
-			stb->addZeile( 7, zeile );
-			zeile->release();
-			stb->speichern();
-			stb->release();
+            KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
+            if( !stb->laden() )
+                DateiPfadErstellen( "data/Minigames/Snake/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( neuAnzahl );
+            zeile->add( nAnzahlT );
+            stb->addZeile( 7, zeile );
+            zeile->release();
+            stb->speichern();
+            stb->release();
             DateiRemove( "data/Minigames/Snake/data/game.save" );
-		}
-	}
+        }
+    }
     cs.unlock();
-	return ret;
+    return ret;
 }
 
 void Map::render( Bild &zRObj )
 {
-	int xStart = 0;
-	int yStart = 0;
-	if( breite < 80 )
-		xStart = 400 - breite * 5;
-	else
-		xStart -= kamPos.x * 10;
-	if( höhe < 50 )
-		yStart = 250 - höhe * 5;
-	else
-		yStart -= kamPos.y * 10;
-	feld->setPosition( xStart, yStart );
-	feld->setSize( breite * 10, höhe * 10 );
-	feld->render( zRObj );
-	bool rMap = breite > 80 || höhe > 50;
-	int sLän = schlange->getEintragAnzahl();
-	for( int i = 0; i < sLän; i++ )
-		zRObj.fillRegion( xStart + schlange->get( i ).x * 10, yStart + schlange->get( i ).y * 10, 9, 9, 0xFFFFFFFF );
-	int zAnz = ziele->getEintragAnzahl();
-	for( int i = 0; i < zAnz; i++ )
-		zRObj.fillRegion( xStart + ziele->get( i ).x * 10, yStart + ziele->get( i ).y * 10, 9, 9, 0xFF00FF00 );
-	if( rMap )
-	{
-		const Punkt &dOff = zRObj.getDrawOff();
-		map->render( zRObj );
-		for( int i = 0; i < sLän; i++ )
-			zRObj.setPixelDP( 10 + ( 200 * schlange->get( i ).x ) / breite + dOff.x, 10 + ( 200 * schlange->get( i ).y ) / höhe + dOff.y, 0xFFFFFFFF );
-		for( int i = 0; i < zAnz; i++ )
-			zRObj.setPixelDP( 10 + ( 200 * ziele->get( i ).x ) / breite + dOff.x, 10 + ( 200 * ziele->get( i ).y ) / höhe + dOff.y, 0xFF00FF00 );
-		kam->setPosition( 10 + ( 200 * kamPos.x ) / breite, 10 + ( 200 * kamPos.y ) / höhe );
-		kam->setSize( 16000 / breite, ( 10000 ) / höhe );
-		if( kam->getBreite() > 200 )
-			kam->setSize( 200, kam->getHeight() );
-		if( kam->getHeight() > 200 )
-			kam->setSize( kam->getBreite(), 200 );
-		kam->render( zRObj );
-	}
+    int xStart = 0;
+    int yStart = 0;
+    if( breite < 80 )
+        xStart = 400 - breite * 5;
+    else
+        xStart -= kamPos.x * 10;
+    if( höhe < 50 )
+        yStart = 250 - höhe * 5;
+    else
+        yStart -= kamPos.y * 10;
+    feld->setPosition( xStart, yStart );
+    feld->setSize( breite * 10, höhe * 10 );
+    feld->render( zRObj );
+    bool rMap = breite > 80 || höhe > 50;
+    int sLän = schlange->getEintragAnzahl();
+    for( int i = 0; i < sLän; i++ )
+        zRObj.fillRegion( xStart + schlange->get( i ).x * 10, yStart + schlange->get( i ).y * 10, 9, 9, 0xFFFFFFFF );
+    int zAnz = ziele->getEintragAnzahl();
+    for( int i = 0; i < zAnz; i++ )
+        zRObj.fillRegion( xStart + ziele->get( i ).x * 10, yStart + ziele->get( i ).y * 10, 9, 9, 0xFF00FF00 );
+    if( rMap )
+    {
+        const Punkt &dOff = zRObj.getDrawOff();
+        map->render( zRObj );
+        for( int i = 0; i < sLän; i++ )
+            zRObj.setPixelDP( 10 + ( 200 * schlange->get( i ).x ) / breite + dOff.x, 10 + ( 200 * schlange->get( i ).y ) / höhe + dOff.y, 0xFFFFFFFF );
+        for( int i = 0; i < zAnz; i++ )
+            zRObj.setPixelDP( 10 + ( 200 * ziele->get( i ).x ) / breite + dOff.x, 10 + ( 200 * ziele->get( i ).y ) / höhe + dOff.y, 0xFF00FF00 );
+        kam->setPosition( 10 + ( 200 * kamPos.x ) / breite, 10 + ( 200 * kamPos.y ) / höhe );
+        kam->setSize( 16000 / breite, ( 10000 ) / 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()
@@ -403,29 +403,29 @@ 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*)&richtung, 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 );
+        d->schreibe( (char *)&richtung, 4 );
         int anz = schlange->getEintragAnzahl();
-        d->schreibe( (char*)&anz, 4 );
+        d->schreibe( (char *)&anz, 4 );
         for( int i = 0; i < anz; i++ )
         {
             short p = schlange->get( i ).x;
-            d->schreibe( (char*)&p, 2 );
+            d->schreibe( (char *)&p, 2 );
             p = schlange->get( i ).y;
-            d->schreibe( (char*)&p, 2 );
+            d->schreibe( (char *)&p, 2 );
         }
         anz = ziele->getEintragAnzahl();
-        d->schreibe( (char*)&anz, 4 );
+        d->schreibe( (char *)&anz, 4 );
         for( int i = 0; i < anz; i++ )
         {
             short p = ziele->get( i ).x;
-            d->schreibe( (char*)&p, 2 );
+            d->schreibe( (char *)&p, 2 );
             p = ziele->get( i ).y;
-            d->schreibe( (char*)&p, 2 );
+            d->schreibe( (char *)&p, 2 );
         }
         d->close();
         d->release();
@@ -437,25 +437,10 @@ void Map::speichern()
 // constant
 int Map::getScore() const
 {
-	return score;
+    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;
+    return beendet;
 }

+ 35 - 39
Snake/Map.h

@@ -10,58 +10,54 @@ using namespace Framework;
 
 struct Pos
 {
-	short x;
-	short y;
+    short x;
+    short y;
 };
 
-class Map
+class Map : public virtual ReferenceCounter
 {
 private:
-	Array< Pos > *schlange;
-	Array< Pos > *ziele;
-	Rahmen *feld;
-	Rahmen *kam;
-	Rahmen *map;
-	Pos kamPos;
-	bool move;
-	int score;
+    Array< Pos > *schlange;
+    Array< Pos > *ziele;
+    Rahmen *feld;
+    Rahmen *kam;
+    Rahmen *map;
+    Pos kamPos;
+    bool move;
+    int score;
     int scoreCheck;
-	int breite;
-	int höhe;
-	int geschwindigkeit;
-	int zAnzahl;
-	double next;
-	int richtung;
-	bool beendet;
-	int addAnzahl;
-	int neuAnzahl;
-	bool sr;
-	bool rend;
+    int breite;
+    int höhe;
+    int geschwindigkeit;
+    int zAnzahl;
+    double next;
+    int richtung;
+    bool beendet;
+    int addAnzahl;
+    int neuAnzahl;
+    bool sr;
+    bool rend;
     double gameTime;
     Datei capture;
     Critical cs;
     KSGClient::MinigameServerClient *klient;
     RandomGenerator *rGen;
-	int ref;
 
 public:
-	// Konstruktor
-	Map( KSGClient::MinigameServerClient *klient );
-	// Destruktor
-	~Map();
-	// nicht constant
-	void reset( Text *zOptionen );
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
+    // Konstruktor
+    Map( KSGClient::MinigameServerClient *klient );
+    // Destruktor
+    ~Map();
+    // nicht constant
+    void reset( Text *zOptionen );
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
     void speichern();
-	// constant
-	int getScore() const;
-	bool istBeendet() const;
-	// Reference Counting
-	Map *getThis();
-	Map *release();
+    // constant
+    int getScore() const;
+    bool istBeendet() const;
 };
 
 #endif

+ 634 - 727
Snake/Menü.cpp

@@ -15,94 +15,79 @@
 
 // Inhalt der MenüVerloren Klasse aus Menü.h
 // Kontruktor
-MenüVerloren::MenüVerloren( Schrift *zSchrift )
+MenüVerloren::MenüVerloren( UIInit &uiFactory )
+    : ReferenceCounter()
 {
-	ram = new LRahmen();
-	ram->setSize( 160, 100 );
-	ram->setPosition( 320, 200 );
-	ram->setFarbe( 0xFFFFFFFF );
-	verloren = initTextFeld( 325, 210, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Du hast verloren." );
-	neu = initKnopf( 350, 240, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Neues Spiel" );
-	beenden = initKnopf( 350, 270, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Zurück" );
-	ref = 1;
+    ram = new LRahmen();
+    ram->setSize( 160, 100 );
+    ram->setPosition( 320, 200 );
+    ram->setFarbe( 0xFFFFFFFF );
+    verloren = initTextFeld( 325, 210, 150, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, "Du hast verloren." );
+    neu = initKnopf( 350, 240, 100, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, "Neues Spiel" );
+    beenden = initKnopf( 350, 270, 100, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::Center, "Zurück" );
 }
 
 // Destruktor
 MenüVerloren::~MenüVerloren()
 {
-	verloren->release();
-	neu->release();
-	beenden->release();
-	ram->release();
+    verloren->release();
+    neu->release();
+    beenden->release();
+    ram->release();
 }
 
 // nicht constant
 int MenüVerloren::doPublicMausEreignis( MausEreignis &me )
 {
-	bool vera = me.verarbeitet;
-	int ret = 0;
-	neu->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-		ret = 1;
-	beenden->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && !ret && me.id == ME_RLinks )
-		ret = 2;
-	return ret;
+    bool vera = me.verarbeitet;
+    int ret = 0;
+    neu->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        ret = 1;
+    beenden->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && !ret && me.id == ME_RLinks )
+        ret = 2;
+    return ret;
 }
 
 bool MenüVerloren::tick( double tickVal )
 {
-	bool ret = verloren->tick( tickVal );
-	ret |= neu->tick( tickVal );
-	ret |= beenden->tick( tickVal );
-	return ret;
+    bool ret = verloren->tick( tickVal );
+    ret |= neu->tick( tickVal );
+    ret |= beenden->tick( tickVal );
+    return ret;
 }
 
 void MenüVerloren::render( Bild &zRObj )
 {
-	zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
-	verloren->render( zRObj );
-	neu->render( zRObj );
-	beenden->render( zRObj );
-	ram->render( zRObj );
-}
-
-// Reference Counting
-MenüVerloren *MenüVerloren::getThis()
-{
-	ref++;
-	return this;
-}
-
-MenüVerloren *MenüVerloren::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
+    verloren->render( zRObj );
+    neu->render( zRObj );
+    beenden->render( zRObj );
+    ram->render( zRObj );
 }
 
 
 // Inhalt der MenüSpiel Klasse aus Menü.h
 // Konstruktor
-MenüSpiel::MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient )
+MenüSpiel::MenüSpiel( UIInit &uiFactory, KSGClient::MinigameServerClient *klient )
+    : ReferenceCounter()
 {
-	scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
-	beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
-	map = new Map( klient );
-	verloren = new MenüVerloren( zSchrift );
-	beendet = 0;
+    scoreT = initTextFeld( 690, 10, 100, 20, uiFactory, TextFeld::Style::Text, "Score: 0" );
+    beenden = initKnopf( 690, 40, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Beenden" );
+    map = new Map( klient );
+    verloren = new MenüVerloren( uiFactory );
+    beendet = 0;
     timePuffer = 0;
-	ref = 1;
 }
 
 // Destruktor
 MenüSpiel::~MenüSpiel()
 {
-	scoreT->release();
-	beenden->release();
-	map->release();
-	verloren->release();
+    scoreT->release();
+    beenden->release();
+    map->release();
+    verloren->release();
 }
 
 // nicht constant
@@ -162,103 +147,89 @@ void Men
     opd->speichern();
     opd->release();
     optionen += ",Seed=0";
-	map->reset( &optionen );
-	beendet = 0;
-	scoreT->setText( "Score: " );
-	scoreT->zText()->append( map->getScore() );
+    map->reset( &optionen );
+    beendet = 0;
+    scoreT->setText( "Score: " );
+    scoreT->zText()->append( map->getScore() );
 }
 
 void MenüSpiel::doPublicMausEreignis( MausEreignis &me )
 {
-	bool vera = me.verarbeitet;
-	beenden->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-	{
-		map->speichern();
-		beendet = 1;
-	}
-	map->doPublicMausEreignis( me );
-	if( map->istBeendet() )
-	{
-		int ak = verloren->doPublicMausEreignis( me );
-		if( ak == 1 )
-			reset();
-		if( ak == 2 )
-			beendet = 1;
-	}
+    bool vera = me.verarbeitet;
+    beenden->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        map->speichern();
+        beendet = 1;
+    }
+    map->doPublicMausEreignis( me );
+    if( map->istBeendet() )
+    {
+        int ak = verloren->doPublicMausEreignis( me );
+        if( ak == 1 )
+            reset();
+        if( ak == 2 )
+            beendet = 1;
+    }
 }
 
 void MenüSpiel::doTastaturEreignis( TastaturEreignis &te )
 {
-	if( map->istBeendet() )
-	{
-		if( te.id == TE_Release && te.taste == T_Enter )
-			reset();
-		if( te.id == TE_Release && te.taste == T_BackSpace )
-			beendet = 1;
-		return;
-	}
-	map->doTastaturEreignis( te );
+    if( map->istBeendet() )
+    {
+        if( te.id == TE_Release && te.taste == T_Enter )
+            reset();
+        if( te.id == TE_Release && te.taste == T_BackSpace )
+            beendet = 1;
+        return;
+    }
+    map->doTastaturEreignis( te );
 }
 
 bool MenüSpiel::tick( double tickVal )
 {
     timePuffer += tickVal;
-	bool ret = beenden->tick( tickVal );
+    bool ret = beenden->tick( tickVal );
     while( timePuffer >= 0.01 )
     {
         ret |= map->tick( 0.01 );
         timePuffer -= 0.01;
     }
-	scoreT->setText( "Score: " );
-	scoreT->zText()->append( map->getScore() );
-	if( map->istBeendet() )
-		ret |= verloren->tick( tickVal );
-	return ret;
+    scoreT->setText( "Score: " );
+    scoreT->zText()->append( map->getScore() );
+    if( map->istBeendet() )
+        ret |= verloren->tick( tickVal );
+    return ret;
 }
 
 void MenüSpiel::render( Bild &zRObj )
 {
-	scoreT->render( zRObj );
-	beenden->render( zRObj );
-	map->render( zRObj );
-	if( map->istBeendet() )
-		verloren->render( zRObj );
+    scoreT->render( zRObj );
+    beenden->render( zRObj );
+    map->render( zRObj );
+    if( map->istBeendet() )
+        verloren->render( zRObj );
 }
 
 // constant
 bool MenüSpiel::istBeendet() const
 {
-	return beendet;
-}
-
-// Reference Counting
-MenüSpiel *MenüSpiel::getThis()
-{
-	ref++;
-	return this;
-}
-
-MenüSpiel *MenüSpiel::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return beendet;
 }
 
 
 // Inhalt der MenüWiederhohlung Klasse
 // Konstruktor
-MenüWiederhohlung::MenüWiederhohlung( Schrift *zSchrift, Bildschirm *zScreen, Datei *datei, Text *zOptionen )
+MenüWiederhohlung::MenüWiederhohlung( UIInit &uiFactory, Datei *datei, Text *zOptionen )
+    : ReferenceCounter()
 {
-    scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
-    beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
+    scoreT = initTextFeld( 690, 10, 100, 20, uiFactory, TextFeld::Style::Text, "Score: 0" );
+    beenden = initKnopf( 690, 40, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Beenden" );
     this->datei = datei;
     if( !datei->istOffen() )
         datei->open( Datei::Style::lesen );
     __int64 seed;
-    datei->lese( (char*)&seed, 8 );
+    datei->lese( (char *)&seed, 8 );
     zOptionen->append( ",Fortsetzen=0,Seed=" );
     zOptionen->append( seed );
     map = new Map( 0 );
@@ -266,9 +237,8 @@ Men
     beendet = 0;
     nowTime = 0;
     nextTime = 0;
-    datei->lese( (char*)&nextTime, 8 );
+    datei->lese( (char *)&nextTime, 8 );
     timePuffer = 0;
-    ref = 1;
 }
 
 // Destruktor
@@ -312,7 +282,7 @@ bool Men
         if( datei->istEnde() )
             nextTime = -1;
         else
-            datei->lese( (char*)&nextTime, 8 );
+            datei->lese( (char *)&nextTime, 8 );
         TastaturEreignis te;
         te.taste = aktion;
         te.verarbeitet = 0;
@@ -344,41 +314,27 @@ bool Men
     return beendet;
 }
 
-// Reference Counting
-MenüWiederhohlung *MenüWiederhohlung::getThis()
-{
-    ref++;
-    return this;
-}
-
-MenüWiederhohlung *MenüWiederhohlung::release()
-{
-    if( !--ref )
-        delete this;
-    return 0;
-}
-
 
 // Inhalt der MenüStatistik Klasse aus Menü.h
 // Konstruktor
-MenüStatistik::MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient )
+MenüStatistik::MenüStatistik( UIInit &uiFactory, KSGClient::MinigameServerClient *klient )
+    : ReferenceCounter()
 {
     this->klient = klient;
     wiederH = 0;
-    screen = zScreen->getThis();
-	ansichtT = initTextFeld( 245, 10, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Ansicht:" );
-	ansicht = initAuswahlBox( 295, 10, 120, 20, zSchrift, AuswahlBox::Style::Normal | AuswahlBox::Style::Hintergrund, { "Tabelle", "Diagramm" } );
-	optionen = initKontrollKnopf( 425, 10, 130, 20, zSchrift, KontrollKnopf::Style::Normal, "Optionen beachten" );
-    worldBestT = initObjTabelle( 115, 40, 570, 120, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 60, 0, 0 },{ "Spieler", 100, 0, 0 },{ "Ansehen", 55, 0, 0 },{ "Breite", 70, 0, 0 },{ "Höhe", 70, 0, 0 },{ "Ziele", 70, 0, 0 },{ "Anhängen", 60, 0, 0 },{ "Tempo", 65, 0, 0 } }, 20 );
-	gesammtT = initObjTabelle( 115, 170, 570, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "Anhängen", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
-	optionenT = initObjTabelle( 115, 170, 570, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "Anhängen", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
-	gesammtD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
-	optionenD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
-	releasen = initKnopf( 10, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zurücksetzen" );
-	zurück = initKnopf( 350, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zurück" );
-	schrift = zSchrift->getThis();
-    tr = new TextRenderer( schrift->getThis() );
-	asyncFinished = 1;
+    this->uiFactory = uiFactory;
+    ansichtT = initTextFeld( 245, 10, 50, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Ansicht:" );
+    ansicht = initAuswahlBox( 295, 10, 120, 20, uiFactory, AuswahlBox::Style::Normal | AuswahlBox::Style::Hintergrund, { "Tabelle", "Diagramm" } );
+    optionen = initKontrollKnopf( 425, 10, 130, 20, uiFactory, KontrollKnopf::Style::Normal, "Optionen beachten" );
+    worldBestT = initObjTabelle( 115, 40, 570, 120, uiFactory, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 60, 0, 0 },{ "Spieler", 100, 0, 0 },{ "Ansehen", 55, 0, 0 },{ "Breite", 70, 0, 0 },{ "Höhe", 70, 0, 0 },{ "Ziele", 70, 0, 0 },{ "Anhängen", 60, 0, 0 },{ "Tempo", 65, 0, 0 } }, 20 );
+    gesammtT = initObjTabelle( 115, 170, 570, 290, uiFactory, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "Anhängen", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
+    optionenT = initObjTabelle( 115, 170, 570, 290, uiFactory, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Höhe", 70, 0, 0 }, { "Ziele", 70, 0, 0 }, { "Anhängen", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
+    gesammtD = initLinienDiagramm( 100, 170, 600, 290, uiFactory, LDiag::Style::DatenRahmen, 0 );
+    optionenD = initLinienDiagramm( 100, 170, 600, 290, uiFactory, LDiag::Style::DatenRahmen, 0 );
+    releasen = initKnopf( 10, 470, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Zurücksetzen" );
+    zurück = initKnopf( 350, 470, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Zurück" );
+    tr = new TextRenderer( dynamic_cast<Schrift *>( uiFactory.initParam.schrift->getThis() ) );
+    asyncFinished = 1;
 }
 
 // Destruktor
@@ -390,32 +346,29 @@ Men
     }
     tr->release();
     worldBestT->release();
-	ansichtT->release();
-	ansicht->release();
-	optionen->release();
-	gesammtT->release();
-	optionenT->release();
-	gesammtD->release();
-	optionenD->release();
-	releasen->release();
-	zurück->release();
-	schrift->release();
+    ansichtT->release();
+    ansicht->release();
+    optionen->release();
+    gesammtT->release();
+    optionenT->release();
+    gesammtD->release();
+    optionenD->release();
+    releasen->release();
+    zurück->release();
     klient->release();
     if( wiederH )
         wiederH->release();
-    screen->release();
 }
 
 // nicht constant
 void MenüStatistik::reset()
 {
     if( wiederH )
-        wiederH = wiederH->release();
-    ObjTabelle *tmpWBT = ( ObjTabelle*)worldBestT->getThis();
-    KSGClient::MinigameServerClient *tmpKlient = klient->getThis();
-    Schrift *tmpSchrift = schrift->getThis();
-	asyncFinished = 0;
-    new AsynchronCall( [ this, tmpWBT, tmpKlient, tmpSchrift ]()
+        wiederH = (MenüWiederhohlung *)wiederH->release();
+    ObjTabelle *tmpWBT = dynamic_cast<ObjTabelle *>( worldBestT->getThis() );
+    KSGClient::MinigameServerClient *tmpKlient = dynamic_cast<KSGClient::MinigameServerClient *>( klient->getThis() );
+    asyncFinished = 0;
+    new AsynchronCall( [this, tmpWBT, tmpKlient]()
     {
         Array< int > score;
         RCArray< Text > player;
@@ -423,39 +376,39 @@ void Men
         int anz = tmpKlient->getMinigameBestscoreList( "Snake", &score, &player, &option );
         for( int i = 0; i < anz; i++ )
         {
-            TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text( score.get( i ) ) );
-            TextFeld *spielerT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, player.z( i )->getText() );
+            TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, Text( score.get( i ) ) );
+            TextFeld *spielerT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, player.z( i )->getText() );
             Text optionen = option.z( i )->getText();
             Text *breite = optionen.getTeilText( optionen.positionVon( '=' ) + 1, optionen.positionVon( ',' ) );
             Text *höhe = optionen.getTeilText( optionen.positionVon( '=', 1 ) + 1, optionen.positionVon( ',', 1 ) );
             Text *ziele = optionen.getTeilText( optionen.positionVon( '=', 2 ) + 1, optionen.positionVon( ',', 2 ) );
             Text *anhang = optionen.getTeilText( optionen.positionVon( '=', 3 ) + 1, optionen.positionVon( ',', 3 ) );
             Text *tempo = optionen.getTeilText( optionen.positionVon( '=', 4 ) + 1 );
-            TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, breite->getText() );
+            TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, breite->getText() );
             breite->release();
-            TextFeld *höheT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, höhe->getText() );
+            TextFeld *höheT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, höhe->getText() );
             höhe->release();
-            TextFeld *zieleT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, ziele->getText() );
+            TextFeld *zieleT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, ziele->getText() );
             ziele->release();
-            TextFeld *anhangT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, anhang->getText() );
+            TextFeld *anhangT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, anhang->getText() );
             anhang->release();
-            TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, tempo->getText() );
+            TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, tempo->getText() );
             tempo->release();
-            Knopf *ansehenK = initKnopf( 0, 0, 0, 0, tmpSchrift, Knopf::Style::Normal, "Ansehen" );
-            ansehenK->setMausEreignis( [ this, optionen ]( void *p, void *obj, MausEreignis me ) -> bool
+            Knopf *ansehenK = initKnopf( 0, 0, 0, 0, uiFactory, Knopf::Style::Normal, "Ansehen" );
+            ansehenK->setMausEreignis( [this, optionen]( void *p, void *obj, MausEreignis me ) -> bool
             {
                 if( me.id == ME_RLinks && !me.verarbeitet )
                 {
-                    ( (Knopf*)obj )->removeStyle( Knopf::Style::Erlaubt );
+                    ( (Knopf *)obj )->removeStyle( Knopf::Style::Erlaubt );
                     getThis();
-                    new AsynchronCall( [ this, optionen, obj ]()
+                    new AsynchronCall( [this, optionen, obj]()
                     {
                         Datei *d = klient->downloadGameCapture( "Snake", optionen );
-                        ( (Knopf*)obj )->addStyle( Knopf::Style::Erlaubt );
+                        ( (Knopf *)obj )->addStyle( Knopf::Style::Erlaubt );
                         if( wiederH )
-                            wiederH = wiederH->release();
+                            wiederH = (MenüWiederhohlung *)wiederH->release();
                         Text options = optionen.getText();
-                        wiederH = new MenüWiederhohlung( schrift, screen, d, &options );
+                        wiederH = new MenüWiederhohlung( uiFactory, d, &options );
                         release();
                     } );
                 }
@@ -473,138 +426,137 @@ void Men
         }
         tmpKlient->release();
         tmpWBT->release();
-        tmpSchrift->release();
     }, &asyncFinished );
-	InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
-	opd->laden();
-	if( !opd->wertExistiert( "Breite" ) )
-		opd->addWert( "Breite", "80" );
-	if( !opd->wertExistiert( "Höhe" ) )
-		opd->addWert( "Höhe", "50" );
-	if( !opd->wertExistiert( "Ziele" ) )
-		opd->addWert( "Ziele", "1" );
-	if( !opd->wertExistiert( "Anhängen" ) )
-		opd->addWert( "Anhängen", "10" );
-	if( !opd->wertExistiert( "Geschwindigkeit" ) )
-		opd->addWert( "Geschwindigkeit", "10" );
-	if( !opd->wertExistiert( "Fortsetzen" ) )
-		opd->addWert( "Fortsetzen", "0" );
-	opd->speichern();
-	KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
-	stb->laden();
-	int anz = stb->getZeilenAnzahl();
-	bool *fertig = new bool[ anz ];
-	ZeroMemory( fertig, anz );
-	int mS = 0;
-	int omS = 0;
-	int oAnz = 0;
-	for( int i = 0; i < anz; i++ )
-	{
-		int maxScore = -1;
-		int p = -1;
-		for( int j = 0; j < anz; j++ )
-		{
-			if( !fertig[ j ] && maxScore < (int)*stb->zFeld( j, 1 ) )
-			{
-				p = j;
-				maxScore = (int)*stb->zFeld( j, 1 );
-			}
-		}
-		if( p >= 0 )
-		{
-			fertig[ p ] = 1;
-			TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 1 )->getText() );
-			TextFeld *datumT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 0 )->getText() );
-			TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 2 )->getText() );
-			TextFeld *höheT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 3 )->getText() );
-			TextFeld *zieleT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 5 )->getText() );
-			TextFeld *appendT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 6 )->getText() );
-			TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 4 )->getText() );
-			gesammtT->addZeile( Text() += p );
-			gesammtT->setZeichnungZ( 0, i + 1, scoreT );
-			gesammtT->setZeichnungZ( 1, i + 1, datumT );
-			gesammtT->setZeichnungZ( 2, i + 1, breiteT );
-			gesammtT->setZeichnungZ( 3, i + 1, höheT );
-			gesammtT->setZeichnungZ( 4, i + 1, zieleT );
-			gesammtT->setZeichnungZ( 5, i + 1, appendT );
-			gesammtT->setZeichnungZ( 6, i + 1, tempoT );
-			if( breiteT->zText()->istGleich( opd->zWert( "Breite" )->getText() ) &&
-				höheT->zText()->istGleich( opd->zWert( "Höhe" )->getText() ) &&
-				zieleT->zText()->istGleich( opd->zWert( "Ziele" )->getText() ) &&
-				appendT->zText()->istGleich( opd->zWert( "Anhängen" )->getText() ) &&
-				tempoT->zText()->istGleich( opd->zWert( "Geschwindigkeit" )->getText() ) )
-			{
-				optionenT->addZeile( Text() += p );
-				int n = optionenT->getZeilenNummer( Text() += p );
-				optionenT->setZeichnungZ( 0, n, scoreT->getThis() );
-				optionenT->setZeichnungZ( 1, n, datumT->getThis() );
-				optionenT->setZeichnungZ( 2, n, breiteT->getThis() );
-				optionenT->setZeichnungZ( 3, n, höheT->getThis() );
-				optionenT->setZeichnungZ( 4, n, zieleT->getThis() );
-				optionenT->setZeichnungZ( 5, n, appendT->getThis() );
-				optionenT->setZeichnungZ( 6, n, tempoT->getThis() );
-				if( !omS )
-					omS = maxScore;
-				oAnz++;
-			}
-		}
-		if( !mS )
-			mS = maxScore;
-	}
-	delete[] fertig;
-	DiagDaten *gd = new DiagDaten();
-	gd->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
-	gd->hIntervallFarbe = 0xFFFFFFFF;
-	gd->hIntervallName->setText( "Spiel" );
-	gd->rasterDicke = 1;
-	gd->rasterFarbe = 0xFF505050;
-	gd->vIntervallFarbe = 0xFFFFFFFF;
-	gd->vIntervallName->setText( "Score" );
-	gesammtD->setDiagDatenZ( gd );
-	gesammtD->addVIntervallText( mS + 1, Text() += ( mS + 1 ) );
-	gesammtD->addVIntervallText( 0, "0" );
-	gesammtD->addHIntervallText( 0, "1" );
-	if( anz > 1 )
-		gesammtD->addHIntervallText( anz - 1, Text() += anz );
-	gesammtD->addWert( "Score" );
-	gesammtD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
-	gesammtD->setWertFarbe( 0, 0xFF00FF00 );
-	gesammtD->zDiagWert( 0 )->hintergrund = 0xFF205050;
-	DiagDaten *od = new DiagDaten();
-	od->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
-	od->hIntervallFarbe = 0xFFFFFFFF;
-	od->hIntervallName->setText( "Spiel" );
-	od->rasterDicke = 1;
-	od->rasterFarbe = 0xFF505050;
-	od->vIntervallFarbe = 0xFFFFFFFF;
-	od->vIntervallName->setText( "Score" );
-	optionenD->setDiagDatenZ( od );
-	optionenD->addVIntervallText( omS + 1, Text() += ( omS + 1 ) );
-	optionenD->addVIntervallText( 0, "0" );
-	optionenD->addHIntervallText( 0, "1" );
-	if( oAnz > 1 )
-		optionenD->addHIntervallText( oAnz - 1, Text() += oAnz );
-	optionenD->addWert( "Score" );
-	optionenD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
-	optionenD->setWertFarbe( 0, 0xFF00FF00 );
-	optionenD->zDiagWert( 0 )->hintergrund = 0xFF205050;
-	int j = 0;
-	for( int i = 0; i < anz; i++ )
-	{
-		gesammtD->addPunkt( 0, i, (int)*stb->zFeld( i, 1 ) );
-		if( (int)*stb->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
-			(int)*stb->zFeld( i, 3 ) == (int)*opd->zWert( "Höhe" ) &&
-			(int)*stb->zFeld( i, 5 ) == (int)*opd->zWert( "Ziele" ) &&
-			(int)*stb->zFeld( i, 6 ) == (int)*opd->zWert( "Anhängen" ) &&
-			(int)*stb->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
-		{
-			optionenD->addPunkt( 0, j, (int)*stb->zFeld( i, 1 ) );
-			j++;
-		}
-	}
-	stb->release();
-	opd->release();
-	beendet = 0;
+    InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
+    opd->laden();
+    if( !opd->wertExistiert( "Breite" ) )
+        opd->addWert( "Breite", "80" );
+    if( !opd->wertExistiert( "Höhe" ) )
+        opd->addWert( "Höhe", "50" );
+    if( !opd->wertExistiert( "Ziele" ) )
+        opd->addWert( "Ziele", "1" );
+    if( !opd->wertExistiert( "Anhängen" ) )
+        opd->addWert( "Anhängen", "10" );
+    if( !opd->wertExistiert( "Geschwindigkeit" ) )
+        opd->addWert( "Geschwindigkeit", "10" );
+    if( !opd->wertExistiert( "Fortsetzen" ) )
+        opd->addWert( "Fortsetzen", "0" );
+    opd->speichern();
+    KSGTDatei *stb = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
+    stb->laden();
+    int anz = stb->getZeilenAnzahl();
+    bool *fertig = new bool[ anz ];
+    ZeroMemory( fertig, anz );
+    int mS = 0;
+    int omS = 0;
+    int oAnz = 0;
+    for( int i = 0; i < anz; i++ )
+    {
+        int maxScore = -1;
+        int p = -1;
+        for( int j = 0; j < anz; j++ )
+        {
+            if( !fertig[ j ] && maxScore < (int)*stb->zFeld( j, 1 ) )
+            {
+                p = j;
+                maxScore = (int)*stb->zFeld( j, 1 );
+            }
+        }
+        if( p >= 0 )
+        {
+            fertig[ p ] = 1;
+            TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 1 )->getText() );
+            TextFeld *datumT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 0 )->getText() );
+            TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 2 )->getText() );
+            TextFeld *höheT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 3 )->getText() );
+            TextFeld *zieleT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 5 )->getText() );
+            TextFeld *appendT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 6 )->getText() );
+            TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 4 )->getText() );
+            gesammtT->addZeile( Text() += p );
+            gesammtT->setZeichnungZ( 0, i + 1, scoreT );
+            gesammtT->setZeichnungZ( 1, i + 1, datumT );
+            gesammtT->setZeichnungZ( 2, i + 1, breiteT );
+            gesammtT->setZeichnungZ( 3, i + 1, höheT );
+            gesammtT->setZeichnungZ( 4, i + 1, zieleT );
+            gesammtT->setZeichnungZ( 5, i + 1, appendT );
+            gesammtT->setZeichnungZ( 6, i + 1, tempoT );
+            if( breiteT->zText()->istGleich( opd->zWert( "Breite" )->getText() ) &&
+                höheT->zText()->istGleich( opd->zWert( "Höhe" )->getText() ) &&
+                zieleT->zText()->istGleich( opd->zWert( "Ziele" )->getText() ) &&
+                appendT->zText()->istGleich( opd->zWert( "Anhängen" )->getText() ) &&
+                tempoT->zText()->istGleich( opd->zWert( "Geschwindigkeit" )->getText() ) )
+            {
+                optionenT->addZeile( Text() += p );
+                int n = optionenT->getZeilenNummer( Text() += p );
+                optionenT->setZeichnungZ( 0, n, dynamic_cast<Zeichnung *>( scoreT->getThis() ) );
+                optionenT->setZeichnungZ( 1, n, dynamic_cast<Zeichnung *>( datumT->getThis() ) );
+                optionenT->setZeichnungZ( 2, n, dynamic_cast<Zeichnung *>( breiteT->getThis() ) );
+                optionenT->setZeichnungZ( 3, n, dynamic_cast<Zeichnung *>( höheT->getThis() ) );
+                optionenT->setZeichnungZ( 4, n, dynamic_cast<Zeichnung *>( zieleT->getThis() ) );
+                optionenT->setZeichnungZ( 5, n, dynamic_cast<Zeichnung *>( appendT->getThis() ) );
+                optionenT->setZeichnungZ( 6, n, dynamic_cast<Zeichnung *>( tempoT->getThis() ) );
+                if( !omS )
+                    omS = maxScore;
+                oAnz++;
+            }
+        }
+        if( !mS )
+            mS = maxScore;
+    }
+    delete[] fertig;
+    DiagDaten *gd = new DiagDaten();
+    gd->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
+    gd->hIntervallFarbe = 0xFFFFFFFF;
+    gd->hIntervallName->setText( "Spiel" );
+    gd->rasterDicke = 1;
+    gd->rasterFarbe = 0xFF505050;
+    gd->vIntervallFarbe = 0xFFFFFFFF;
+    gd->vIntervallName->setText( "Score" );
+    gesammtD->setDiagDatenZ( gd );
+    gesammtD->addVIntervallText( mS + 1, Text() += ( mS + 1 ) );
+    gesammtD->addVIntervallText( 0, "0" );
+    gesammtD->addHIntervallText( 0, "1" );
+    if( anz > 1 )
+        gesammtD->addHIntervallText( anz - 1, Text() += anz );
+    gesammtD->addWert( "Score" );
+    gesammtD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
+    gesammtD->setWertFarbe( 0, 0xFF00FF00 );
+    gesammtD->zDiagWert( 0 )->hintergrund = 0xFF205050;
+    DiagDaten *od = new DiagDaten();
+    od->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
+    od->hIntervallFarbe = 0xFFFFFFFF;
+    od->hIntervallName->setText( "Spiel" );
+    od->rasterDicke = 1;
+    od->rasterFarbe = 0xFF505050;
+    od->vIntervallFarbe = 0xFFFFFFFF;
+    od->vIntervallName->setText( "Score" );
+    optionenD->setDiagDatenZ( od );
+    optionenD->addVIntervallText( omS + 1, Text() += ( omS + 1 ) );
+    optionenD->addVIntervallText( 0, "0" );
+    optionenD->addHIntervallText( 0, "1" );
+    if( oAnz > 1 )
+        optionenD->addHIntervallText( oAnz - 1, Text() += oAnz );
+    optionenD->addWert( "Score" );
+    optionenD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
+    optionenD->setWertFarbe( 0, 0xFF00FF00 );
+    optionenD->zDiagWert( 0 )->hintergrund = 0xFF205050;
+    int j = 0;
+    for( int i = 0; i < anz; i++ )
+    {
+        gesammtD->addPunkt( 0, i, (int)*stb->zFeld( i, 1 ) );
+        if( (int)*stb->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
+            (int)*stb->zFeld( i, 3 ) == (int)*opd->zWert( "Höhe" ) &&
+            (int)*stb->zFeld( i, 5 ) == (int)*opd->zWert( "Ziele" ) &&
+            (int)*stb->zFeld( i, 6 ) == (int)*opd->zWert( "Anhängen" ) &&
+            (int)*stb->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
+        {
+            optionenD->addPunkt( 0, j, (int)*stb->zFeld( i, 1 ) );
+            j++;
+        }
+    }
+    stb->release();
+    opd->release();
+    beendet = 0;
 }
 
 void MenüStatistik::doPublicMausEreignis( MausEreignis &me )
@@ -614,47 +566,47 @@ void Men
         wiederH->doPublicMausEreignis( me );
         return;
     }
-	ansicht->doPublicMausEreignis( me );
-	optionen->doPublicMausEreignis( me );
+    ansicht->doPublicMausEreignis( me );
+    optionen->doPublicMausEreignis( me );
     gesammtT->doPublicMausEreignis( me );
     optionenT->doPublicMausEreignis( me );
     worldBestT->doPublicMausEreignis( me );
-	bool vera = me.verarbeitet;
-	releasen->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-	{ // Statistik releasen
-		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
-		{ // nur bestimmte Statistik releasen
-			InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
-			opd->laden();
-			KSGTDatei *score = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
-			score->laden();
-			int zeilen = score->getZeilenAnzahl();
-			for( int i = 0; i < zeilen; i++ )
-			{
-				if( (int)*score->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
-					(int)*score->zFeld( i, 3 ) == (int)*opd->zWert( "Höhe" ) &&
-					(int)*score->zFeld( i, 5 ) == (int)*opd->zWert( "Ziele" ) &&
-					(int)*score->zFeld( i, 6 ) == (int)*opd->zWert( "Anhängen" ) &&
-					(int)*score->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
-				{
-					score->removeZeile( i );
-					i--;
-					zeilen--;
-				}
-			}
-			score->speichern();
-			score->release();
-			opd->release();
-		}
-		else // alles releasen
-			DateiRemove( "data/Minigames/Snake/data/score.ksgt" );
-		reset();
-	}
-	vera = me.verarbeitet;
-	zurück->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-		beendet = 1;
+    bool vera = me.verarbeitet;
+    releasen->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    { // Statistik releasen
+        if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
+        { // nur bestimmte Statistik releasen
+            InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
+            opd->laden();
+            KSGTDatei *score = new KSGTDatei( "data/Minigames/Snake/data/score.ksgt" );
+            score->laden();
+            int zeilen = score->getZeilenAnzahl();
+            for( int i = 0; i < zeilen; i++ )
+            {
+                if( (int)*score->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
+                    (int)*score->zFeld( i, 3 ) == (int)*opd->zWert( "Höhe" ) &&
+                    (int)*score->zFeld( i, 5 ) == (int)*opd->zWert( "Ziele" ) &&
+                    (int)*score->zFeld( i, 6 ) == (int)*opd->zWert( "Anhängen" ) &&
+                    (int)*score->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
+                {
+                    score->removeZeile( i );
+                    i--;
+                    zeilen--;
+                }
+            }
+            score->speichern();
+            score->release();
+            opd->release();
+        }
+        else // alles releasen
+            DateiRemove( "data/Minigames/Snake/data/score.ksgt" );
+        reset();
+    }
+    vera = me.verarbeitet;
+    zurück->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        beendet = 1;
 }
 
 bool MenüStatistik::tick( double tickVal )
@@ -663,19 +615,19 @@ bool Men
     {
         bool ret = wiederH->tick( tickVal );
         if( wiederH->istBeendet() )
-            wiederH = wiederH->release();
+            wiederH = (MenüWiederhohlung *)wiederH->release();
         return ret;
     }
-	bool ret = ansicht->tick( tickVal );
-	ret |= optionen->tick( tickVal );
-	ret |= releasen->tick( tickVal );
-	ret |= zurück->tick( tickVal );
-	ret |= gesammtT->tick( tickVal );
-	ret |= optionenT->tick( tickVal );
-	ret |= gesammtD->tick( tickVal );
-	ret |= optionenD->tick( tickVal );
+    bool ret = ansicht->tick( tickVal );
+    ret |= optionen->tick( tickVal );
+    ret |= releasen->tick( tickVal );
+    ret |= zurück->tick( tickVal );
+    ret |= gesammtT->tick( tickVal );
+    ret |= optionenT->tick( tickVal );
+    ret |= gesammtD->tick( tickVal );
+    ret |= optionenD->tick( tickVal );
     ret |= worldBestT->tick( tickVal );
-	return ret;
+    return ret;
 }
 
 void MenüStatistik::render( Bild &zRObj )
@@ -691,31 +643,31 @@ void Men
     Text localScore = "Dein Score:";
     tr->renderText( 10, 170, localScore, zRObj, 0xFFFFFFFF );
     worldBestT->render( zRObj );
-	if( !ansicht->getAuswahl() )
-	{
-		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
-			optionenT->render( zRObj );
-		else
-			gesammtT->render( zRObj );
-	}
-	else
-	{
-		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
-			optionenD->render( zRObj );
-		else
-			gesammtD->render( zRObj );
-	}
-	ansichtT->render( zRObj );
-	ansicht->render( zRObj );
-	optionen->render( zRObj );
-	releasen->render( zRObj );
-	zurück->render( zRObj );
+    if( !ansicht->getAuswahl() )
+    {
+        if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
+            optionenT->render( zRObj );
+        else
+            gesammtT->render( zRObj );
+    }
+    else
+    {
+        if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
+            optionenD->render( zRObj );
+        else
+            gesammtD->render( zRObj );
+    }
+    ansichtT->render( zRObj );
+    ansicht->render( zRObj );
+    optionen->render( zRObj );
+    releasen->render( zRObj );
+    zurück->render( zRObj );
 }
 
 // constant
 bool MenüStatistik::istBeendet() const
 {
-	return beendet;
+    return beendet;
 }
 
 bool MenüStatistik::istWiederhohlung() const
@@ -723,424 +675,379 @@ bool Men
     return wiederH != 0;
 }
 
-// Reference Counting
-MenüStatistik *MenüStatistik::getThis()
-{
-	ref++;
-	return this;
-}
-
-MenüStatistik *MenüStatistik::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
-}
-
 
 // Inhalt der MenüOptionen aus Menü.h
 // Konstruktor
-MenüOptionen::MenüOptionen( Schrift *zSchrift, Bildschirm *zScreen )
+MenüOptionen::MenüOptionen( UIInit &uiFactory )
+    : ReferenceCounter()
 {
-	breiteT = initTextFeld( 310, 120, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Breite:" );
-	breite = initTextFeld( 440, 120, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
-	breite->setTastaturEreignis( _nurNummernTE );
-	höheT = initTextFeld( 310, 160, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Höhe:" );
-	höhe = initTextFeld( 440, 160, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
-	höhe->setTastaturEreignis( _nurNummernTE );
-	zAnzahlT = initTextFeld( 310, 200, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Verschiedene Ziele:" );
-	zAnzahl = initTextFeld( 440, 200, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
-	zAnzahl->setTastaturEreignis( _nurNummernTE );
-	nAnzahlT = initTextFeld( 310, 240, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Länge Hinzufügen:" );
-	nAnzahl = initTextFeld( 440, 240, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
-	nAnzahl->setTastaturEreignis( _nurNummernTE );
-	tempoT = initTextFeld( 310, 280, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Geschwindigkeit:" );
-	tempo = initTextFeld( 440, 280, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
-	tempo->setTastaturEreignis( _nurNummernTE );
-	fortsetzen = initKontrollKnopf( 310, 320, 180, 20, zSchrift, KontrollKnopf::Style::Normal, "Letztes Spiel fortsetzen" );
-	fortsetzen->setMausEreignis( _ret1ME );
-	abbrechen = initKnopf( 310, 360, 85, 20, zSchrift, Knopf::Style::Sichtbar, "Abbrechen" );
-	ok = initKnopf( 405, 360, 85, 20, zSchrift, Knopf::Style::Sichtbar, "Ok" );
-	beendet = 0;
-	ref = 1;
+    breiteT = initTextFeld( 310, 120, 130, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Breite:" );
+    breite = initTextFeld( 440, 120, 50, 20, uiFactory, TextFeld::Style::TextFeld, "" );
+    breite->setTastaturEreignis( _nurNummernTE );
+    höheT = initTextFeld( 310, 160, 130, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Höhe:" );
+    höhe = initTextFeld( 440, 160, 50, 20, uiFactory, TextFeld::Style::TextFeld, "" );
+    höhe->setTastaturEreignis( _nurNummernTE );
+    zAnzahlT = initTextFeld( 310, 200, 130, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Verschiedene Ziele:" );
+    zAnzahl = initTextFeld( 440, 200, 50, 20, uiFactory, TextFeld::Style::TextFeld, "" );
+    zAnzahl->setTastaturEreignis( _nurNummernTE );
+    nAnzahlT = initTextFeld( 310, 240, 130, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Länge Hinzufügen:" );
+    nAnzahl = initTextFeld( 440, 240, 50, 20, uiFactory, TextFeld::Style::TextFeld, "" );
+    nAnzahl->setTastaturEreignis( _nurNummernTE );
+    tempoT = initTextFeld( 310, 280, 130, 20, uiFactory, TextFeld::Style::Text | TextFeld::Style::VCenter, "Geschwindigkeit:" );
+    tempo = initTextFeld( 440, 280, 50, 20, uiFactory, TextFeld::Style::TextFeld, "" );
+    tempo->setTastaturEreignis( _nurNummernTE );
+    fortsetzen = initKontrollKnopf( 310, 320, 180, 20, uiFactory, KontrollKnopf::Style::Normal, "Letztes Spiel fortsetzen" );
+    fortsetzen->setMausEreignis( _ret1ME );
+    abbrechen = initKnopf( 310, 360, 85, 20, uiFactory, Knopf::Style::Sichtbar, "Abbrechen" );
+    ok = initKnopf( 405, 360, 85, 20, uiFactory, Knopf::Style::Sichtbar, "Ok" );
+    beendet = 0;
 }
 
 // Destruktor
 MenüOptionen::~MenüOptionen()
 {
-	breiteT->release();
-	breite->release();
-	höheT->release();
-	höhe->release();
-	zAnzahlT->release();
-	zAnzahl->release();
-	nAnzahlT->release();
-	nAnzahl->release();
-	tempoT->release();
-	tempo->release();
-	fortsetzen->release();
-	abbrechen->release();
-	ok->release();
+    breiteT->release();
+    breite->release();
+    höheT->release();
+    höhe->release();
+    zAnzahlT->release();
+    zAnzahl->release();
+    nAnzahlT->release();
+    nAnzahl->release();
+    tempoT->release();
+    tempo->release();
+    fortsetzen->release();
+    abbrechen->release();
+    ok->release();
 }
 
 // nicht constant
 void MenüOptionen::reset()
 {
-	InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
-	if( !opd->laden() )
-		DateiPfadErstellen( "data/Minigames/Snake/data/optionen.ini" );
-	breite->setText( "80" );
-	if( opd->wertExistiert( "Breite" ) )
-		breite->setText( Text() += (int)*opd->zWert( "Breite" ) );
-	else
-		opd->addWert( "Breite", "80" );
-	höhe->setText( "50" );
-	if( opd->wertExistiert( "Höhe" ) )
-		höhe->setText( Text() += (int)*opd->zWert( "Höhe" ) );
-	else
-		opd->addWert( "Höhe", "50" );
-	zAnzahl->setText( "1" );
-	if( opd->wertExistiert( "Ziele" ) )
-		zAnzahl->setText( Text() += (int)*opd->zWert( "Ziele" ) );
-	else
-		opd->addWert( "Ziele", "1" );
-	nAnzahl->setText( "10" );
-	if( opd->wertExistiert( "Anhängen" ) )
-		nAnzahl->setText( Text() += (int)*opd->zWert( "Anhängen" ) );
-	else
-		opd->addWert( "Anhängen", "10" );
-	tempo->setText( "10" );
-	if( opd->wertExistiert( "Geschwindigkeit" ) )
-		tempo->setText( Text() += (int)*opd->zWert( "Geschwindigkeit" ) );
-	else
-		opd->addWert( "Geschwindigkeit", "10" );
-	fortsetzen->removeStyle( KontrollKnopf::Style::Selected );
-	if( opd->wertExistiert( "Fortsetzen" ) )
-		fortsetzen->setStyle( KontrollKnopf::Style::Selected, (int)*opd->zWert( "Fortsetzen" ) != 0 );
-	else
-		opd->addWert( "Fortsetzen", "0" );
-	beendet = 0;
-	opd->speichern();
-	opd->release();
+    InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
+    if( !opd->laden() )
+        DateiPfadErstellen( "data/Minigames/Snake/data/optionen.ini" );
+    breite->setText( "80" );
+    if( opd->wertExistiert( "Breite" ) )
+        breite->setText( Text() += (int)*opd->zWert( "Breite" ) );
+    else
+        opd->addWert( "Breite", "80" );
+    höhe->setText( "50" );
+    if( opd->wertExistiert( "Höhe" ) )
+        höhe->setText( Text() += (int)*opd->zWert( "Höhe" ) );
+    else
+        opd->addWert( "Höhe", "50" );
+    zAnzahl->setText( "1" );
+    if( opd->wertExistiert( "Ziele" ) )
+        zAnzahl->setText( Text() += (int)*opd->zWert( "Ziele" ) );
+    else
+        opd->addWert( "Ziele", "1" );
+    nAnzahl->setText( "10" );
+    if( opd->wertExistiert( "Anhängen" ) )
+        nAnzahl->setText( Text() += (int)*opd->zWert( "Anhängen" ) );
+    else
+        opd->addWert( "Anhängen", "10" );
+    tempo->setText( "10" );
+    if( opd->wertExistiert( "Geschwindigkeit" ) )
+        tempo->setText( Text() += (int)*opd->zWert( "Geschwindigkeit" ) );
+    else
+        opd->addWert( "Geschwindigkeit", "10" );
+    fortsetzen->removeStyle( KontrollKnopf::Style::Selected );
+    if( opd->wertExistiert( "Fortsetzen" ) )
+        fortsetzen->setStyle( KontrollKnopf::Style::Selected, (int)*opd->zWert( "Fortsetzen" ) != 0 );
+    else
+        opd->addWert( "Fortsetzen", "0" );
+    beendet = 0;
+    opd->speichern();
+    opd->release();
 }
 
 void MenüOptionen::doPublicMausEreignis( MausEreignis &me )
 {
-	breite->doPublicMausEreignis( me );
-	höhe->doPublicMausEreignis( me );
-	zAnzahl->doPublicMausEreignis( me );
-	nAnzahl->doPublicMausEreignis( me );
-	tempo->doPublicMausEreignis( me );
-	fortsetzen->doPublicMausEreignis( me );
-	bool vera = me.verarbeitet;
-	abbrechen->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-		beendet = 1;
-	vera = me.verarbeitet;
-	ok->doPublicMausEreignis( me );
-	if( !vera && me.verarbeitet && me.id == ME_RLinks )
-	{
-		InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
-		if( !opd->laden() )
-			DateiPfadErstellen( "data/Minigames/Snake/data/optionen.ini" );
-		if( (int)*breite->zText() > 1000 )
-			breite->setText( "1000" );
-		if( (int)*breite->zText() < 20 )
-			breite->setText( "20" );
-		if( opd->wertExistiert( "Breite" ) )
-			opd->setWert( "Breite", Text() += (int)*breite->zText() );
-		else
-			opd->addWert( "Breite", Text() += (int)*breite->zText() );
-		if( (int)*höhe->zText() > 1000 )
-			höhe->setText( "1000" );
-		if( (int)*höhe->zText() < 20 )
-			höhe->setText( "20" );
-		if( opd->wertExistiert( "Höhe" ) )
-			opd->setWert( "Höhe", Text() += (int)*höhe->zText() );
-		else
-			opd->addWert( "Höhe", Text() += (int)*höhe->zText() );
-		if( (int)*zAnzahl->zText() > ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 )
-			zAnzahl->setText( Text() += ( ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 ) );
-		if( (int)*zAnzahl->zText() < 1 )
-			zAnzahl->setText( "1" );
-		if( opd->wertExistiert( "Ziele" ) )
-			opd->setWert( "Ziele", Text() += (int)*zAnzahl->zText() );
-		else
-			opd->addWert( "Ziele", Text() += (int)*zAnzahl->zText() );
-		if( (int)*nAnzahl->zText() > ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 )
-			nAnzahl->setText( Text() += ( ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 ) );
-		if( (int)*nAnzahl->zText() < 1 )
-			nAnzahl->setText( "1" );
-		if( opd->wertExistiert( "Anhängen" ) )
-			opd->setWert( "Anhängen", Text() += (int)*nAnzahl->zText() );
-		else
-			opd->addWert( "Anhängen", Text() += (int)*nAnzahl->zText() );
-		if( (int)*tempo->zText() < 1 )
-			tempo->setText( "1" );
-		if( (int)*tempo->zText() > 10 )
-			tempo->setText( "10" );
-		if( opd->wertExistiert( "Geschwindigkeit" ) )
-			opd->setWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
-		else
-			opd->addWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
-		if( opd->wertExistiert( "Fortsetzen" ) )
-			opd->setWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
-		else
-			opd->addWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
-		opd->speichern();
-		opd->release();
-		beendet = 1;
-	}
+    breite->doPublicMausEreignis( me );
+    höhe->doPublicMausEreignis( me );
+    zAnzahl->doPublicMausEreignis( me );
+    nAnzahl->doPublicMausEreignis( me );
+    tempo->doPublicMausEreignis( me );
+    fortsetzen->doPublicMausEreignis( me );
+    bool vera = me.verarbeitet;
+    abbrechen->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+        beendet = 1;
+    vera = me.verarbeitet;
+    ok->doPublicMausEreignis( me );
+    if( !vera && me.verarbeitet && me.id == ME_RLinks )
+    {
+        InitDatei *opd = new InitDatei( "data/Minigames/Snake/data/optionen.ini" );
+        if( !opd->laden() )
+            DateiPfadErstellen( "data/Minigames/Snake/data/optionen.ini" );
+        if( (int)*breite->zText() > 1000 )
+            breite->setText( "1000" );
+        if( (int)*breite->zText() < 20 )
+            breite->setText( "20" );
+        if( opd->wertExistiert( "Breite" ) )
+            opd->setWert( "Breite", Text() += (int)*breite->zText() );
+        else
+            opd->addWert( "Breite", Text() += (int)*breite->zText() );
+        if( (int)*höhe->zText() > 1000 )
+            höhe->setText( "1000" );
+        if( (int)*höhe->zText() < 20 )
+            höhe->setText( "20" );
+        if( opd->wertExistiert( "Höhe" ) )
+            opd->setWert( "Höhe", Text() += (int)*höhe->zText() );
+        else
+            opd->addWert( "Höhe", Text() += (int)*höhe->zText() );
+        if( (int)*zAnzahl->zText() > ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 )
+            zAnzahl->setText( Text() += ( ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 ) );
+        if( (int)*zAnzahl->zText() < 1 )
+            zAnzahl->setText( "1" );
+        if( opd->wertExistiert( "Ziele" ) )
+            opd->setWert( "Ziele", Text() += (int)*zAnzahl->zText() );
+        else
+            opd->addWert( "Ziele", Text() += (int)*zAnzahl->zText() );
+        if( (int)*nAnzahl->zText() > ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 )
+            nAnzahl->setText( Text() += ( ( (int)*breite->zText() * (int)*höhe->zText() ) / 100 ) );
+        if( (int)*nAnzahl->zText() < 1 )
+            nAnzahl->setText( "1" );
+        if( opd->wertExistiert( "Anhängen" ) )
+            opd->setWert( "Anhängen", Text() += (int)*nAnzahl->zText() );
+        else
+            opd->addWert( "Anhängen", Text() += (int)*nAnzahl->zText() );
+        if( (int)*tempo->zText() < 1 )
+            tempo->setText( "1" );
+        if( (int)*tempo->zText() > 10 )
+            tempo->setText( "10" );
+        if( opd->wertExistiert( "Geschwindigkeit" ) )
+            opd->setWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
+        else
+            opd->addWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
+        if( opd->wertExistiert( "Fortsetzen" ) )
+            opd->setWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
+        else
+            opd->addWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
+        opd->speichern();
+        opd->release();
+        beendet = 1;
+    }
 }
 
 void MenüOptionen::doTastaturEreignis( TastaturEreignis &te )
 {
-	breite->doTastaturEreignis( te );
-	höhe->doTastaturEreignis( te );
-	zAnzahl->doTastaturEreignis( te );
-	nAnzahl->doTastaturEreignis( te );
-	tempo->doTastaturEreignis( te );
+    breite->doTastaturEreignis( te );
+    höhe->doTastaturEreignis( te );
+    zAnzahl->doTastaturEreignis( te );
+    nAnzahl->doTastaturEreignis( te );
+    tempo->doTastaturEreignis( te );
 }
 
 bool MenüOptionen::tick( double tickVal )
 {
-	bool ret = breite->tick( tickVal );
-	ret |= höhe->tick( tickVal );
-	ret |= zAnzahl->tick( tickVal );
-	ret |= nAnzahl->tick( tickVal );
-	ret |= tempo->tick( tickVal );
-	ret |= fortsetzen->tick( tickVal );
-	ret |= abbrechen->tick( tickVal );
-	ret |= ok->tick( tickVal );
-	return ret;
+    bool ret = breite->tick( tickVal );
+    ret |= höhe->tick( tickVal );
+    ret |= zAnzahl->tick( tickVal );
+    ret |= nAnzahl->tick( tickVal );
+    ret |= tempo->tick( tickVal );
+    ret |= fortsetzen->tick( tickVal );
+    ret |= abbrechen->tick( tickVal );
+    ret |= ok->tick( tickVal );
+    return ret;
 }
 
 void MenüOptionen::render( Bild &zRObj )
 {
-	breiteT->render( zRObj );
-	breite->render( zRObj );
-	höheT->render( zRObj );
-	höhe->render( zRObj );
-	zAnzahlT->render( zRObj );
-	zAnzahl->render( zRObj );
-	nAnzahlT->render( zRObj );
-	nAnzahl->render( zRObj );
-	tempoT->render( zRObj );
-	tempo->render( zRObj );
-	fortsetzen->render( zRObj );
-	abbrechen->render( zRObj );
-	ok->render( zRObj );
+    breiteT->render( zRObj );
+    breite->render( zRObj );
+    höheT->render( zRObj );
+    höhe->render( zRObj );
+    zAnzahlT->render( zRObj );
+    zAnzahl->render( zRObj );
+    nAnzahlT->render( zRObj );
+    nAnzahl->render( zRObj );
+    tempoT->render( zRObj );
+    tempo->render( zRObj );
+    fortsetzen->render( zRObj );
+    abbrechen->render( zRObj );
+    ok->render( zRObj );
 }
 
 // constant
 bool MenüOptionen::istBeendet() const
 {
-	return beendet;
-}
-
-// Reference Counting
-MenüOptionen *MenüOptionen::getThis()
-{
-	ref++;
-	return this;
-}
-
-MenüOptionen *MenüOptionen::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return beendet;
 }
 
 
 // Inhalt der Menü Klasse aus Menü.h
 // Konstruktor
-Menü::Menü( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient )
+Menü::Menü( UIInit &uiFactory, KSGClient::MinigameServerClient *klient )
+    : ReferenceCounter()
 {
-	spielen = initKnopf( 350, 180, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Spielen" );
-	spielenF = new MenüSpiel( zSchrift, zScreen, klient->getThis() );
-	optionen = initKnopf( 350, 220, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Optionen" );
-	optionenF = new MenüOptionen( zSchrift, zScreen );
-	statistik = initKnopf( 350, 260, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Statistik" );
-	statistikF = new MenüStatistik( zSchrift, zScreen, klient );
-	beenden = initKnopf( 350, 300, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
-	ram = new LRahmen();
-	ram->setFarbe( 0xFFFFFFFF );
-	beendet = 0;
-	status = 0;
-	LTDBDatei *bgd = new LTDBDatei();
-	bgd->setDatei( new Text( "data/Minigames/Snake/bilder/hintergrund.ltdb" ) );
-	bgd->leseDaten( 0 );
-	hintergrund = bgd->laden( 0, new Text( "bg.jpg" ) );
-	bgd->release();
-	ref = 1;
+    spielen = initKnopf( 350, 180, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Spielen" );
+    spielenF = new MenüSpiel( uiFactory, dynamic_cast<KSGClient::MinigameServerClient *>( klient->getThis() ) );
+    optionen = initKnopf( 350, 220, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Optionen" );
+    optionenF = new MenüOptionen( uiFactory );
+    statistik = initKnopf( 350, 260, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Statistik" );
+    statistikF = new MenüStatistik( uiFactory, klient );
+    beenden = initKnopf( 350, 300, 100, 20, uiFactory, Knopf::Style::Sichtbar, "Beenden" );
+    ram = new LRahmen();
+    ram->setFarbe( 0xFFFFFFFF );
+    beendet = 0;
+    status = 0;
+    LTDBDatei *bgd = new LTDBDatei();
+    bgd->setDatei( new Text( "data/Minigames/Snake/bilder/hintergrund.ltdb" ) );
+    bgd->leseDaten( 0 );
+    hintergrund = bgd->laden( 0, new Text( "bg.jpg" ) );
+    bgd->release();
 }
 
 // Destruktor
 Menü::~Menü()
 {
-	spielen->release();
-	spielenF->release();
-	optionen->release();
-	optionenF->release();
-	statistik->release();
-	statistikF->release();
-	beenden->release();
-	if( hintergrund )
-		hintergrund->release();
-	ram->release();
+    spielen->release();
+    spielenF->release();
+    optionen->release();
+    optionenF->release();
+    statistik->release();
+    statistikF->release();
+    beenden->release();
+    if( hintergrund )
+        hintergrund->release();
+    ram->release();
 }
 
 // nicht constant
 void Menü::reset()
 {
-	status = 0;
-	beendet = 0;
+    status = 0;
+    beendet = 0;
 }
 
 void Menü::doPublicMausEreignis( MausEreignis &me )
 {
-	switch( status )
-	{
-	case 0:
-		if( 1 )
-		{
-			bool vera = me.verarbeitet;
-			spielen->doPublicMausEreignis( me );
-			if( !vera && me.verarbeitet && me.id == ME_RLinks )
-			{
-				spielenF->reset();
-				status = 3;
-			}
-			vera = me.verarbeitet;
-			optionen->doPublicMausEreignis( me );
-			if( !vera && me.verarbeitet && me.id == ME_RLinks )
-			{
-				optionenF->reset();
-				status = 1;
-			}
-			vera = me.verarbeitet;
-			statistik->doPublicMausEreignis( me );
-			if( !vera && me.verarbeitet && me.id == ME_RLinks )
-			{
-				statistikF->reset();
-				status = 2;
-			}
-			vera = me.verarbeitet;
-			beenden->doPublicMausEreignis( me );
-			if( !vera && me.verarbeitet && me.id == ME_RLinks )
-				beendet = 1;
-		}
-		break;
-	case 1:
-		optionenF->doPublicMausEreignis( me );
-		break;
-	case 2:
-		statistikF->doPublicMausEreignis( me );
-		break;
-	case 3:
-		spielenF->doPublicMausEreignis( me );
-	}
+    switch( status )
+    {
+    case 0:
+        if( 1 )
+        {
+            bool vera = me.verarbeitet;
+            spielen->doPublicMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+            {
+                spielenF->reset();
+                status = 3;
+            }
+            vera = me.verarbeitet;
+            optionen->doPublicMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+            {
+                optionenF->reset();
+                status = 1;
+            }
+            vera = me.verarbeitet;
+            statistik->doPublicMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+            {
+                statistikF->reset();
+                status = 2;
+            }
+            vera = me.verarbeitet;
+            beenden->doPublicMausEreignis( me );
+            if( !vera && me.verarbeitet && me.id == ME_RLinks )
+                beendet = 1;
+        }
+        break;
+    case 1:
+        optionenF->doPublicMausEreignis( me );
+        break;
+    case 2:
+        statistikF->doPublicMausEreignis( me );
+        break;
+    case 3:
+        spielenF->doPublicMausEreignis( me );
+    }
 }
 
 void Menü::doTastaturEreignis( TastaturEreignis &te )
 {
-	if( status == 1 )
-		optionenF->doTastaturEreignis( te );
-	if( status == 3 )
-		spielenF->doTastaturEreignis( te );
+    if( status == 1 )
+        optionenF->doTastaturEreignis( te );
+    if( status == 3 )
+        spielenF->doTastaturEreignis( te );
 }
 
 bool Menü::tick( double z )
 {
-	switch( status )
-	{
-	case 0:
-		if( 1 )
-		{
-			bool ret = spielen->tick( z );
-			ret |= statistik->tick( z );
-			ret |= optionen->tick( z );
-			ret |= beenden->tick( z );
-			return ret;
-		}
-	case 1:
-		if( optionenF->istBeendet() )
-		{
-			status = 0;
-			return 1;
-		}
-		return optionenF->tick( z );
-	case 2:
-		if( statistikF->istBeendet() )
-		{
-			status = 0;
-			return 1;
-		}
-		return statistikF->tick( z );
-	case 3:
-		if( spielenF->istBeendet() )
-		{
-			status = 0;
-			return 1;
-		}
-		return spielenF->tick( z );
-	}
-	return 0;
+    switch( status )
+    {
+    case 0:
+        if( 1 )
+        {
+            bool ret = spielen->tick( z );
+            ret |= statistik->tick( z );
+            ret |= optionen->tick( z );
+            ret |= beenden->tick( z );
+            return ret;
+        }
+    case 1:
+        if( optionenF->istBeendet() )
+        {
+            status = 0;
+            return 1;
+        }
+        return optionenF->tick( z );
+    case 2:
+        if( statistikF->istBeendet() )
+        {
+            status = 0;
+            return 1;
+        }
+        return statistikF->tick( z );
+    case 3:
+        if( spielenF->istBeendet() )
+        {
+            status = 0;
+            return 1;
+        }
+        return spielenF->tick( z );
+    }
+    return 0;
 }
 
 void Menü::render( Bild &zRObj )
 {
-	if( status != 3 && hintergrund && ( status != 2 || !statistikF->istWiederhohlung() ) )
-		zRObj.drawBild( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), *hintergrund );
-	switch( status )
-	{
-	case 0:
-		ram->setPosition( 300, 170 );
-		ram->setSize( 200, 160 );
-		zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
-		ram->render( zRObj );
-		spielen->render( zRObj );
-		statistik->render( zRObj );
-		optionen->render( zRObj );
-		beenden->render( zRObj );
-		break;
-	case 1:
-		ram->setPosition( 300, 110 );
-		ram->setSize( 200, 280 );
-		zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
-		ram->render( zRObj );
-		optionenF->render( zRObj );
-		break;
-	case 2:
-		if( hintergrund && !statistikF->istWiederhohlung() )
-			zRObj.alphaRegion( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), 0xD0000000 );
-		statistikF->render( zRObj );
-		break;
-	case 3:
-		spielenF->render( zRObj );
-	}
+    if( status != 3 && hintergrund && ( status != 2 || !statistikF->istWiederhohlung() ) )
+        zRObj.drawBild( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), *hintergrund );
+    switch( status )
+    {
+    case 0:
+        ram->setPosition( 300, 170 );
+        ram->setSize( 200, 160 );
+        zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
+        ram->render( zRObj );
+        spielen->render( zRObj );
+        statistik->render( zRObj );
+        optionen->render( zRObj );
+        beenden->render( zRObj );
+        break;
+    case 1:
+        ram->setPosition( 300, 110 );
+        ram->setSize( 200, 280 );
+        zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
+        ram->render( zRObj );
+        optionenF->render( zRObj );
+        break;
+    case 2:
+        if( hintergrund && !statistikF->istWiederhohlung() )
+            zRObj.alphaRegion( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), 0xD0000000 );
+        statistikF->render( zRObj );
+        break;
+    case 3:
+        spielenF->render( zRObj );
+    }
 }
 
 // constant
 bool Menü::istBeendet() const
 {
-	return beendet;
-}
-
-// Reference Counting
-Menü *Menü::getThis()
-{
-	ref++;
-	return this;
-}
-
-Menü *Menü::release()
-{
-	ref--;
-	if( !ref )
-		delete this;
-	return 0;
+    return beendet;
 }

+ 108 - 132
Snake/Menü.h

@@ -5,63 +5,56 @@
 #include <Tabelle.h>
 #include <Diagramm.h>
 #include <AuswahlBox.h>
+#include <UIInitialization.h>
 #include "Map.h"
 
 using namespace Framework;
 
-class MenüVerloren
+class MenüVerloren : public virtual ReferenceCounter
 {
 private:
-	Rahmen *ram;
-	TextFeld *verloren;
-	Knopf *neu;
-	Knopf *beenden;
-	int ref;
+    Rahmen *ram;
+    TextFeld *verloren;
+    Knopf *neu;
+    Knopf *beenden;
 
 public:
-	// Kontruktor
-	MenüVerloren( Schrift *zSchrift );
-	// Destruktor
-	~MenüVerloren();
-	// nicht constant
-	int doPublicMausEreignis( MausEreignis &me );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// Reference Counting
-	MenüVerloren *getThis();
-	MenüVerloren *release();
+    // Kontruktor
+    MenüVerloren( UIInit &uiFactory );
+    // Destruktor
+    ~MenüVerloren();
+    // nicht constant
+    int doPublicMausEreignis( MausEreignis &me );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
 };
 
-class MenüSpiel
+class MenüSpiel : public virtual ReferenceCounter
 {
 private:
-	TextFeld *scoreT;
-	Knopf *beenden;
-	Map *map;
-	MenüVerloren *verloren;
+    TextFeld *scoreT;
+    Knopf *beenden;
+    Map *map;
+    MenüVerloren *verloren;
     double timePuffer;
-	bool beendet;
-	int ref;
+    bool beendet;
 
 public:
-	// Konstruktor
-	MenüSpiel( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient );
-	// Destruktor
-	~MenüSpiel();
-	// nicht constant
-	void reset();
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-	bool istBeendet() const;
-	// Reference Counting
-	MenüSpiel *getThis();
-	MenüSpiel *release();
+    // Konstruktor
+    MenüSpiel( UIInit &uiFactory, KSGClient::MinigameServerClient *klient );
+    // Destruktor
+    ~MenüSpiel();
+    // nicht constant
+    void reset();
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    bool istBeendet() const;
 };
 
-class MenüWiederhohlung
+class MenüWiederhohlung : public virtual ReferenceCounter
 {
 private:
     TextFeld *scoreT;
@@ -72,11 +65,10 @@ private:
     double nextTime;
     bool beendet;
     double timePuffer;
-    int ref;
 
 public:
     // Konstruktor
-    MenüWiederhohlung( Schrift *zSchrift, Bildschirm *zScreen, Datei *datei, Text *zOptionen );
+    MenüWiederhohlung( UIInit &uiFactory, Datei *datei, Text *zOptionen );
     // Destruktor
     ~MenüWiederhohlung();
     // nicht constant
@@ -86,120 +78,104 @@ public:
     void render( Bild &zRObj );
     // constant
     bool istBeendet() const;
-    // Reference Counting
-    MenüWiederhohlung *getThis();
-    MenüWiederhohlung *release();
 };
 
-class MenüStatistik
+class MenüStatistik : public virtual ReferenceCounter
 {
 private:
-	TextFeld *ansichtT;
-	AuswahlBox *ansicht;
-	KontrollKnopf *optionen;
-	ObjTabelle *gesammtT;
-	ObjTabelle *optionenT;
+    TextFeld *ansichtT;
+    AuswahlBox *ansicht;
+    KontrollKnopf *optionen;
+    ObjTabelle *gesammtT;
+    ObjTabelle *optionenT;
     ObjTabelle *worldBestT;
-	LDiag *gesammtD;
-	LDiag *optionenD;
-	Knopf *releasen;
-	Knopf *zurück;
-	Schrift *schrift;
+    LDiag *gesammtD;
+    LDiag *optionenD;
+    Knopf *releasen;
+    Knopf *zurück;
+    UIInit uiFactory;
     TextRenderer *tr;
     KSGClient::MinigameServerClient *klient;
     MenüWiederhohlung *wiederH;
-    Bildschirm *screen;
     bool asyncFinished;
-	bool beendet;
-	int ref = 1;
+    bool beendet;
 
 public:
-	// Konstruktor
-	MenüStatistik( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient );
-	// Destruktor
-	~MenüStatistik();
-	// nicht constant
-	void reset();
-	void doPublicMausEreignis( MausEreignis &me );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-	bool istBeendet() const;
+    // Konstruktor
+    MenüStatistik( UIInit &uiFactory, KSGClient::MinigameServerClient *klient );
+    // Destruktor
+    ~MenüStatistik();
+    // nicht constant
+    void reset();
+    void doPublicMausEreignis( MausEreignis &me );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    bool istBeendet() const;
     bool istWiederhohlung() const;
-	// Reference Counting
-	MenüStatistik *getThis();
-	MenüStatistik *release();
 };
 
-class MenüOptionen
+class MenüOptionen : public virtual ReferenceCounter
 {
 private:
-	TextFeld *breiteT;
-	TextFeld *breite;
-	TextFeld *höheT;
-	TextFeld *höhe;
-	TextFeld *zAnzahlT;
-	TextFeld *zAnzahl;
-	TextFeld *nAnzahlT;
-	TextFeld *nAnzahl;
-	TextFeld *tempoT;
-	TextFeld *tempo;
-	KontrollKnopf *fortsetzen;
-	Knopf *abbrechen;
-	Knopf *ok;
-	bool beendet;
-	int ref;
+    TextFeld *breiteT;
+    TextFeld *breite;
+    TextFeld *höheT;
+    TextFeld *höhe;
+    TextFeld *zAnzahlT;
+    TextFeld *zAnzahl;
+    TextFeld *nAnzahlT;
+    TextFeld *nAnzahl;
+    TextFeld *tempoT;
+    TextFeld *tempo;
+    KontrollKnopf *fortsetzen;
+    Knopf *abbrechen;
+    Knopf *ok;
+    bool beendet;
 
 public:
-	// Konstruktor
-	MenüOptionen( Schrift *zSchrift, Bildschirm *zScreen );
-	// Destruktor
-	~MenüOptionen();
-	// nicht constant
-	void reset();
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te );
-	bool tick( double tickVal );
-	void render( Bild &zRObj );
-	// constant
-	bool istBeendet() const;
-	// Reference Counting
-	MenüOptionen *getThis();
-	MenüOptionen *release();
+    // Konstruktor
+    MenüOptionen( UIInit &uiFactory );
+    // Destruktor
+    ~MenüOptionen();
+    // nicht constant
+    void reset();
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double tickVal );
+    void render( Bild &zRObj );
+    // constant
+    bool istBeendet() const;
 };
 
-class Menü
+class Menü : public virtual ReferenceCounter
 {
 private:
-	Knopf *spielen;
-	MenüSpiel *spielenF;
-	Knopf *optionen;
-	MenüOptionen *optionenF;
-	Knopf *statistik;
-	MenüStatistik *statistikF;
-	Knopf *beenden;
-	Bild *hintergrund;
-	Rahmen *ram;
-	bool beendet;
-	int status;
-	int ref;
+    Knopf *spielen;
+    MenüSpiel *spielenF;
+    Knopf *optionen;
+    MenüOptionen *optionenF;
+    Knopf *statistik;
+    MenüStatistik *statistikF;
+    Knopf *beenden;
+    Bild *hintergrund;
+    Rahmen *ram;
+    bool beendet;
+    int status;
 
 public:
-	// Konstruktor
-	Menü( Schrift *zSchrift, Bildschirm *zScreen, KSGClient::MinigameServerClient *klient );
-	// Destruktor
-	~Menü();
-	// nicht constant#
-	void reset();
-	void doPublicMausEreignis( MausEreignis &me );
-	void doTastaturEreignis( TastaturEreignis &te );
-	bool tick( double z );
-	void render( Bild &zRObj );
-	// constant
-	bool istBeendet() const;
-	// Reference Counting
-	Menü *getThis();
-	Menü *release();
+    // Konstruktor
+    Menü( UIInit &uiFactory, KSGClient::MinigameServerClient *klient );
+    // Destruktor
+    ~Menü();
+    // nicht constant#
+    void reset();
+    void doPublicMausEreignis( MausEreignis &me );
+    void doTastaturEreignis( TastaturEreignis &te );
+    bool tick( double z );
+    void render( Bild &zRObj );
+    // constant
+    bool istBeendet() const;
 };
 
 #endif