Spiel in C++


  • Gesperrt

    Hallo, habt ihr vielleicht eine Idee für ein kleines/einfaches Konsolen-Spiel oder Problem, das man gut in C++ programmieren könnte, für Übungszwecke, was auch Strukturen und Klassen und so beinhaltet? Vielleicht eine TicTacToe-KI mit Schwierigkeitsstufen - oder wäre das zu umfangreich? Alle Sprachkonstrukte und Idiome sollte mal vorkommen (auch, wenn mir das gerade etwas viel erscheint...).

    Gut wäre es auch, wenn man sich dabei Gedanken um ein Pattern wie MVC/MVP, fluent und so machen müsste.



  • TicTacToe, 4 gewinnt, Sudoku und Reversi sind alles Spiele, die problemlos mit einer einfachen Konsolenausgabe auskommen können.

    Fang doch einfach mal an. TTT sollte nicht wirklich schwierig zu implementieren sein. Und von da ist es sicher nicht weit zu 4 gewinnt. (wobei du da z.B. auch die Größe des Spielfeldes variablel halten könntest).

    Alle Sprachkonstrukte und Idiome sollte mal vorkommen (auch, wenn mir das gerade etwas viel erscheint...).

    Ähm... nein, das klingt nicht wirklich sinnvoll. Scheitert schon daran zu bestimmen, was "alle Idiome" genau beinhaltet. Und die Idee eines Design Pattern ist es, eine bestimmte Problemfamilie zu lösen. Wenn ein derartiges Problem in deinem Projekt gar nicht auftritt, braucht es auch nicht gelöst zu werden.


  • Gesperrt

    @wpi sagte in Spiel in C++:

    Alle ... sollte mal

    Iwie klemmt meine Tastatur manchmal !!! +n

    @wob Vielen Dank für die Anregungen!!!


  • Gesperrt

    Ergänzung: Hier sind 97 aufgelistet: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms



  • oder wenn du es einfacher haben willst: Hangman oder Lingo (so ein Spiel, wo man Wörter raten muss und richtige Buchstaben (richtig+Stelle richtig vs. kommt vor) angezeigt werden.



  • @wpi sagte in Spiel in C++:

    Ergänzung: Hier sind 97 aufgelistet: https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms

    Diese Liste erscheint mir mehr für Library-Entwickler sinnvoll zu sein, nicht für 0815 Anwendungsprogramme.


  • Gesperrt

    @wob sagte in Spiel in C++:

    oder wenn du es einfacher haben willst: Hangman oder Lingo (so ein Spiel, wo man Wörter raten muss und richtige Buchstaben (richtig+Stelle richtig vs. kommt vor) angezeigt werden.

    Ich versuche es mal mit hangman...

    #include <iostream>
    #include <ios>
    #include <vector>
    #include <string>
    #include <curlpp/cURLpp.hpp>
    #include <curlpp/Options.hpp>
    using namespace std;
    
    vector<string> getPossibleWords()
    {
        // RAII cleanup
        curlpp::Cleanup myCleanup;
        // Send request and get a result.
        ostringstream os;
        os << curlpp::options::Url(string("https://de.wikipedia.org/wiki/Special:Random"));
        vector<string> r;
        r.push_back(os.str());
        return r;
    }
    
    
    $ g++ Hangman.cpp -o hm.exe
    Hangman.cpp: In function ‘std::vector<std::basic_string<char> > getPossibleWords()’:
    Hangman.cpp:14:19: error: aggregate ‘std::ostringstream os’ has incomplete type and cannot be defined
       14 |     ostringstream os;
          |                   ^~
    
    

    Ich verstehe den Fehler nicht. 🤧

    Das sollte doch "da" sein:

    $ make install
    [ 50%] Built target curlpp
    [100%] Built target curlpp_static
    Install the project...
    -- Install configuration: ""
    -- Installing: /usr/local/include/utilspp
    -- Installing: /usr/local/include/utilspp/clone_ptr.hpp
    -- Installing: /usr/local/include/utilspp/EmptyType.hpp
    -- Installing: /usr/local/include/utilspp/NonCopyable.hpp
    -- Installing: /usr/local/include/utilspp/NullType.hpp
    -- Installing: /usr/local/include/utilspp/SmartPtr.hpp
    -- Installing: /usr/local/include/utilspp/ThreadingFactoryMutex.hpp
    -- Installing: /usr/local/include/utilspp/ThreadingFactoryMutex.inl
    -- Installing: /usr/local/include/utilspp/ThreadingSingle.hpp
    -- Installing: /usr/local/include/utilspp/ThreadingSingle.inl
    -- Installing: /usr/local/include/utilspp/TypeList.hpp
    -- Installing: /usr/local/include/utilspp/TypeTrait.hpp
    -- Installing: /usr/local/include/curlpp
    -- Installing: /usr/local/include/curlpp/cURLpp.hpp
    -- Installing: /usr/local/include/curlpp/Easy.hpp
    -- Installing: /usr/local/include/curlpp/Easy.inl
    -- Installing: /usr/local/include/curlpp/Exception.hpp
    -- Installing: /usr/local/include/curlpp/Form.hpp
    -- Installing: /usr/local/include/curlpp/Info.hpp
    -- Installing: /usr/local/include/curlpp/Info.inl
    -- Installing: /usr/local/include/curlpp/Infos.hpp
    -- Installing: /usr/local/include/curlpp/internal
    -- Installing: /usr/local/include/curlpp/internal/CurlHandle.hpp
    -- Installing: /usr/local/include/curlpp/internal/CurlHandle.inl
    -- Installing: /usr/local/include/curlpp/internal/OptionContainer.hpp
    -- Installing: /usr/local/include/curlpp/internal/OptionContainer.inl
    -- Installing: /usr/local/include/curlpp/internal/OptionContainerType.hpp
    -- Installing: /usr/local/include/curlpp/internal/OptionList.hpp
    -- Installing: /usr/local/include/curlpp/internal/OptionSetter.hpp
    -- Installing: /usr/local/include/curlpp/internal/OptionSetter.inl
    -- Installing: /usr/local/include/curlpp/internal/SList.hpp
    -- Installing: /usr/local/include/curlpp/Multi.hpp
    -- Installing: /usr/local/include/curlpp/Option.hpp
    -- Installing: /usr/local/include/curlpp/Option.inl
    -- Installing: /usr/local/include/curlpp/OptionBase.hpp
    -- Installing: /usr/local/include/curlpp/Options.hpp
    -- Installing: /usr/local/include/curlpp/Types.hpp
    -- Installing: /usr/local/lib/libcurlpp.dll.a
    -- Installing: /usr/local/bin/cygcurlpp-1.dll
    -- Installing: /usr/local/lib/libcurlpp.a
    -- Installing: /usr/local/bin/curlpp-config
    -- Installing: /usr/local/lib/pkgconfig/curlpp.pc
    


  • #include <sstream>
    

  • Gesperrt

    @Belli sagte in Spiel in C++:

    #include <sstream>
    

    Danke, funktioniert, aber jetzt erhalte ich 1000 Linker-Fehler. 🤧


  • Gesperrt

    Er kann curlpp::Cleanup::Cleanup() nicht finden.



  • @wpi wenn es darum geht ein Spiel zu programmieren, würde ich mich jetzt nicht damit aufhalten, curl ans laufen zu bringen.
    Bei Hangman brauchst du ein Wort, das kannst du erstmal hinter einer GetWord Funktion verstecken, die erstmal als Dummy immer das selbe Wort zurück gibt. Und da drum kannst du erstmal den Rest bauen ohne dir darüber Gedanken zu machen, woher genau das Wort eigentlich kommen soll, das erraten werden soll.



  • Das, was @Schlangenmensch sagt.

    Mach einen Schritt nach dem anderen.

    Du musst libcurl natürlich auch in dein Programm linken, in der Regel einfach -lcurl als Parameter hinten ans g++-Kommando anhängen. Aber mach dir doch erstmal eine Liste von 5 Wörtern direkt ins Programm, dann kannst dir eine längere Liste in einer Datei anlegen und erst dann dynamisch aus dem Internet laden.

    Also so:

    std::vector<std::string> getPossibleWords() {
       return {"Hallo", "dies", "ist", "ein", "Test"};
    };
    
    

    Vielleicht wäre allerdings eine Funktion std::string get_random_word() sinnvoller - wozu willst du alle möglichen Wörter haben?
    Und dann kannst du als erste Übung überlegen, wie du deinem Programm sinnvoll beibringst, von unterschiedlichen Orten ein Wort zu holen...

    • std::string get_random_word_from_test_data()
    • std::string get_random_word_from_file()
    • std::string get_random_word_from_url()

    Etwa so? Aber wie würde man das erweitern? Wäre das gut erweiterbar? Vielleicht soll gar der Spieler die Wortquelle wählen können, etwas auch get_random_german_word, get_random_english_word. Oder doch lieber eine Wortliste holen - welche Vor- und Nachteile gibt es? Da kannst du viel üben. Aber erstmal mit der einfachsten Variante davon das Spiel fertigmachen.


  • Gesperrt

    Danke ... aber das wurmt mich jetzt ...

     g++ Hangman.cpp -o hm.exe -lcurl
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text+0x23): undefined reference to `curlpp::Cleanup::Cleanup()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text+0x87): undefined reference to `operator<<(std::ostream&, curlpp::OptionTrait<std::string, (CURLoption)10002> const&)'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text+0x114): undefined reference to `curlpp::Cleanup::~Cleanup()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text+0x198): undefined reference to `curlpp::Cleanup::~Cleanup()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp6OptionISsEC2E10CURLoptionRKSs[_ZN6curlpp6OptionISsEC2E10CURLoptionRKSs]+0x21): undefined reference to `curlpp::OptionBase::OptionBase(CURLoption)'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp6OptionISsEC2E10CURLoptionRKSs[_ZN6curlpp6OptionISsEC2E10CURLoptionRKSs]+0x5c): undefined reference to `curlpp::OptionBase::~OptionBase()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp6OptionISsED2Ev[_ZN6curlpp6OptionISsED2Ev]+0x53): undefined reference to `curlpp::OptionBase::~OptionBase()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.rdata$_ZTVN6curlpp11OptionTraitISsL10CURLoption10002EEE[_ZTVN6curlpp11OptionTraitISsL10CURLoption10002EEE]+0x20): undefined reference to `curlpp::OptionBase::operator<(curlpp::OptionBase const&) const'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.rdata$_ZTVN6curlpp6OptionISsEE[_ZTVN6curlpp6OptionISsEE]+0x20): undefined reference to `curlpp::OptionBase::operator<(curlpp::OptionBase const&) const'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp11UnsetOptionD1Ev[_ZN6curlpp11UnsetOptionD1Ev]+0x22): undefined reference to `curlpp::RuntimeError::~RuntimeError()'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp6OptionISsE16updateMeToOptionERKNS_10OptionBaseE[_ZN6curlpp6OptionISsE16updateMeToOptionERKNS_10OptionBaseE]+0x68): undefined reference to `curlpp::UnsetOption::UnsetOption(char const*)'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZNK6curlpp11OptionTraitISsL10CURLoption10002EE16updateHandleToMeEPNS_8internal10CurlHandleE[_ZNK6curlpp11OptionTraitISsL10CURLoption10002EE16updateHandleToMeEPNS_8internal10CurlHandleE]+0x3c): undefined reference to `curlpp::UnsetOption::UnsetOption(char const*)'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZNK6curlpp6OptionISsE8getValueEv[_ZNK6curlpp6OptionISsE8getValueEv]+0x3c): undefined reference to `curlpp::UnsetOption::UnsetOption(char const*)'
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: /tmp/ccCF1Lfb.o:Hangman.cpp:(.text$_ZN6curlpp8internal10CurlHandle6optionIPvEEv10CURLoptionT_[_ZN6curlpp8internal10CurlHandle6optionIPvEEv10CURLoptionT_]+0x3e): undefined reference to `curlpp::libcurlRuntimeAssert(char const*, CURLcode)'
    collect2: error: ld returned 1 exit status
    
    

  • Mod

    Der C++-Teil von Curl ist in libcurlpp. Also zusätzlich noch -lcurlpp (das -lcurl brauchst du immer noch, weil der ++-Teil den "normalen" Teil benutzt).


  • Gesperrt

    $ g++ Hangman.cpp -o hm.exe -lcurl -lcurlpp
    /usr/lib/gcc/x86_64-pc-cygwin/11/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lcurlpp: No such file or directory
    collect2: error: ld returned 1 exit status
    

    g++ -I/usr/local/include ... geht auch nicht. Gibt es ein generelles Vorgehen, um statische Libraries zu linken?



  • Mit -L... gibt man den Pfad beim Linken an.
    Besser sollte der Aufruf

    g++ Handmap.cpp -L/usr/lib/.... -lcurl -lcurlpp -o hm.exe
    

    lauten. Die Punkte sind natürlich durch den richtigen Pfad zu ersetzen.



  • @john-0 sagte in Spiel in C++:

    Mit -L... gibt man den Pfad beim Linken an.
    Besser sollte der Aufruf

    g++ Handmap.cpp -L/usr/lib/.... -lcurl -lcurlpp -o hm.exe
    

    lauten. Die Punkte sind natürlich durch den richtigen Pfad zu ersetzen.

    Nicht notwendig, da libcurlpp und libcurl im selben verzeichnis liegen, wenn sie via package manager installiert wurden
    @wpi: Ich kenn mich jetzt nicht großartig mit cygwin aus, aber wie hast du curlpp installiert?
    Nicht das du nur die header files installiert hast aber nicht die eigendlichen binaries?


  • Gesperrt

    @john-0 sagte in Spiel in C++:

    Besser sollte der Aufruf
    g++ Handmap.cpp -L/usr/lib/.... -lcurl -lcurlpp -o hm.exe

    Nein, geht auch nicht.

    Folgendes hab ich gemacht:
    Download von GitHub
    mkdir build
    cd build
    cmake ..
    cmake --build .
    make Install

    Schreibe gerade vom Handy, deshalb geht das nicht ausführlicher.

    Ich hab curlpp also nicht direkt über cygwin selber installiert...

    Aber cygwin hat eine emulierte Konsole sowie spezielles user home...

    Hab mich noch nicht ausgiebig damit befasst



  • @wpi Am Ende musst du gucken, wo die Bibliotheken liegen und den passenden Pfad angeben. Offenbar hast du die manuell selbst kompiliert, ich habe keine Ahnung wo die dann per default landen.



  • @Schlangenmensch sagte in Spiel in C++:

    @wpi Am Ende musst du gucken, wo die Bibliotheken liegen und den passenden Pfad angeben. Offenbar hast du die manuell selbst kompiliert, ich habe keine Ahnung wo die dann per default landen.

    Da offenbar mit cmake installiert wurde, dann mal die CURLConfig.cmake suchen... Siehe auch https://cmake.org/cmake/help/v3.28/module/FindCURL.html

    Jedenfalls bin ich bei cmake-Tipps raus, ich habe das zwar immer irgendwie zum Laufen bekommen, aber mit Betonung auf "irgendwie" 😉



  • @wpi sagte in Spiel in C++:

    Hallo, habt ihr vielleicht eine Idee für ein kleines/einfaches Konsolen-Spiel oder Problem, das man gut in C++ programmieren könnte, für Übungszwecke, was auch Strukturen und Klassen und so beinhaltet?

    Das sollte einfach genug sein. Hangman wurde ja schon vorgeschlagen. Ansonsten kannst du dich auch an sowas wie Snake versuchen. Oder ein klassisches SHMUP - kann man wenn man will auch im Text-Mode machen.

    Vielleicht eine TicTacToe-KI mit Schwierigkeitsstufen - oder wäre das zu umfangreich?

    Das sollte schon nach machbar sein. Klassisches 3x3 TicTacToe ist von der max. benötigten Suchtiefe her so begrenzt dass man eigentlich nicht optimieren muss. D.h. du musst dich nicht tief in diverse Optimierungen einarbeiten und kannst dich auf das Lernen von idiomatischem C++ konzentrieren.

    Alle Sprachkonstrukte und Idiome sollte mal vorkommen (auch, wenn mir das gerade etwas viel erscheint...).

    Gut wäre es auch, wenn man sich dabei Gedanken um ein Pattern wie MVC/MVP, fluent und so machen müsste.

    Alles mit einem kleinen, realistischen Projekt abzudecken ist mMn. nicht realistisch. Dazu müsste man vermutlich auch zig seltsame Anforderungen dazudefinieren. Mal ganz abgesehen davon dass es meist keine gute Idee ist zu versuchen alles auf einmal zu lernen. Fang einfach mal mit etwas kleinem an.


Anmelden zum Antworten