Spiel in C++


  • Gesperrt

    @Jockelx sagte in Spiel in C++:

    wahrscheinlich nochmal irgendwein wrapper, der das vereinfacht

    Korrigiere: Ein wrapper, der das vereinfachen

    soll. 😉

    Ok, aber erst mal Danke.



  • @wpi sagte in Spiel in C++:

    @Jockelx sagte in Spiel in C++:

    wahrscheinlich nochmal irgendwein wrapper, der das vereinfacht

    Korrigiere: Ein wrapper, der das vereinfachen

    soll. 😉

    Ok, aber erst mal Danke.

    Tut es auch, wenn man die Dokumentation liest und versteht...

    https://github.com/jpbarrette/curlpp/blob/master/doc/guide.pdf

    Und zwar den Abschnitt "5.1 Option setting/retrieving"



  • libcurl hat eine grauenhafte API. Der C++ Wrapper scheint auch eine grauenhafte API zu haben. Daher: nicht blind auf gut Glück irgendwelche Beispiele abändern, sondern besser eins suchen wo genau das gemacht wird was man machen möchte. Und/oder erstmal die komplette Doku zu allen Funktionen lesen die in dem Beispiel/den Beispielen die man kombinieren möchte verwendet werden.


  • Gesperrt

    Vielen Dank @hustbaer , genau das meinte ich ...

    @firefly Du musst doch nicht sofort scharf schießen, nur weil jemand zu etwas eine Meinung hat ...



  • Nachtigall, ick hör dir trapsen...


  • Gesperrt

    Na ja, ich sterbe zwar immer, aber immerhin ist das Spiel fertig.^^

    #include <random>
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <string>
    #include <regex>
    #include <curlpp/Easy.hpp>
    #include <curlpp/cURLpp.hpp>
    #include <curlpp/Options.hpp>
    using namespace std;
    
    vector<string> getPossibleWords()
    {
        curlpp::Cleanup myCleanup;
        curlpp::Easy handle;
        handle.setOpt(curlpp::options::Url(string("https://de.wikipedia.org/wiki/Spezial:Zuf%C3%A4llige_Seite")));
        handle.setOpt(curlpp::options::FollowLocation(true));
        // handle.perform();
        ostringstream os;
        os << handle;
        string seq = os.str();
    
        vector<string> r;
        regex rgx("\\w+");
        for (sregex_iterator it(seq.begin(), seq.end(), rgx), it_end; it != it_end; ++it)
        {
            r.push_back((*it)[0]);
        }
        return r;
    }
    
    string getRandomWord(vector<string> words, int minLen, bool uppercase)
    {
        random_device dev;
        mt19937 rng(dev());
        uniform_int_distribution<mt19937::result_type> dist(0, words.size() - 1);
    
        while (1)
        {
            auto w = words[dist(rng)];
            if (w.size() >= minLen && (!uppercase || isupper(w[0])))
            {
                return w;
            }
        }
        return nullptr;
    }
    
    int main(int argc, char const *argv[])
    {
        auto v = getPossibleWords();
        auto w = getRandomWord(v, 5, true);
        string w2;
        for (int i = 0; i < w.size(); i++)
        {
            w2 += "_ ";
        }
        int len = w.size(), found = 0, tries = 0, health = 100;
        while (len > found && health > 0)
        {
            cout << "Das Spiel beginnt!" << endl;
            cout << "Das gesuchte Wort hat Länge " << len << endl;
            cout << "Du hast " << found << " gefunden und es " << tries << "-mal versucht" << endl;
            cout << w2 << endl;
    
            cout << "Welcher Buchstabe?" << endl;
            char c;
            cin >> c;
            int f = 0;
            for (int i = 0; i < w.size(); i++)
            {
                if (w[i] == c && w2[i * 2] == '_')
                {
                    f++;
                    found++;
                    w2[i * 2] = c;
                }
            }
            tries++;
            if (f > 0)
            {
                cout << "Prima, der Buchstabe " << c << " kam " << f << "-mal vor!" << endl;
            }
            else
            {
                cout << "Leider kein Glück gehabt ..." << endl;
                health -= 25;
            }
        }
        cout << "Das Spiel ist aus ..." << endl;
        if (health > 0)
        {
            cout << "Prima! Du hast das Wort " << w << " gefunden!" << endl;
        }
        else
        {
            cout << "Leider bist du tot. :-()" << endl;
        }
        return 0;
    }
    

    Falls jemand gewinnt, bitte mal melden. 😃


  • Gesperrt

    Weiß jemand, wie man "mit einfachen Mitteln" nur den sichtbaren Text einer Website/eines Wikipedia-Artikels erhalten kann (bzw. parsen)? JS und CSS sei also unwichtig ...

    Fragen dazu werden auf StackOverflow gnadenlos downgevotet.

    Prinzipiell doch zwei Ansätze:

    1. Den XML-DOM-Baum parsen ... oder
    2. HTML parsen (mit Regex ...)

    1. würde wahrscheinlich daran scheitern, dass HTML ja meistens kein wohlgeformtes XML is ...

    Es geht mir einfach darum, keine HTML-Steuerzeichen/-Tags als Suchwort zu verwenden.


  • Gesperrt

    Ich habe noch eine Frage bzw. nichtfunktionale Anforderung ...

    Die .exe ist jetzt über 1 MB. Wie schaffen die anderen Freaks das, dass eine .exe nur ein paar KB groß ist?



  • In dem man sich json von irgendeinem API holt (wikipedia hat auch eine).

    google hat ungefaehr noch ein dutzend weitere APIs ausgespuckt die ebenfalls wordlists/random words zur verfuegung stellen.

    Dein binary bekommst du kleiner wenn du entsprechende compiler flags fuer optimierung mitgibst (eg. -O3) und dir deine linker optionen mal anschaust.



  • @wpi
    libcurl ist halt nicht gerade klein.
    Du kannst libcurl kleiner bekommen, indem du sie selbst baust, und dabei alle Protokolle deaktivierst die du nicht brauchst.

    Oder du kannst die HTTP Funktionen der WinAPI verwenden. z.B. mit https://learn.microsoft.com/en-us/windows/win32/winhttp/iwinhttprequest-send
    Damit schaffst du vermutlich das kleinste Programm.


  • Gesperrt

    @hustbaer Bitte schau dir auch mal mein anderes Thema an ...


  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • @wpi sagte in Spiel in C++:

    struct ToFind

    Kommentiere alle structs/Klassen. Es muss ja nicht lang sein, aber "ToFind" kann alles und nichts bedeuten. Was sind z.B. w1 und w2? Ein paar mehr Buchstaben für bessere Namen kosten nichts.

    void initToFind(struct ToFind *stf, string w)

    Welche Sprache willst du eigentlich schreiben? Das sieht nach C ohne ++ aus, aber mit string.


  • Gesperrt

    @wob
    Sorry, hat sich schon erledigt, da war noch zu viel falsch.



  • @wpi sagte in Spiel in C++:

    @hustbaer Bitte schau dir auch mal mein anderes Thema an ...

    Welches andere Thema?


  • Gesperrt

    @hustbaer sagte in Spiel in C++:

    @wpi sagte in Spiel in C++:

    @hustbaer Bitte schau dir auch mal mein anderes Thema an ...

    Welches andere Thema?

    Das hier https://www.c-plusplus.net/forum/topic/354334/c-library-mit-cygwin-bauen-und-verwenden

    Aber es hat sich schon erledigt, bin mit dem Hangman-Spiel fertig. Soll ich das zeigen?


  • Gesperrt

        void initWord()
        {
            for (int i = 0; i < w1.size(); i++)
            {
                if (w1[i] == ' ')
                {
                    w2 += "  ";
                }
                else if (w1[i] > 'z')
                {
                    w2 += "--";
                }
                else
                {
                    w2 += "_ ";
                }
            }
        }
    

    Wieso ersetzt er hier keine Sonderzeichen durch --? Die müssten doch > 'z' sein. (Zeile 9 bis 12)



  • @wpi was für ein Datentyp ist w2 denn? Ich würde darauf tippen das du dich mit Kodierungen wie utf8/16 und der entsprechenden Repräsentierung in deiner Software beschäftigen musst.



  • @wpi sagte in Spiel in C++:

    Wieso ersetzt er hier keine Sonderzeichen durch --? Die müssten doch > 'z' sein. (Zeile 9 bis 12)

    Warum müssten sie das?
    In ASCII gilt: '!' < '%' < 'A' < 'Z' < '[' < 'a' < 'z' < '}'


  • Gesperrt

    @Schlangenmensch sagte in Spiel in C++:

    @wpi was für ein Datentyp ist w2 denn?

    Das sind alles std::strings ...

    @wob sagte in Spiel in C++:

    Warum müssten sie das?

    Ich dachte, egal welches Encoding ... intern basiert es auf dem ASCII?

    Anbei mal der Code:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <regex>
    #include <curlpp/Easy.hpp>
    #include <curlpp/cURLpp.hpp>
    #include <curlpp/Options.hpp>
    
    std::string getRandomWordFromWikipedia()
    {
        curlpp::Cleanup cleanup;
        curlpp::Easy handle;
        handle.setOpt(curlpp::options::Url("https://en.wikipedia.org/wiki/special:random"));
        handle.setOpt(curlpp::options::FollowLocation(true));
        std::ostringstream os;
        os << handle;
        std::string response = os.str();
        std::regex headingRegex("<h1.+id=\"firstHeading\"[^>]*>(.+)</h1>");
        std::regex tagRegex("<[^>]+>(.+)</[^>]+>");
        std::smatch headingMatch;
        
        if (std::regex_search(response, headingMatch, headingRegex))
        {
            std::string heading = headingMatch[1];
            if (heading.find("<") != std::string::npos)
            {
                std::smatch tagMatch;
                if (std::regex_search(heading, tagMatch, tagRegex))
                {
                    return tagMatch[1];
                }
            }
        }
        
        return "";
    }
    
    struct ToFind
    {
        std::string w1;
        std::string w2;
        int tries;
        int right;
        int health;
        int hintsLeft;
    
        ToFind() : tries(0), right(0), health(100), hintsLeft(2)
        {
        }
    
        ToFind(std::string word) : w1(word), tries(0), right(0), health(100), hintsLeft(2)
        {
            initWord();
        }
    
        void setWord(std::string word)
        {
            w1 = word;
            initWord();
        }
    
        void initWord()
        {
            for (int i = 0; i < w1.size(); i++)
            {
                if (w1[i] == ' ')
                {
                    w2 += "  ";
                }
                else if (w1[i] > 'z')
                {
                    w2 += "--";
                }
                else
                {
                    w2 += "_ ";
                }
            }
        }
    
        void printStatistics()
        {
            static int round = 1;
            std::cout << "Round:      " << round << "\n";
            std::cout << "Tries:      " << tries << "\n";
            std::cout << "Rights:     " << right << " (" << (right * 100.0f / tries) << " %)\n";
            std::cout << "Health:     " << health << " from 100\n";
            std::cout << "Hints left: " << hintsLeft << "\n";
            round++;
        }
    
        bool hasWord()
        {
            return !w1.empty();
        }
    
        bool stillAlive()
        {
            return health > 0;
        }
    
        int findInToFind(char c)
        {
            int f = 0;
            for (int i = 0; i < w1.size(); i++)
            {
                if (w1[i] == c && w2[i * 2] == '_')
                {
                    f++;
                    w2[i * 2] = c;
                }
            }
    
            tries++;
    
            if (f > 0)
            {
                right++;
            }
            else
            {
                health -= 10;
            }
    
            return f;
        }
    
        void nextHint()
        {
            if (hintsLeft == 0)
            {
                std::cout << "no hints left\n";
                return;
            }
            hintsLeft--;
            std::cout << "hints left: " << hintsLeft << "\n";
    
            tries++;
    
            std::map<char, int> occurencies;
            for (int i = 0; i < w1.size(); i++)
            {
                if (w2[i * 2] == '_')
                {
                    occurencies[w1[i]]++;
                }
            }
            char maxChar;
            int maxCount = 0;
            for (auto it = occurencies.begin(); it != occurencies.end(); it++)
            {
                if (it->second > maxCount)
                {
                    maxChar = it->first;
                    maxCount = it->second;
                }
            }
            for (int i = 0; i < w1.size(); i++)
            {
                if (w1[i] == maxChar && w2[i * 2] == '_')
                {
                    w2[i * 2] = maxChar;
                }
            }
        }
    };
    
    int main(int argc, char const *argv[])
    {
        struct ToFind stf(getRandomWordFromWikipedia());
        if (!stf.hasWord())
        {
            return EXIT_FAILURE;
        }
        std::cout << "The game begins!\n";
        std::cout << "The word(s) you are looking for has a length of " << stf.w1.size() << "\n";
        while (stf.w2.find("_") != std::string::npos && stf.health > 0)
        {
            stf.printStatistics();
            std::cout << stf.w2 << "\n";
            std::cout << "Which letter next? (9 for help)\n";
            char c;
            std::cin >> c;
            if (c == '9')
            {
                stf.nextHint();
            }
            else
            {
                int f = stf.findInToFind(c);
                if (f > 0)
                {
                    std::cout << "Great, the letter " << c << " appeared " << f << " times!\n";
                }
                else
                {
                    std::cout << "Unfortunately you weren't lucky this time ...\n";
                }
            }
        }
        std::cout << "The game is over ...\n";
        if (stf.stillAlive())
        {
            std::cout << "Great, you found the word " << stf.w1 << "!\n";
        }
        else
        {
            std::cout << "Unfortunately you didn't find the word " << stf.w1 << ". :(\n";
        }
        stf.printStatistics();
        std::cout << "Any char to continue ...\n";
        char c;
        std::cin >> c;
        return EXIT_SUCCESS;
    }
    

    Ich denke langsam, mein Computer spinnt hinsichtlich des Encodings ... (Cygwin, Win11, PS, g++, .exe ...)


Anmelden zum Antworten