TicTacToe



  • Mach mal das auf jeden Fall noch:

    @Leon0402 sagte in TicTacToe:

    Würdest du so eine Methode aber brauchen, solltest du eine Referenz zurück geben und die Methode als const kennzeichnen.

    const std::vector<char> getFieldVec();
    

    Getter sind idR const und der Rückgabewert ist idR const& (bei nicht primitiven Datentypen).
    Eine Kopie als const zurück zugeben macht jedenfalls gar keinen Sinn.



  • Hab sie gleich komplett gelöscht. Die Methode war wohl noch vom Anfang des Projekts^^. Aktuell wir sie nirgends verwendet. Aber danke nochmal für die Erinnerung 👍🏻



  • @Jockelx sagte in TicTacToe:

    Ich mag deinen Datentypen char für das Spielfeld nicht.
    Das kann man sicherlich lesbarer machen, z.B. als enum oder mit Pointern auf Player.
    Wobei Player dann eine class ist, was vielleicht auch sinnvoll wäre.

    Bei einem enum player_t { PLAYER_ONE = 'X', PLAYER_TWO = 'O', PLAYER_NONE = ' ' }; bin ich noch dabei. Aber eine Klasse für die beiden Spieler und dann noch Pointer darauf im Spielfeld? Overengineering?



  • @Swordfish
    Ja, kann gut sein, dass das hier noch too much ist. Habe auch extra sehr defensiv den Vorschlag gemacht, da ich die Notwendigkeit auch nicht so 100%ig sehe.
    Spätestens sobald aber einer der Player AI sein kann, wird es Zeit für mehr Abstraktion. Aber wenn das jetzt schon quasi fertig ist, dann hast du sicherlich Recht.



  • @Jockelx sagte in TicTacToe:

    Spätestens sobald aber einer der Player AI sein kann, wird es Zeit für mehr Abstraktion.

    Weiß nicht, ob ich da übereinstimme*. Man braucht doch nur eine Funktion estimateBestMove(currentPosition) (wobei currentPosition natürlich auch enthält, wer dran ist). Und darin generiert man Züge und macht einen MinMax-Algorithmus. Fertig. Sehe nicht, dass man da irgendwie im Spielfeld irgendwas Komplizierteres benötigt. Halte es einfach!

    Edit: * = weiß ich doch. Und zwar stimme ich nicht überein.
    Edit2: bei TTT kann man statt mit MinMax einfach alles durchprobieren.



  • @wob sagte in TicTacToe:

    Man braucht doch nur eine Funktion estimateBestMove(currentPosition)

    Was hat das denn jetzt mit einer Player-Klasse zu tun, die sinnvoll ist (oder vielleicht halt auch nicht).

    Schon in der main würde ich mir die Finger brechen, wenn ich das mit char hier und char da machen müsste, statt irgendwie sowas

    int main() {
    	Player player[2] = {Human, Ai};
            int round = 0;
    	while(! player[round%2].isWinning())
    	{
                player[round%2].makeTurn(); // estimateBestMove or userinput
                ++round;
    	}
    	return 0;
    }
    


  • @Jockelx sagte in TicTacToe:

    Eine Kopie als const zurück zugeben macht jedenfalls gar keinen Sinn.

    Bist du dir da ganz sicher?



  • @Mechanics sagte in TicTacToe:

    Bist du dir da ganz sicher?

    Trolling?

    Wenn nicht, was findest Du besser?

    const int foo() { return 42; }
    

    oder

    const const const /* <~ just to make really, really sure */ int foo() { return 42; }
    

    ?

    ...

    // ...
    int bar{ foo() };
    bar = 47;  // uups
    // ...
    


  • Darum gings nicht 😉
    Mir gings um die pauschale Aussage "macht jedenfalls gar keinen Sinn", noch spezifischer um das "gar keinen", und das stimmt so nicht. Man kann sich durchaus Fälle vorstellen, bei denen das zumindest ein bisschen Sinn macht. Nämlich, wenn man Aufrufe verschachtelt. z.B. bei in Qt mit den ganzen Copy-On-Write Containern wäre das ein Problem.

    QVector<SomeClass> itemList() const {return m_items;}
    itemList().first();
    

    Würde evtl. schon zu einer Deep Copy führen. Und ähnliche Konstrukte sehe ich bei uns im Code sehr häufig. Deswegen find ich so eine "gar keinen Sinn" Aussage hier zu pauschal, man muss zumindest im Hinterkopf behalten, was es alles für Möglichkeiten gibt.



  • Der Thread ist ganz schön ausgeartet. Also ich bin hier bei dem Stand, dass ich wahrscheinlich noch die Auswertungen auf mein std::pair umschreibe und den Rest so lassen kann wie bei meinen letzten Post. Zumindest hat niemand weitere Einwände geäußert. Wenn ihr noch Tipps habt, die nicht den Rahmen des usecases sprengen, bin ich ganz Ohr. Ansonsten schonmal vielen Dank für die vielen Tipps und Hinweise. 👍🏻 👍🏻 👍🏻



  • @Mechanics sagte in TicTacToe:

    QVector<SomeClass> itemList() const {return m_items;}
    itemList().first();
    

    Verstehe das Beispiel nicht. Da ist die Methode const und nicht der Rückgabewert!?
    Edit:

    Ok, ich verstehe dein Beispiel. Also gut, wie immer in C++ ist eine absolute Aussage auch hier fehl am Platz.
    Nehme das "gar keinen Sinn" zurück!


Anmelden zum Antworten