|
@@ -0,0 +1,774 @@
|
|
|
+#include "Spiel.h"
|
|
|
+#include <time.h>
|
|
|
+#include "KartenLeser.h"
|
|
|
+#include "Statistik.h"
|
|
|
+#include <DateiSystem.h>
|
|
|
+#ifdef WIN32
|
|
|
+#include <random>
|
|
|
+#else
|
|
|
+#include <math.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#define Sleep( x ) usleep( (x) * 1000 )
|
|
|
+#endif
|
|
|
+
|
|
|
+#define TICK 0.03333333
|
|
|
+
|
|
|
+// Inhalt der Spiel Klasse aus Spiel.h
|
|
|
+// Konstruktor
|
|
|
+Spiel::Spiel()
|
|
|
+{
|
|
|
+ stat = new Statistik();
|
|
|
+ score = new Bestenliste();
|
|
|
+ teams = new Array< int >();
|
|
|
+ teamAnzahl = 0;
|
|
|
+ psqldb = 0;
|
|
|
+ spieler = new RCArray< Spieler >();
|
|
|
+ spielerAnzahl = 0;
|
|
|
+ spielId = 0;
|
|
|
+ karte = new Karte();
|
|
|
+ isRunning = 0;
|
|
|
+ sts = 0;
|
|
|
+ InitializeCriticalSection( &cs );
|
|
|
+ rundenAnzahl = 0;
|
|
|
+ spielZeit = 0;
|
|
|
+ ende = 1;
|
|
|
+ ref = 1;
|
|
|
+}
|
|
|
+
|
|
|
+// Destruktor
|
|
|
+Spiel::~Spiel()
|
|
|
+{
|
|
|
+ teams->release();
|
|
|
+ stat->release();
|
|
|
+ score->release();
|
|
|
+ spieler->release();
|
|
|
+ if( psqldb )
|
|
|
+ psqldb->release();
|
|
|
+ karte->release();
|
|
|
+ if( sts )
|
|
|
+ sts->release();
|
|
|
+ DeleteCriticalSection( &cs );
|
|
|
+}
|
|
|
+
|
|
|
+// nicht constant
|
|
|
+void Spiel::setPSQLK( SSDatenbankV *psqldb )
|
|
|
+{
|
|
|
+ if( this->psqldb )
|
|
|
+ this->psqldb->release();
|
|
|
+ this->psqldb = psqldb;
|
|
|
+ stat->setPSQLDB( psqldb->getThis() );
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setSpielId( int id )
|
|
|
+{
|
|
|
+ spielId = id;
|
|
|
+ stat->setSpielId( id );
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setKarteId( int karteId )
|
|
|
+{
|
|
|
+ this->karteId = karteId;
|
|
|
+ karte->setKarteId( karteId );
|
|
|
+ stat->setKarteId( karteId );
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setTempPfad( char *pfad )
|
|
|
+{
|
|
|
+ mapPfad = pfad;
|
|
|
+ mapPfad += "/";
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setAccounts( int anzahl, Array< int > *zAccounts )
|
|
|
+{
|
|
|
+ spielerAnzahl = anzahl;
|
|
|
+ for( int i = 0; i < anzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = new Spieler();
|
|
|
+ tmp->setAccountId( zAccounts->hat( i ) ? zAccounts->get( i ) : 0 );
|
|
|
+ spieler->set( tmp, i );
|
|
|
+ }
|
|
|
+ stat->setSpieler( spielerAnzahl, spieler );
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setKlients( int anzahl, RCArray< SSKlientV > *zKlients )
|
|
|
+{
|
|
|
+ for( int i = 0; i < anzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp )
|
|
|
+ tmp->setKlient( new Klient( zKlients->get( i ) ) );
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::setSpielerNummern( int anzahl, Array< int > *spielerNummern )
|
|
|
+{
|
|
|
+ if( !sts )
|
|
|
+ {
|
|
|
+ sts = new SpielerTeamStruktur();
|
|
|
+ KartenLeser *reader = new KartenLeser( karteId, psqldb->getThis(), mapPfad );
|
|
|
+ reader->ladeSpielerTeamStruktur( sts );
|
|
|
+ reader->release();
|
|
|
+ stat->setTeamNamen( sts->teamName->getThis() );
|
|
|
+ }
|
|
|
+ for( int i = 0; i < anzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp )
|
|
|
+ {
|
|
|
+ int sNum = spielerNummern->hat( i ) ? spielerNummern->get( i ) : 0;
|
|
|
+ tmp->setSpielerNummer( sNum );
|
|
|
+ tmp->setSpielerFarbe( sts->spielerFarbe->hat( sNum ) ? sts->spielerFarbe->get( sNum ) : 0 );
|
|
|
+ int team = 0;
|
|
|
+ int von = 0;
|
|
|
+ int bis = 0;
|
|
|
+ for( int j = 0; j < sts->teamAnzahl; j++ )
|
|
|
+ {
|
|
|
+ bis = von + ( sts->teamSize->hat( j ) ? sts->teamSize->get( j ) : 0 );
|
|
|
+ if( sNum >= von && sNum < bis )
|
|
|
+ {
|
|
|
+ team = j;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ von = bis;
|
|
|
+ }
|
|
|
+ tmp->setTeam( team );
|
|
|
+ tmp->setTeamFarbe( sts->teamFarbe->hat( team ) ? sts->teamFarbe->get( team ) : 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::klientOffline( int accountId )
|
|
|
+{
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i )->getAccountId() == accountId )
|
|
|
+ spieler->z( i )->offline();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::klientOnline( int accountId, SSKlientV *zKlient )
|
|
|
+{
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i )->getAccountId() == accountId )
|
|
|
+ {
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ Spieler *s = spieler->z( i );
|
|
|
+ s->online( zKlient );
|
|
|
+ Klient *tmp = spieler->z( i )->zKlient();
|
|
|
+ tmp->sendeSpielerNummer( s->getSpielerNummer(), 0 );
|
|
|
+ tmp->sendeInitSpieler( spielerAnzahl, spieler, 0 );
|
|
|
+ tmp->sendeKammeraSize( 400, 400, 0 );
|
|
|
+ tmp->sendeKartenSize( karte->getBreite(), karte->getHeight(), 0 );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *z = spieler->z( i );
|
|
|
+ if( z )
|
|
|
+ {
|
|
|
+ tmp->sendeSpielerPosition( z, 0 );
|
|
|
+ tmp->sendeSpielerGeschwindigkeit( z, 0 );
|
|
|
+ tmp->sendeSpielerWendigkeit( z, 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::nachricht( int accountId, int len, char *bytes )
|
|
|
+{
|
|
|
+ if( !isRunning || ende )
|
|
|
+ return;
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ if( ende )
|
|
|
+ {
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ char *msgBeg = bytes;
|
|
|
+ int msgLen = len;
|
|
|
+ int msgAccount = accountId;
|
|
|
+ bool saveMSG = 1;
|
|
|
+ len--;
|
|
|
+ switch( *bytes )
|
|
|
+ {
|
|
|
+ case 0: // Spieler drückt T_Links
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->getAccountId() == accountId )
|
|
|
+ {
|
|
|
+ if( !tmp->istAmLeben() )
|
|
|
+ break;
|
|
|
+ if( tmp->machtKurve( 0 ) )
|
|
|
+ {
|
|
|
+ saveMSG = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ tmp->setLKurve( 1 );
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 1, spielZeit );
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 1: // Spieler lässt T_Links los
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->getAccountId() == accountId )
|
|
|
+ {
|
|
|
+ if( !tmp->istAmLeben() )
|
|
|
+ break;
|
|
|
+ if( !tmp->machtKurve( 0 ) )
|
|
|
+ {
|
|
|
+ saveMSG = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ tmp->setLKurve( 0 );
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 2, spielZeit );
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2: // Spieler drückt T_Rechts
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->getAccountId() == accountId )
|
|
|
+ {
|
|
|
+ if( !tmp->istAmLeben() )
|
|
|
+ break;
|
|
|
+ if( tmp->machtKurve( 1 ) )
|
|
|
+ {
|
|
|
+ saveMSG = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ tmp->setRKurve( 1 );
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 3, spielZeit );
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3: // Spieler lässt T_Rechts los
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->getAccountId() == accountId )
|
|
|
+ {
|
|
|
+ if( !tmp->istAmLeben() )
|
|
|
+ break;
|
|
|
+ if( !tmp->machtKurve( 1 ) )
|
|
|
+ {
|
|
|
+ saveMSG = 0;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ tmp->setRKurve( 0 );
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ s->zKlient()->sendeSpielerKurve( tmp->getSpielerNummer(), 4, spielZeit );
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 4: // chat Nachricht
|
|
|
+ if( 1 )
|
|
|
+ {
|
|
|
+ bytes++;
|
|
|
+ Text *txt = psqldb->getAccountRufName( accountId );
|
|
|
+ txt->append( ": " );
|
|
|
+ txt->append( bytes, len );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->zKlient() )
|
|
|
+ tmp->zKlient()->sendeChatNachricht( txt->getText(), spielZeit );
|
|
|
+ }
|
|
|
+ txt->release();
|
|
|
+ len = 0;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ saveMSG = 0;
|
|
|
+ }
|
|
|
+ if( len )
|
|
|
+ {
|
|
|
+ // error
|
|
|
+ }
|
|
|
+ if( log && log->istOffen() && saveMSG )
|
|
|
+ {
|
|
|
+ char c = 1;
|
|
|
+ log->schreibe( &c, 1 );
|
|
|
+ int spielerNum = 0;
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->getAccountId() == msgAccount )
|
|
|
+ {
|
|
|
+ spielerNum = tmp->getSpielerNummer();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log->schreibe( (char*)&spielerNum, 4 );
|
|
|
+ short l = (short)msgLen;
|
|
|
+ log->schreibe( (char*)&l, 2 );
|
|
|
+ log->schreibe( msgBeg, l );
|
|
|
+ }
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::tick( double zeit )
|
|
|
+{
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp )
|
|
|
+ {
|
|
|
+ bool amLeben = tmp->istAmLeben();
|
|
|
+ bool lu = tmp->linieIstUnterbrochen();
|
|
|
+ tmp->tick( karte->zMap(), zeit );
|
|
|
+ if( amLeben != tmp->istAmLeben() || lu != tmp->linieIstUnterbrochen() )
|
|
|
+ {
|
|
|
+ if( lu != tmp->linieIstUnterbrochen() )
|
|
|
+ {
|
|
|
+ char c = 1;
|
|
|
+ log->schreibe( &c, 1 );
|
|
|
+ int sNum = tmp->getSpielerNummer();
|
|
|
+ log->schreibe( (char*)&sNum, 4 );
|
|
|
+ short len = 2;
|
|
|
+ log->schreibe( (char*)&len, 2 );
|
|
|
+ c = 5;
|
|
|
+ log->schreibe( &c, 1 );
|
|
|
+ c = (char)tmp->linieIstUnterbrochen();
|
|
|
+ log->schreibe( &c, 1 );
|
|
|
+ }
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ {
|
|
|
+ if( amLeben && !tmp->istAmLeben() )
|
|
|
+ {
|
|
|
+ if( tmp->getKillFarbe() == s->getSpielerFarbe() )
|
|
|
+ s->addKill();
|
|
|
+ s->zKlient()->sendeSpielerTod( tmp, spielZeit );
|
|
|
+ if( s != tmp && s->istAmLeben() )
|
|
|
+ {
|
|
|
+ score->addSpielerPunkt( s->getSpielerNummer(), 1 );
|
|
|
+ s->addPunkte( 1 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if( lu != tmp->linieIstUnterbrochen() )
|
|
|
+ s->zKlient()->sendeLinienUnterbrechung( tmp->getSpielerNummer(), tmp->linieIstUnterbrochen(), spielZeit );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( amLeben && !tmp->istAmLeben() )
|
|
|
+ {
|
|
|
+ int team = tmp->getSpielerTeam();
|
|
|
+ bool teamLebt = 0;
|
|
|
+ for( int k = 0; k < spielerAnzahl; k++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( k ) && spieler->z( k )->getSpielerTeam() == team )
|
|
|
+ teamLebt |= spieler->z( k )->istAmLeben();
|
|
|
+ }
|
|
|
+ if( !teamLebt )
|
|
|
+ {
|
|
|
+ int teamAmLebenAnzahl = 0;
|
|
|
+ for( int k = 0; k < teamAnzahl; k++ )
|
|
|
+ {
|
|
|
+ int t = teams->hat( k ) ? teams->get( k ) : 0;
|
|
|
+ bool amLeben = 0;
|
|
|
+ for( int l = 0; l < spielerAnzahl; l++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( l ) && spieler->z( l )->getSpielerTeam() == t )
|
|
|
+ amLeben |= spieler->z( l )->istAmLeben();
|
|
|
+ }
|
|
|
+ if( amLeben )
|
|
|
+ {
|
|
|
+ teamAmLebenAnzahl++;
|
|
|
+ score->addTeamPunkt( t, 1 );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ score->addTeamPunkt( t, 0 );
|
|
|
+ }
|
|
|
+ if( teamAmLebenAnzahl <= 1 )
|
|
|
+ ende = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Spiel::run()
|
|
|
+{
|
|
|
+ log = new Datei();
|
|
|
+ Text *pfad = new Text( "../spiel log/" );
|
|
|
+ pfad->append( spielId );
|
|
|
+ pfad->append( "/verlauf.ksggl" );
|
|
|
+ log->setDatei( pfad );
|
|
|
+ log->remove();
|
|
|
+ log->erstellen();
|
|
|
+ log->open( Datei::Style::schreiben );
|
|
|
+ time_t t;
|
|
|
+ time( &t );
|
|
|
+ srand( (unsigned int)t );
|
|
|
+ log->schreibe( (char*)&spielerAnzahl, 4 );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->zKlient() )
|
|
|
+ {
|
|
|
+ log->schreibe( (char*)&i, 4 );
|
|
|
+ int sNum = tmp->getSpielerNummer();
|
|
|
+ score->setSpielerPunkte( sNum, 0 );
|
|
|
+ log->schreibe( (char*)&sNum, 4 );
|
|
|
+ tmp->zKlient()->sendeSpielerNummer( sNum, 0 );
|
|
|
+ tmp->zKlient()->sendeInitSpieler( spielerAnzahl, spieler, 0 );
|
|
|
+ int kg = 400;
|
|
|
+ log->schreibe( (char*)&kg, 4 );
|
|
|
+ log->schreibe( (char*)&kg, 4 );
|
|
|
+ int team = tmp->getSpielerTeam();
|
|
|
+ log->schreibe( (char*)&team, 4 );
|
|
|
+ int farbe = tmp->getSpielerFarbe();
|
|
|
+ log->schreibe( (char*)&farbe, 4 );
|
|
|
+ farbe = tmp->getTeamFarbe();
|
|
|
+ log->schreibe( (char*)&farbe, 4 );
|
|
|
+ Text *name = psqldb->getAccountRufName( tmp->getAccountId() );
|
|
|
+ char len = (char)( name ? name->getLength() : 0 );
|
|
|
+ log->schreibe( &len, 1 );
|
|
|
+ if( len )
|
|
|
+ log->schreibe( name->getText(), len );
|
|
|
+ if( name )
|
|
|
+ name->release();
|
|
|
+ name = sts->teamName->z( tmp->getSpielerTeam() );
|
|
|
+ len = (char)( name ? name->getLength() : 0 );
|
|
|
+ log->schreibe( &len, 1 );
|
|
|
+ if( len )
|
|
|
+ log->schreibe( name->getText(), len );
|
|
|
+ tmp->zKlient()->sendeKammeraSize( 400, 400, 0 );
|
|
|
+ bool gefunden = 0;
|
|
|
+ for( int j = 0; j < teamAnzahl; j++ )
|
|
|
+ gefunden |= teams->hat( j ) && teams->get( j ) == tmp->getSpielerTeam();
|
|
|
+ if( !gefunden )
|
|
|
+ {
|
|
|
+ score->setTeamMaxPunkte( tmp->getSpielerTeam(), teamAnzahl * 3 );
|
|
|
+ score->setTeamPunkte( tmp->getSpielerTeam(), ( teamAnzahl * 3 ) / 2 );
|
|
|
+ teams->set( tmp->getSpielerTeam(), teamAnzahl );
|
|
|
+ teamAnzahl++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for( int i = 0; i < teamAnzahl; i++ )
|
|
|
+ {
|
|
|
+ score->setTeamMaxPunkte( teams->hat( i ) ? teams->get( i ) : 0, teamAnzahl * 3 );
|
|
|
+ score->setTeamPunkte( teams->hat( i ) ? teams->get( i ) : 0, ( teamAnzahl * 3 ) / 2 );
|
|
|
+ }
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->zKlient() )
|
|
|
+ {
|
|
|
+ for( int j = 0; j < teamAnzahl; j++ )
|
|
|
+ {
|
|
|
+ int team = teams->hat( j ) ? teams->get( j ) : 0;
|
|
|
+ if( i == 0 )
|
|
|
+ log->schreibe( (char*)&team, 4 );
|
|
|
+ int p = score->getTeamMaxPunkte( team );
|
|
|
+ tmp->zKlient()->sendeTeamMaxPunkte( team, p, 0 );
|
|
|
+ if( i == 0 )
|
|
|
+ log->schreibe( (char*)&p, 4 );
|
|
|
+ p = score->getTeamPunkte( team );
|
|
|
+ tmp->zKlient()->sendeTeamPunkte( team, p, 0 );
|
|
|
+ if( i == 0 )
|
|
|
+ log->schreibe( (char*)&p, 4 );
|
|
|
+ if( sts->teamName->z( team ) )
|
|
|
+ tmp->zKlient()->sendeTeamName( team, sts->teamName->z( team )->getText() );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Array< char > spielerStatus;
|
|
|
+ int gewinner = -1;
|
|
|
+ while( 1 )
|
|
|
+ {
|
|
|
+ rundenAnzahl++;
|
|
|
+ int karteBreite = 400 + ( rand() % ( spielerAnzahl * 50 ) );
|
|
|
+ int karteHeignt = 400 + ( rand() % ( spielerAnzahl * 50 ) );
|
|
|
+ karte->setSize( karteBreite, karteHeignt );
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ log->schreibe( (char*)&karteBreite, 4 );
|
|
|
+ log->schreibe( (char*)&karteHeignt, 4 );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->zKlient() )
|
|
|
+ {
|
|
|
+ tmp->zKlient()->sendeKartenSize( karteBreite, karteHeignt, 0 );
|
|
|
+ double w = 50.0 / 180 * PI;
|
|
|
+ log->schreibe( (char*)&w, 8 );
|
|
|
+ tmp->setWendigkeit( w );
|
|
|
+ tmp->setPosition( 100 + ( rand() % ( karteBreite - 200 ) ), 100 + ( rand() % ( karteHeignt - 200 ) ) );
|
|
|
+ double p = tmp->getX();
|
|
|
+ log->schreibe( (char*)&p, 8 );
|
|
|
+ p = tmp->getY();
|
|
|
+ log->schreibe( (char*)&p, 8 );
|
|
|
+ int grad = rand() % 180 - 90;
|
|
|
+ double xs = sin( grad / 180.0 * PI ) * 30;
|
|
|
+ log->schreibe( (char*)&xs, 8 );
|
|
|
+ double ys = sqrt( 30 * 30 - xs * xs );
|
|
|
+ ys *= ( rand() % 2 > 0 ) ? 1 : -1;
|
|
|
+ log->schreibe( (char*)&ys, 8 );
|
|
|
+ tmp->setGeschwindigkeit( xs, ys );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp )
|
|
|
+ {
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *s = spieler->z( j );
|
|
|
+ if( s && s->zKlient() )
|
|
|
+ {
|
|
|
+ s->zKlient()->sendeSpielerPosition( tmp, 0 );
|
|
|
+ s->zKlient()->sendeSpielerGeschwindigkeit( tmp, 0 );
|
|
|
+ s->zKlient()->sendeSpielerWendigkeit( tmp, 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for( int i = 0; i < teamAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( teams->hat( i ) && !score->istTeamAmLeben( teams->get( i ) ) )
|
|
|
+ {
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( teams->get( i ) );
|
|
|
+ if( tmp )
|
|
|
+ tmp->zKlient()->sendeTeamTod( teams->get( i ), 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ZeitMesser *zeit = new ZeitMesser();
|
|
|
+ zeit->messungStart();
|
|
|
+ isRunning = 1;
|
|
|
+ ende = 0;
|
|
|
+ double ausgleich = 0;
|
|
|
+ spielZeit = 0;
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp && tmp->zKlient() )
|
|
|
+ tmp->zKlient()->sendeStart( 0 );
|
|
|
+ }
|
|
|
+ double rZeit = 0;
|
|
|
+ while( !ende )
|
|
|
+ {
|
|
|
+ zeit->messungEnde();
|
|
|
+ zeit->messungStart();
|
|
|
+ double z = zeit->getSekunden();
|
|
|
+ ausgleich += 1.0 / 25 - z;
|
|
|
+ if( ausgleich > 0 )
|
|
|
+ Sleep( (int)( ausgleich * 1000 ) );
|
|
|
+ rZeit += z;
|
|
|
+ while( spielZeit + TICK < rZeit && !ende )
|
|
|
+ {
|
|
|
+ EnterCriticalSection( &cs );
|
|
|
+ spielZeit += TICK;
|
|
|
+ char c = 0;
|
|
|
+ log->schreibe( &c, 1 );
|
|
|
+ tick( TICK );
|
|
|
+ LeaveCriticalSection( &cs );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ zeit->messungEnde();
|
|
|
+ zeit->release();
|
|
|
+ gewinner = -1;
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i )->istAmLeben() )
|
|
|
+ {
|
|
|
+ gewinner = spieler->z( i )->getSpielerTeam();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( gewinner < 0 )
|
|
|
+ {
|
|
|
+ double sterbeZeit = 0;
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i )->getTodesZeit() >= sterbeZeit )
|
|
|
+ {
|
|
|
+ sterbeZeit = spieler->z( i )->getTodesZeit();
|
|
|
+ gewinner = spieler->z( i )->getSpielerTeam();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ stat->rundenEnde( gewinner, (int)spielZeit, karte->zMap()->getThis() );
|
|
|
+ int winTeamAnzahl = 0;
|
|
|
+ Array< int > *winTeams = new Array< int >();
|
|
|
+ for( int i = 0; i < teamAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( score->hatTeamGewonnen( i ) || rundenAnzahl >= 10 )
|
|
|
+ {
|
|
|
+ winTeams->add( i, winTeamAnzahl );
|
|
|
+ winTeamAnzahl++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( !winTeamAnzahl )
|
|
|
+ {
|
|
|
+ int verloren = 0;
|
|
|
+ int team = -1;
|
|
|
+ for( int i = 0; i < teamAnzahl; i++ )
|
|
|
+ {
|
|
|
+ int t = teams->hat( i ) ? teams->get( i ) : 0;
|
|
|
+ if( !score->getTeamPunkte( t ) )
|
|
|
+ verloren++;
|
|
|
+ else
|
|
|
+ team = t;
|
|
|
+ }
|
|
|
+ if( verloren == teamAnzahl - 1 )
|
|
|
+ {
|
|
|
+ winTeams->add( team, winTeamAnzahl );
|
|
|
+ winTeamAnzahl++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( winTeamAnzahl > 1 )
|
|
|
+ {
|
|
|
+ int p = -1;
|
|
|
+ for( int i = 0; i < winTeamAnzahl; i++ )
|
|
|
+ {
|
|
|
+ int t = winTeams->hat( i ) ? winTeams->get( i ) : 0;
|
|
|
+ if( score->getTeamMaxPunkte( t ) - score->getTeamPunkte( t ) < p || p < 0 )
|
|
|
+ {
|
|
|
+ p = score->getTeamMaxPunkte( t ) - score->getTeamPunkte( t );
|
|
|
+ for( int j = 0; j < winTeamAnzahl; j++ )
|
|
|
+ {
|
|
|
+ int tt = winTeams->hat( j ) ? winTeams->get( j ) : 0;
|
|
|
+ if( score->getTeamMaxPunkte( tt ) - score->getTeamPunkte( tt ) > p )
|
|
|
+ {
|
|
|
+ if( i >= j )
|
|
|
+ i--;
|
|
|
+ score->setTeamPunkte( tt, 0 );
|
|
|
+ winTeams->remove( j );
|
|
|
+ winTeamAnzahl--;
|
|
|
+ j--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( ( !winTeamAnzahl || winTeamAnzahl > 1 ) && teamAnzahl > 1 && rundenAnzahl < 10 )
|
|
|
+ {
|
|
|
+ winTeams->release();
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i ) && spieler->z( i )->zKlient() )
|
|
|
+ {
|
|
|
+ spieler->z( i )->neuRunde( score->getTeamPunkte( spieler->z( i )->getSpielerTeam() ) != 0 );
|
|
|
+ spieler->z( i )->zKlient()->sendeRundenEnde( gewinner, 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for( int i = 5; i >= 0; i-- )
|
|
|
+ {
|
|
|
+ for( int k = 0; k < 10; k++ )
|
|
|
+ {
|
|
|
+ Sleep( 100 );
|
|
|
+ for( int j = 0; j < spielerAnzahl; j++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( j ) && spieler->z( j )->zKlient() )
|
|
|
+ spieler->z( j )->zKlient()->sendeZeitVerbleibend( i, 0 );
|
|
|
+ }
|
|
|
+ if( !i )
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ if( spieler->z( i ) && spieler->z( i )->zKlient() )
|
|
|
+ {
|
|
|
+ if( winTeams->getWertIndex( spieler->z( i )->getSpielerTeam() ) < 0 )
|
|
|
+ {
|
|
|
+ spielerStatus.set( 1, i ); // Datenbank Verloren
|
|
|
+ spieler->z( i )->zKlient()->sendeSpielEnde( 0, 0 );
|
|
|
+ }
|
|
|
+ else if( winTeamAnzahl > 1 )
|
|
|
+ {
|
|
|
+ spielerStatus.set( 5, i ); // Datenbank Unentschieden
|
|
|
+ spieler->z( i )->zKlient()->sendeSpielEnde( 2, 0 );
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ spielerStatus.set( 2, i ); // Datenbank Gewonnen
|
|
|
+ spieler->z( i )->zKlient()->sendeSpielEnde( 1, 0 );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( spieler->z( i ) && ( !spieler->z( i )->zKlient() || !spieler->z( i )->istOnline() ) )
|
|
|
+ spielerStatus.set( 3, i );
|
|
|
+ }
|
|
|
+ winTeams->release();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if( teamAnzahl == 1 )
|
|
|
+ psqldb->setSpielStatusBeendet( spielId, 6 );
|
|
|
+ else
|
|
|
+ psqldb->setSpielStatusBeendet( spielId, 5 );
|
|
|
+ for( int i = 0; i < spielerAnzahl; i++ )
|
|
|
+ {
|
|
|
+ Spieler *tmp = spieler->z( i );
|
|
|
+ if( tmp )
|
|
|
+ {
|
|
|
+ psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) );
|
|
|
+ if( teamAnzahl > 1 )
|
|
|
+ psqldb->addSpielerStatistik( tmp->getAccountId(), spielId );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ log->close();
|
|
|
+ log = log->release();
|
|
|
+ isRunning = 0;
|
|
|
+}
|
|
|
+
|
|
|
+// constant
|
|
|
+StatistikV *Spiel::getStatistik() const
|
|
|
+{
|
|
|
+ return stat->getThis();
|
|
|
+}
|
|
|
+
|
|
|
+// Reference Counting
|
|
|
+SpielKlasse *Spiel::getThis()
|
|
|
+{
|
|
|
+ ref++;
|
|
|
+ return this;
|
|
|
+}
|
|
|
+
|
|
|
+SpielKlasse *Spiel::release()
|
|
|
+{
|
|
|
+ ref--;
|
|
|
+ if( !ref )
|
|
|
+ delete this;
|
|
|
+ return 0;
|
|
|
+}
|