Fehler im Spielablauf
-
Sorry ich meine true zurückgibt.
-
Das Problem ist, dass dann immer der falsche Spieler dran ist (da ja der spieler anhand des counters ermittelt wird)
-
Anfänger56 schrieb:
Das Problem ist, dass dann immer der falsche Spieler dran ist (da ja der spieler anhand des counters ermittelt wird)
Keine Ahnung was in getType() und incrementCounter() passiert.
Jedenfalls entspricht dann der Code nicht mehr dem logischen Ablauf.
-
Also ich hab jetzt das Problem behoben, das beim klicken von belegten Feldern auftrat.
Mein aktueller Code:
// Diese Methode regelt den Spielablauf. Mit dem ersten Klick eines Spielers beginnt das Spiel. // Ist der zweite Spieler der PC, wird automatisch die entsprechende Methode aufgerufen. void __fastcall Controller::onClick(TObject *Sender) { Feld *feld = NULL; //Temporärer Speicher für Felder feld = dynamic_cast<Feld*>(Sender); //Sender-Objekt wird zu Feld-Objekt gecastet if(this->isFinished()) //Falls das Spiel beendet wurde, wird abgebrochen { return; //Abbrechen } if(feld != NULL && !feld->isEmpty()) //Falls der Spieler ein Mensch ist, ist feld != NULL { //Wenn dieses Feld dann auch nicht leer ist, return; //Wird die Methode abgebrochen, da nur leere } //Felder angeklickt werden dürfen this->refreshStatus(); this->incrementCounter(); //Sollte der aktuelle Spieler der PC sein, muss der Zug des PCs mit der Methode zugPC ausgeführt werden if(this->getCurrentPlayer()->getType() == "Computer" && !this->isFinished()) { //Da diese Methode unter Umständen mehrere Sekunden nicht verlassen wird, //muss Windows alle Nachrichten an dieses Fenster verarbeiten, um //alle Veränderungen darzustellen. Application->ProcessMessages(); //Um dem Menschlichen Auge Zeit zu geben, wartet der PC 300ms vor seinem Zug Sleep(300); //Der PC führt den Zug aus this->zugPC(); } //Der aktuelle Spieler ist kein PC, sondern ein Mensch. Klick wird ausgewertet else if(this->getCurrentPlayer()->getType() == "Mensch" && !this->isFinished()) { if(feld->isEmpty()) //Man darf nur leere Felder anklicken { feld->setColor(this->getCurrentPlayer()->getColor()); //Angeklicktes Feld einfärben feld->setPlayer(this->getCurrentPlayer()); //Besitzer des Felds eintragen } } else { ShowMessage("Der Spielertyp des aktuellen Spielers ist undefiniert. Spielabbruch"); this->setFinished(true); } this->searchWinner(); //Schauen, ob es einen Gewinner gibt / Unentschieden /* Diese Stelle ist sehr wichtig für den Fall, dass ein Computerspieler an der Reihe ist. Der PC löst nämlich kein onClick-Event aus, deshalb machen wir das hier manuell. */ if(this->getNextPlayer()->getType() == "Computer" && !this->isFinished()) { //Hier wird das onClick-Event manuell ausgelöst (als ob der PC geklickt hätte) this->onClick(NULL); //NULL, weil der PC nichts angeklickt hat } }
void Controller::refreshStatus() { Application->ProcessMessages(); this->gui->setStatusMessage("Spieler '" + this->getCurrentPlayer()->getName() + "' ist dran!"); this->gui->setSpielerfarbeVorschau(this->getCurrentPlayer()->getColor()); Application->ProcessMessages(); }
void Controller::incrementCounter() { this->counter++; this->gui->showSpielzuege(this->counter); }
Aber wenn ich einen Mensch gegen den PC spielen lasse, steht immer dran "Spieler 2(Mensch)" ist dran. Dabei ist es egal, ob Mensch Spieler 1 oder Spieler 2 ist.
Wenn ich 2 Menschen gegeneinander spielen lasse, steht abwechselt "Spieler 1 ist dran" und "Spieler 2 ist dran" im Status.
Lasse ich 2 Computer gegeneinadner spielen, geht es ebenfalls, wie es sein soll.Es sieht also so aus, als ob das Problem nur besteht, wenn 2 unterschiedliche Typen gegeneinander spielen.
Ich kann aber mal wieder keinen Fehler im Code erkennen.
Der Zähler wird nur einmal erhöht, der Counter nur einmal inkrementiert.Übrigens habe ich die Abbruchsbedingung mit isEmpty() jetzt ganz nach oben verlegt. Aber das hat mit dem Problem nichts zu tun.
Bin über Ideen dankbar!
Simon
-
Kann es sein, dass es zu Problemen führt, dass ich 2 verschiedene Datentypen in einem Array habe?
this->spieler[0] = new Computer; this->spieler[0]->setName("1: "+this->spieler[0]->getType()); this->spieler[0]->setColor(clBlue); this->spieler[1] = new Mensch; this->spieler[1]->setColor(clRed); this->spieler[1]->setName("2: "+this->spieler[1]->getType());
this->spieler ist vom Typ Spieler* [2]
Mensch und Computer sind von Spieler* abgeleitet.
-
Das ist kein Problem sofern du richtig abgeleitet hast. Sind die aufgerufenen Funktionen virtual?
Was genau macht getCurrentPlayer()?
-
Hi,
nur die Funktion getType ist virtual:
Spieler:
class Spieler { protected: AnsiString name; TColor color; public: Spieler(AnsiString name) { this->setName(name); this->color; } void setName(AnsiString name); AnsiString getName(); void setColor(TColor); TColor getColor(); virtual AnsiString getType() = 0; }; void Spieler::setName(AnsiString n) { this->name = n; } AnsiString Spieler::getName() { return this->name; } TColor Spieler::getColor() { return this->color; } void Spieler::setColor(TColor cl) { this->color = cl; }
Mensch:
class Mensch : public Spieler { public: Mensch() : Spieler("Mensch") { }; AnsiString getType() { return "Mensch"; } };
Computer:
class Computer : public Spieler { private: unsigned int schwierigkeit; // 1 = Einfach, 2 = Schwer public: Computer() : Spieler("Computer") { this->schwierigkeit = 2; }; Computer(int s) : Spieler("Computer") { this->schwierigkeit = s; } AnsiString getType() { return "Computer"; } unsigned int getSchwierigkeit() { return this->schwierigkeit; } void setSchwierigkeit(unsigned int s) { if(s == 1 || s == 2) { this->schwierigkeit = s; } else { throw "Diese Schwierigkeit existiert nicht!"; } } };
Passt das so alles?
getCurrentPlayer gibt immer einen Pointer auf den aktuellen Spieler zurück:
int Controller::getCurrentPlayerID() { return this->counter % 2 == 0 ? 1 : 0; } Spieler* Controller::getCurrentPlayer() { return this->spieler[this->getCurrentPlayerID()]; }
Das müsste doch gehen, oder?
Ich bin immer noch nicht weiter mit dem Problem...
Du würdest mir echt riesig helfen, wenn du einen heißen Tipp für mich hättest.
MfG
Simon
-
Benötigt ihr noch mehr Infos?
Ich bin immer noch nicht weiter...
-
Was genau ist denn die Frage? Sollen wir deinen Unit Test machen? Sollen wir einen Code review durchführen?
-
Ich brauche nur einen Hinweis, wo sich der Fehler möglicherweise befinden könnte....
-
Was genau ist denn die Frage?
Ich habe keine Ahnung, wie sich dein Fehler äußert oder wann er auftritt, daher kann ich dir nicht helfen, tut mir leid.
-
Das steht doch alles im ersten Beitrag.
Ich habe den Fehler jetzt aber gefunden und bin gerade auf der Suche nach einer Lösung.
Danke für die Hilfe!