Suche Programmierer.



  • Hallo Leute, ich bin mir sicher das ich hier den richtigen finde. Ich suche einen Programmierer für ein kleines Projekt. Es handelt sich um ein Zahlen Ratespiel...

    Das Grundgerüst
    Der Computer berechnet eine Zufallszahl. Sie geben eine geratene Zahl ein. Auf dem Monitor
    sollen der jeweils kleinste Rateversuch, der am nächsten an der Zahl ist , sowie die größte Zahl,
    die am nächsten an der Zahl ist, angezeigt werden – z.B. in der Form
    125<X<200
    2. Die Anzahl der Versuche wird angezeigt
    3. Es gibt am Anfang des Spieles ein Menü: Die Unterpunkte sind "Spielen",
    "Bestenliste","Setup"

    1. Es gibt eine Bestenliste, die auf Platte gespeichert wird. Dazu gibt der Spieler am Anfang des
      Programmes einen Namen (ohne Leerzeichen!) ein, dieser wird mit der Anzahl der benötigten
      Versuche abgespeichert. Die Liste soll nach Anzahl der Versuche sortiert werden. Benutzen Sie
      als Vorgabe-Liste die Datei "score.txt", die Sie im Lernportal herunterladen können. Die
      Bestenliste soll 20 Einträge erlauben, schlechtere Plätze als 20 werden gelöscht. Hat der Spieler
      einen schlechteren Platz als 20 erspielt, wird er nicht aufgenommen. Die Bestenliste wird am
      Spielende angezeigt.

    2. Im Setup kann die Bestenliste zurückgesetzt werden, so daß alle Einträge gelöscht sind. Die
      Liste wird dabei nicht gelöscht, ist danach nur leer

    3. Im Setup kann die höchste zu ratende Zahl eingegeben werden. Diese wird in einer Setup-
      Datei (z.B. setup.txt) gespeichert und bei nächsten Start wieder geladen.

    4. Im Setup kann eingegeben werden, ob der Spieler nur eine beschränkte Anzahl von Versuchen
      hat. Überschreitet er diese, so wird das Spiel beendet, die Zahl angezeigt und der Spieler NICHT
      in die Bestenliste aufgenommen. Auch diese Zahl wird in der Setup-Datei gespeichert und beim
      Programmstart wieder geladen.

    5. Die Zeit, die der Spieler benötigt, wird bei jedem Versuch angezeigt (Benutzen Sie z.B. den
      Befehl time(NULL), der die Systemzeit in Sekunden als long wiedergibt. Die Zeit muß aber
      nicht fortlaufend angezeigt werden, während der Spieler seine Eingabe macht. Die Zeit wird in
      der Bestenliste mit abgespeichert.

    6. Der Spieler kann das Spiel durch Eingabe einer negativen Zahl beenden – er wird nicht in die
      Bestenliste aufgenommen. Die zu ratende Zahl wird angezeigt

    7. Es gibt einen Cheating Code: Gibt der Spieler die Zahl -123 ein, so wird die zu erratende Zahl
      angezeigt. Das Spiel geht normal weiter.

    8. Cheating Code 2: Bei Eingabe von -456 kann der Spieler die Versuche und die Zeit selbst
      eingeben, das Spiel wird beendet und der Spieler in der Bestenliste mit diesen Werte
      aufgenommen.

    9. Kommentierter Quelltext, bei dem jede Zeile kommentiert ist

    😖 Der mir für ein kleines Geld bis VB 70 Euro weiter hilft. Ich hoffe es meldet sich jemand. Danke schon mal im Voraus.🙏



  • Bloss nicht sagen um was für ein Projekt es sich handelt, sonst meldet sich am Ende noch jemand 😉



  • Dieser Beitrag wurde gelöscht!

  • Mod

    Du willst doch, dass dir jemand hilft. Wenn du meinst, dass sich jemand auf so eine Anzeige hin meldet: Wie du meinst. Gibt bestimmt keinen Grund, wieso hustbaer dir den Rat gegeben hat, dass das eventuell nicht stimmen könne :face_with_stuck-out_tongue:



  • @hustbaer sagte in Suche Programmierer.:

    Bloss nicht sagen um was für ein Projekt es sich handelt, sonst meldet sich am Ende noch jemand 😉

    Ein Zahlen-Ratespiel. Er zahlt und wir müssen raten wofür.



  • So jetzt ist komplett.



  • Punkt 12 😲



  • @bashar sagte in Suche Programmierer.:

    Punkt 12

    Ja, ziemlich sinnlos und hässlich am Ende jeder Zeile // zu schreiben ^^


  • Mod

    @bashar sagte in Suche Programmierer.:

    Punkt 12 😲

    #include <iostream>  // Includes iostream for std::cout
    using namespace std;  // Pushes namespace std to global namespace so that we can write 'cout' instead of 'std::cout'
    // This is line 3
    int main() {  // Defines the main function. The main function is the entry point for the executable
    	cout << "Hello World\n";   // Writes the message to stdout. '\n' ist a line break.
    	return 0;  // Return the value 0. As this is the main function, returning from it will effectively end execution. The value 0 indicates successful program termination.
    }  // Ends the definition of main
    


  • kürzer:

    #include <iostream>//
    int main() { std::cout << "Hello World\n"; }//
    


  • omg, ist mir langweilig ...

    #include <iostream>//
    #include <fstream>//
    #include <string>//
    #include <set>//
    #include <iterator>//
    #include <limits>//
    #include <chrono>//
    #include <random>//
    //
    using namespace std::string_literals;//
    //
    class setup_t//
    {//
    	static char const *filename;//
    	std::random_device rd;//
    	std::mt19937 generator;//
    	int max_number;//
    	int max_attempts;//
    public://
    	setup_t();//
    	int get_max_attempts() const { return max_attempts; }//
    	int get_new_number_to_guess();//
    	void write() const;//
    	void print() const;//
    	void alter();//
    };//
    //
    char const *setup_t::filename = "setup.txt";//
    //
    setup_t::setup_t()//
    : rd{},//
      generator{ rd() },//
      max_number{ 100 },//
      max_attempts{ 10 }//
    {//
    	int number{};//
    	int attempts{};//
    	std::ifstream is{ filename };//
    	if (!(is && (is >> number >> attempts))) {//
    		std::cerr << "Error reading game settings from \"" << filename << "\"!\nReverting to defaults.\n\n";//
    		return;//
    	}//
    	max_number = number;//
    	max_attempts = attempts;//
    }//
    //
    int setup_t::get_new_number_to_guess()//
    {//
    	std::uniform_int_distribution<> distribution{ 0, max_number };//
    	return distribution(generator);//
    }//
    //
    void setup_t::write() const//
    {//
    	std::ofstream os{ filename, std::ios_base::trunc };//
    	if (!(os && (os << max_number << ' ' << max_attempts))) {//
    		std::cerr << "Error writing game settings to \"" << filename << "\"!\n\n";//
    	}//
    }//
    //
    void setup_t::print() const//
    {//
    	std::cout << "\nCurrent Setup:\nMaximal number to guess: " << max_number//
    		<< "\nMax attempts to guess the number (0 = indefinite): " << max_attempts << "\n\n";//
    }//
    //
    void setup_t::alter()//
    {//
    	while (std::cout << "Please enter the maximal number to guess: ",//
    		!(std::cin >> max_number)) {//
    		std::cerr << "Input Error!\n\n";//
    		std::cin.clear();//
    		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//
    	}//
    	while (std::cout << "Please enter the maximal count of attempts to guess: ",//
    		!(std::cin >> max_attempts)) {//
    		std::cerr << "Input Error!\n\n";//
    		std::cin.clear();//
    		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//
    	}//
    }//
    //
    struct game_result_t//
    {//
    	int attempts;//
    	long long time;//
    	bool won;//
    };//
    //
    class highscore_t//
    {//
    	friend std::ostream& operator<<(std::ostream &, highscore_t const &);//
    public://
    	struct entry_t//
    	{//
    		std::string name;//
    		int attempts;//
    		long long time;//
    	};//
    //
    private://
    	static char const *filename;//
    	std::multiset<entry_t> highscore;//
    //
    public://
    	highscore_t();//
    	void insert(std::string const &player_name, game_result_t const &result);//
    	void clear() { highscore.clear(); }//
    	void write() const;//
    };//
    //
    char const *highscore_t::filename = "score.txt";//
    //
    std::istream& operator>>(std::istream &is, highscore_t::entry_t &entry)//
    {//
    	is >> entry.name >> entry.attempts >> entry.time;//
    	return is;//
    }//
    //
    std::ostream& operator<<(std::ostream &os, highscore_t::entry_t const &entry)//
    {//
    	os << entry.name << '\t' << entry.attempts << '\t' << entry.time;//
    	return os;//
    }//
    //
    highscore_t::highscore_t()//
    {//
    	std::ifstream is{ filename };//
    	if (!is) {//
    		std::cerr << "Error reading \"" << filename << "\"!\n\n";//
    		return;//
    	}//
    	//
    	entry_t entry;//
    	while (is >> entry)//
    		highscore.insert(entry);//
    }//
    //
    void highscore_t::insert(std::string const &player_name, game_result_t const &result)//
    {//
    	if (!result.won)//
    		return;//
    	//
    	highscore.insert({ player_name, result.attempts, result.time });//
    	//
    	if (highscore.size() > 20) {//
    		auto new_end{ highscore.begin() };//
    		std::advance(new_end, 20);//
    		highscore.erase(new_end, highscore.end());//
    	}//
    }//
    //
    void highscore_t::write() const//
    {//
    	std::ofstream os{ filename, std::ios_base::trunc };//
    	if (!os) {//
    		std::cerr << "Couldn't write highscore list to \"" << filename << "\"!\n\n";//
    		return;//
    	}//
    	//
    	for (auto &entry : highscore)//
    		os << entry << '\n';//
    }//
    //
    bool operator<(highscore_t::entry_t const &lhs, highscore_t::entry_t const &rhs)//
    {//
    	return lhs.attempts < rhs.attempts;//
    }//
    //
    std::ostream& operator<<(std::ostream &os, highscore_t const &highscore)//
    {//
    	for (auto &entry : highscore.highscore)//
    		os << entry << '\n';//
    	os.put('\n');//
    	return os;//
    }//
    //
    game_result_t play(setup_t &setup)//
    {//
    	auto start_time{ std::chrono::high_resolution_clock::now() };//
    	int number_to_guess{ setup.get_new_number_to_guess() };//
    	int lower_bound{}, upper_bound{ std::numeric_limits<int>::max() };//
    	bool lower_bound_set{ false }, upper_bound_set{ false };//
    	int guess{};//
    	game_result_t result{};//
    	//
    	do {//
    		while (std::cout << "\nYour guess #" << ++result.attempts << ": ",//
    		       !(std::cin >> guess)) {//
    			std::cerr << "Input Error!\n";//
    			std::cin.clear();//
    			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//
    		}//
    		if (guess == -123) {//
    			std::cout << "Number to guess: " << number_to_guess << "\n";//
    			--result.attempts;//
    			guess = std::numeric_limits<int>::max();
    			continue;//
    		}//
    		if (guess == -456) {//
    			std::cout << "Attempts: ";//
    			std::cin >> result.attempts;//
    			std::cout << "Time: ";//
    			std::cin >> result.time;//
    			result.won = true;//
    			return result;//
    		}//
    		if (guess > number_to_guess && guess <= upper_bound) {//
    			upper_bound = guess;//
    			upper_bound_set = true;//
    		}//
    		else if (guess < number_to_guess && guess >= lower_bound) {//
    			lower_bound = guess;//
    			lower_bound_set = true;//
    		}//
    		std::cout << ( lower_bound_set ? std::to_string(lower_bound) : "???"s ) << " < X < "//
    		          << ( upper_bound_set ? std::to_string(upper_bound) : "???"s ) << "\n\n";//
    	//
    	} while ( (guess != number_to_guess) && guess >= 0 &&//
    	          (!setup.get_max_attempts() || result.attempts < setup.get_max_attempts()));//
    	//
    	result.time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - start_time).count();//
    	result.won = guess == number_to_guess;//
    	//
    	if (guess >= 0)//
    		std::cout << "\nYour guessed: " << guess;//
    	std::cout << "\nNumber to guess: " << number_to_guess//
    	          << "\nAttempts: " << result.attempts << "\nTime: " << result.time << '\n';//
    	//
    	return result;//
    }//
    //
    int main()//
    {//
    	highscore_t highscore;//
    	setup_t setup;//
    	//
    	std::cout << "Name: ";//
    	std::string player_name;//
    	std::cin >> player_name;//
    	//
    	int choice{};//
    	do {//
    		do {//
    			std::cout << "\n1. Play\n2: Highscore\n3: Setup\n4: Exit\n\nYour choice: ";//
    			if (!( std::cin >> choice )) {//
    				std::cin.clear();//
    				std::cin.ignore(std::numeric_limits<std::streamsize>::max());//
    				std::cerr << "Input Error!\n\n";//
    			}//
    		} while (choice < 1 || choice > 4);//
    		//
    		switch (choice) {//
    		case 1://
    			highscore.insert(player_name, play(setup));//
    			break;//
    		case 2://
    			std::cout << "\nHighscore:\n" << highscore;//
    			break;//
    		case 3://
    			setup.print();//
    			setup.alter();//
    			setup.write();//
    			{//
    				char ch;//
    				while (std::cout << "Clear highscore list (y/n)? ",//
    				       !(std::cin >> ch) || (ch != 'y' && ch != 'n')) {//
    						std::cin.clear();//
    						std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//
    						std::cerr << "Input Error!\n\n";//
    				}//
    				if (ch == 'y')//
    					highscore.clear();//
    			}//
    			break;//
    		}//
    	} while (choice != 4);//
    	//
    	std::cout << "\nHighscore:\n" << highscore;//
    	highscore.write();//
    	setup.write();//
    }//
    

    sogar

    @pale sagte in Suche Programmierer.:

    Kommentierter Quelltext, bei dem jede Zeile kommentiert ist

    👍



  • Wow. Wenn der das seinem Lehrer zeigt, wird der erst mal 5 Minuten staunen und dann zu den Kommentaren fragen, was das soll 😃


  • Mod

    Ihr haltet euch im Gegensatz zu mir nicht an den Sinn der Regel. Wenn ihr zeigen wollte, dass die Regel dumm ist, dann müsst ihr sie ganz normal wie gedacht anwenden (siehe mein Code). Dass irgendein Klugscheißer jede Regel irgendwie verdrehen kann ist kein Kunststück und kein Argument gegen die Regel.



  • @seppj sagte in Suche Programmierer.:

    Wenn ihr zeigen wollte, dass die Regel dumm ist, dann müsst ihr sie ganz normal wie gedacht anwenden (siehe mein Code).

    Genau das habe ich mir anfangs auch überlegt/vorgenommen zu tun: jedes Token ganz trocken und sinnfrei zu beschreiben, ähnlich wie in Deinem Beispiel1). Nur habe ich mich dann doch aus Faulheit bei ~280 Zeilen für das Mindestmaß entschieden, das die Aufgabenstellung erfüllt.

    1: Wobei mir Deine Kommentare fast schon zu nützlich und ausführlich sind. Gegenvorschlag:

    #include <iostream>  // includes iostream
    using namespace std;  // a using directive
    // a line without any statement
    int main() // defines the function main taking no arguments returning an integer
    { // an opening curly bracket
    	cout << "Hello World\n";   // inserts "Hello World\n" into the object referred to by cout
    	return 0;  // returns the value 0
    }  // a closing curly bracket
    


  • @swordfish sagte in Suche Programmierer.:

    Nur habe ich mich dann doch aus Faulheit bei ~280 Zeilen für das Mindestmaß entschieden, das die Aufgabenstellung erfüllt.

    Ist // denn schon ein Kommentar oder erst das Nachfolgende bis zum Zeilenende?



  • @dirkb sagte in Suche Programmierer.:

    Ist // denn schon ein Kommentar oder erst das Nachfolgende bis zum Zeilenende?

    Da // einen Kommentar einleitet ... natürlich! *pfeifend wegschländer*



  • @swordfish

    Es wird ja nicht verlangt, dass der Kommentar einen Bezug zur programmierten Zeile hat.

    Z.B. die "Ode an einen kleinen grünen Kittklumpen, den ich eines Sommermorgens in meiner Achselhöhle fand." sollte das zukünftige Verlangen nach Kommentaren in jeder Zeile vermindern.


  • Mod

    @swordfish sagte in Suche Programmierer.:

    1: Wobei mir Deine Kommentare fast schon zu nützlich und ausführlich sind.

    Das war der Plan. Ich habe die Regel nach Bestem Wissen und Gewissen genau so angewendet wie sie gedacht ist. Trotzdem, oder gerade deswegen, ist das Ergebnis ziemlicher Unfug. So zeigt man, dass die Regel absurd ist, denn das durch die Regelung erhoffte Ergebnis (Nachvollziehbarkeit, Lesbarkeit) wird gerade aufgrund der Regel verfehlt.

    @Pale: Falls du nicht nachvollziehen kannst, wieso sich alle über Regel 12 amüsieren: Es gilt als ziemlich schlechter Stil, wenn Code eines Kommentars bedarf. Guter Code ist selbsterklärend, und es sollte die absolute Ausnahme sein, dass man jemals eine Zeile kommentieren muss, um zu erklären, was sie tut. Wenn das öfters nötig ist, ist das ein deutlicher Code-Smell, ein Zeichen für schlechten Code/Programmierung. Kommentare setzt man üblicherweise zur Dokumentation ein, was eine Funktion/Klasse tut und wie sie zu benutzen ist ("Diese Funktion liefert den Sinus des Arguments x"); als Hinweis für andere Programmierer ("Die Längenprüfung hier ist wichtig, sonst bekommt man einen Indexfehler wenn das Suchergebnis leer ist"); oder als allgemeinen Kommentar zu einem Codestück ("Hier wird der Holgensteiner-Clusteringalgorithmus implementiert, wie er in JoCS 24, pp. 456-0487 beschrieben wird").



  • @seppj sagte in Suche Programmierer.:

    Ich habe die Regel nach Bestem Wissen und Gewissen genau so angewendet wie sie gedacht ist.

    Denken spreche ich dem Aufgabensteller zumindest für die Zeit der Formulierung von Punkt 12 einfach mal ab. Und falls doch steht nirgends in der Aufgabe, daß es nötig sei zu erraten, welche verkorksten kognitiven Prozesse in dessen Birne liefen. Ich bin immer noch der Meinung, daß mein lückenlos kommentierter Code der Aufgabenstellung voll und ganz genügt.



  • aber gut, ich will ja keinen Punkteabzug riskieren:

    #include <fstream>  // includes fstream
    #include <string>   // includes string
    #include <set>      // includes set
    #include <iterator> // includes iterator
    #include <limits>   // includes limits
    #include <chrono>   // includes chrono
    #include <random>   // includes random
    // a line without any statement
    using namespace std::string_literals; // a using directive concerning std::string_literals
    // a line without any statement
    class setup_t // begins the declaration of a class named setup_t
    {// opening curly bracket
    	static char const *filename; // declares a static pointer to const char named filename
    	std::random_device rd; // declares a std::random_device named rd
    	std::mt19937 generator; //declares a std::mt19937 named generator
    	int max_number; // declares an integer named max_number
    	int max_attempts; // declares an integer named max_attempts
    public: // an access specifier
    	setup_t(); // declares a constructor of a class named setup_t
    	int get_max_attempts() const { return max_attempts; } // defines a const qualified function named get_max_attempts returning an integer, namely max_attempts
    	int get_new_number_to_guess(); // declares a function named get_new_number_to_guess returning an integer
    	void write() const; // defines a const qualified function named write
    	void print() const; // defines a const qualified function named print
    	void alter(); // defines a function named alter
    }; // a closing curly bracket followed by a semicolon
    // a line without any statement
    char const *setup_t::filename{ "setup.txt" }; // defines a static pointer to const char named filename and initializes it to point to the string "setup.txt"
    // a line without any statement
    setup_t::setup_t()// begins the definition of a constructor of class setup_t
    	: rd{}, // default-initializes rd
    	generator{ rd() }, // initializes generator with the result of rd()
    	max_number{ 100 }, // initializes max_number to 100
    	max_attempts{ 10 } // initializes max_attempts to 10
    { // an opening curly bracket
    	int number{}; // declares and defines an integer named number
    	int attempts{}; // declares and defines an integer named attempts
    	std::ifstream is{ filename }; // declares and defines a std::ifstream initialized with filename
    	if (!(is && (is >> number >> attempts))) { // an if statement evaluating !(is && (is >> number >> attempts))
    		std::cerr << "Error reading game settings from \"" << filename << "\"!\nReverting to defaults.\n\n"; // inserts "Error reading game settings from \"", filename and "\"!\nReverting to defaults.\n\n" into the object referred to by std::cerr
    		return; // returns from the function
    	} // a closing curly bracket
    	max_number = number; // assigns number to max_number
    	max_attempts = attempts; // assigns attempts to max_attempts
    } // a closing curly bracket
    // a line without any statement
    int setup_t::get_new_number_to_guess() // begins the definition of a function named get_new_number_to_guess
    { // an opening curly backet
    	std::uniform_int_distribution<> distribution{ 0, max_number }; // declares and defines a std::uniform_int_distribution<> named distribution and initializes it with 0 and max_number
    	return distribution(generator); // returns the return value 
    } // a closing curly bracket
    // a line without any statement
    void setup_t::write() const // begins the definition of a function named write which is const spezified
    { // an opening curly bracket
    	std::ofstream os{ filename, std::ios::trunc }; // declares and defines a std::ofstream named os initialized with filename and std::ios::trunc
    	if (!(os && (os << max_number << ' ' << max_attempts))) { // an if statement evaluating !(os && (os << max_number << ' ' << max_attempts))
    		std::cerr << "Error writing game settings to \"" << filename << "\"!\n\n"; // inserts "Error writing game settings to \"", filename and "\"!\n\n" into the object referred to by std::cerr
    	} // a closing curly backet
    } // a closing curly backet
    // a line without any statement
    void setup_t::print() const // begins the definition of a function named print which is const qualified
    { // an opening curly bracket
    	std::cout << "\nCurrent Setup:\nMaximal number to guess: " << max_number //inserts "\nCurrent Setup:\nMaximal number to guess: ", max_number,
    		<< "\nMax attempts to guess the number (0 = indefinite): " << max_attempts << "\n\n"; // "\nMax attempts to guess the number (0 = indefinite): ", max_attempts and "\n\n" into the object referred to by std::cout
    } // a closing curly bracket
    // a line without any statement
    void setup_t::alter() // begins the definition of a function named alter
    { // an opening curly backet
    	while (std::cout << "Please enter the maximal number to guess: ", // a while statement inserting "Please enter the maximal number to guess: " into the object referred to by std::cout and then
    		!(std::cin >> max_number)) { // evaluating !(std::cin >> max_number)
    		std::cerr << "Input Error!\n\n"; // inserts "Input Error!\n\n" into the object referred to by std::cerr
    		std::cin.clear(); // calls the function clear on the object referred to by std::cin
    		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // calls the function ignore on the object referred to by std::cin passing the result of the function called std::numeric_limits<std::streamsize>::max() and '\n' as parameters
    	} // a closing curly bracket
    	while (std::cout << "Please enter the maximal count of attempts to guess: ", // a while statement inserting "Please enter the maximal count of attempts to guess: " into the object referred to by std::cout and then
    		!(std::cin >> max_attempts)) { // evaluating !(std::cin >> max_attempts)
    		std::cerr << "Input Error!\n\n"; // inserts "Input Error!\n\n" into the object referred to by std::cerr
    		std::cin.clear(); // calls the function clear on the object referred to by std::cin
    		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // calls the function ignore on the object referred to by std::cin passing the result of the function called std::numeric_limits<std::streamsize>::max() and '\n' as parameters
    	} // a closing curly bracket
    } // a closing curly bracket
    // a line without any statement
    struct game_result_t // begins the declaration of a struct named game_result_t
    { // an opening curly bracket
    	int attempts; // declares a variable of type int named attempts
    	long long time; // declares a variable of type long long named time
    	bool won; // declares a variable of type bool naed won
    }; // a closing curly bracket followed by a semicolon
    // a line without any statement
    class highscore_t // begins the declaration of a class named highscore_t
    { // an opening curly bracket
    	friend std::ostream& operator<<(std::ostream &, highscore_t const &); // declares std::ostream& operator<<(std::ostream &, highscore_t const &) to be a friend of the class highscore_t
    public: // an access specifier
    	struct entry_t // declares a struct named entry_t
    	{ // an opening curly bracket
    		std::string name; // declares a variable of type std::string named name
    		int attempts; // declares a variable of type int named attempts
    		long long time; // declares a variable of type long long named time
    	}; // a closing curly bracket followed by a semicolon
    private: // an access specifier
    	static char const *filename; // declares a static variable of type pointer to const char named filename
    	std::multiset<entry_t> highscore; // declares a variable of type std::multiset<entry_t> named highscore
    public: // an access specifier
    	highscore_t(); // declares a constructor of class highscore_t
    	void insert(std::string const &player_name, game_result_t const &result); // declares a function named insert which takes a parameter of type reference to const std::string named player_name and a parameter of type reference to const game_result_t named result
    	void clear() { highscore.clear(); } // declares and defines a function named clear
    	void write() const; // declares a function named write which is const qualified
    }; // closing curly brackets
    // a line without any statement
    char const *highscore_t::filename = "score.txt"; // defines a static pointer to const char named filename and initializes it to point to the string "score.txt"
    // a line without any statement
    std::istream& operator>>(std::istream &is, highscore_t::entry_t &entry) // begins the definition of a function named operator>> taking a parameter of type reference to std::istream name is and a parameter of type reference to highscore_t::entry_t named entry returning a reference to std::istream
    { // an opening curly bracket
    	is >> entry.name >> entry.attempts >> entry.time; // extracts a value of std::tring, a value of type int and a value of type long long from the object referred to by is and stores them in entry.name, entry.attempts and entry.time, respectively
    	return is; // returns is
    } // a closing curly bracket
    // a line without any statement
    std::ostream& operator<<(std::ostream &os, highscore_t::entry_t const &entry) // begins the definition of a function name operator<< taking a parameter of type reference to std::ostream named os and a parameter of type reference to const highscore_t::entry_t named entry returning a reference to std::ostream
    { // an opening curly bracket
    	os << entry.name << '\t' << entry.attempts << '\t' << entry.time; // inserts entry.name, '\t', entry.attempts, '\t' and entry.time into the object referred to by os
    	return os; // returns os
    } // a closing curly bracket
    // a line without any statement
    highscore_t::highscore_t() // begins the definition of a constructor for class highscore_t
    { // an opening curly bracket
    	std::ifstream is{ filename }; // declares and defines a variable is which is initialized with filename
    	if (!is) { // an if statement evaluating !is
    		std::cerr << "Error reading \"" << filename << "\"!\n\n"; // inserts "Error reading \"", filename and "\"!\n\n" into the object referred to by std::cerr
    		return; // a return statement
    	} // a closing curly bracket
    	// a line without any statement
    	entry_t entry; // declares a variable of type entry_t named entry
    	while (is >> entry) // a while statement evaluating is >> entry
    		highscore.insert(entry); // calls the function insert on the object highscore passing entry as an argument
    } // a closing curly bracket
    // a line without any statement
    void highscore_t::insert(std::string const &player_name, game_result_t const &result) // begins the definition of a function called insert taking a reference to const std::string named player_name and a reference to const game_result_t named result as parameters
    { // an opening curly bracket
    	if (!result.won) // an if statement evaluating !result.won
    		return; // a return statement
    	// a line without any statement
    	highscore.insert({ player_name, result.attempts, result.time }); // calls the function insert on the object highscore passing a temporary entity of type entry_t initialized with player_name, result.attempts and result.time
    	// a line without any statement
    	if (highscore.size() > 20) { // an if statement evaluating highscore.size() > 20
    		auto new_end{ highscore.begin() }; // declares and defines a variable of type std::multiset<entry_t>::iterator which is initialized with the result of a call to highscore.begin()
    		std::advance(new_end, 20); // calls the function std::advance passing new_end and 20 as parameters
    		highscore.erase(new_end, highscore.end()); // calls the function erase on the object highscore passing new_end and the result of a call to highscore.end() as parameters
    	} // a closing curly bracket
    }// a closing curly bracket
    // a line without any statement
    void highscore_t::write() const // begins the definition of a function named write which is const qualified
    { // an opening curly bracket
    	std::ofstream os{ filename, std::ios::trunc }; // declares and defines a variable of type std::ofstream named os initialized with filename and std::ios::trunc
    	if (!os) { // an if statement evaluating !os
    		std::cerr << "Couldn't write highscore list to \"" << filename << "\"!\n\n"; // inserts "Couldn't write highscore list to \"", filename and "\"!\n\n" into the object referred to by std::cerr
    		return; // a return statement
    	} // a closing curly bracket
    	// a line without any statement
    	for (auto &entry : highscore) // a for statement looping through each entry contained in highscore
    		os << entry << '\n'; // inserts entry and '\n' into the object referred to by os
    } // a closing curly bracket
    // a line without any statement
    bool operator<(highscore_t::entry_t const &lhs, highscore_t::entry_t const &rhs) // begins the definition of a function named operator< taking two parameters of type reference to const highscore_t::entry_t named lhs and rhs returning a value of type bool
    { // an opening curly bracket
    	return lhs.attempts < rhs.attempts; // returns the result of lhs.attempts < rhs.attempts
    }// a closing curly bracket
     // a line without any statement
    std::ostream& operator<<(std::ostream &os, highscore_t const &highscore) // begins the definition of a function named operator<< taking a parameter of type reference to std::ostream named os and a parameter of type reference to const highscore_t named highscore returning a reference to std::ostream
    { // an opening curly bracket
    	for (auto &entry : highscore.highscore) // a for statement looping through each entry contained in highscore.highscore
    		os << entry << '\n'; // inserts entry and '\n' into the object referred to by os
    	os.put('\n'); // calls the function put with a parameter of the value '\n' on the object referred to by os
    	return os; // returns the value of the variable os
    }// a closing curly bracket
     // a line without any statement
    game_result_t play(setup_t &setup) // begins the definition of a function named play taking one parameter of type reference to setup_t called setup returning a value of type game_result_t
    { // an opening curly bracket
    	auto start_time{ std::chrono::high_resolution_clock::now() }; // declares and defines a variable of type std::chrono::time_point<std::chrono::steady_clock> which is initialized with the result of a call to std::chrono::high_resolution_clock::now()
    	int number_to_guess{ setup.get_new_number_to_guess() };// declares and defines a variable of type int which is initialized with the result of a call to setup.get_new_number_to_guess()
    	int lower_bound{}, upper_bound{ std::numeric_limits<int>::max() }; // declares and defines two variables of type int named lower_bound which is zero-initialized and upper_bound which is initialized with the result of a call to std::numeric_limits<int>::max()
    	bool lower_bound_set{ false }, upper_bound_set{ false }; // declares and defines two variables of type bool named lower_bound_set and upper_bound set which are both initialized with the value false
    	int guess{}; // declares and defines a variable of type int named guess
    	game_result_t result{}; // declares and defines a variable of type game_result_t named result
    	// a line without any statement
    	do { // a do ...
    		while (std::cout << "\nYour guess #" << ++result.attempts << ": ", // a while statement inserting "\nYour guess #", ++result.attempts and ": " into the object referred to by std::cout and
    			   !(std::cin >> guess)) { // evaluating !(std::cin >> guess)
    			std::cerr << "Input Error!\n"; // inserts "Input Error!\n" into the object referred to by std::cerr
    			std::cin.clear(); // calls the function clear on the object referred to by std::cin
    			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // calls the function ignore on the object referred to by std::cin passing the result of the function called std::numeric_limits<std::streamsize>::max() and '\n' as parameters
    		} // a closing curly bracket
    		if (guess == -123) { // an if statement evaluating guess == -123
    			std::cout << "Number to guess: " << number_to_guess << '\n'; // inserts "Number to guess: ", number_to_guess and '\n' into the object referred to by std::cout
    			--result.attempts; // decrements result.attempts
    			guess = std::numeric_limits<int>::max(); // assigns the result of a call to std::numeric_limits<int>::max() to guess
    			continue; // continues the execution of its containing do...while loop at the end of the loop body
    		} // a closing curly bracket
    		if (guess == -456) { // an if statement evaluating guess == -456
    			std::cout << "Attempts: "; // inserts "Attempts: " into the object referred to by std::cout
    			std::cin >> result.attempts; // extracts a value of type int from the object referred to by std::cin and stores it in result.attempts
    			std::cout << "Time: "; // inserts "Time: " into the object referred to by std::cout
    			std::cin >> result.time; // extracts a value of type long long from the object referred to by std::cin and stores it in result.time
    			result.won = true; // assigns the value true to result.won
    			return result; // returns the value of the variable result
    		} // a closing curly bracket
    		if (guess > number_to_guess && guess <= upper_bound) { // an if statement evaluating guess > number_to_guess && guess <= upper_bound
    			upper_bound = guess; // assigns the value of guess to upper_bound
    			upper_bound_set = true; // assigns the value true to upper_bound_set
    		} // a closing curly bracket
    		else if (guess < number_to_guess && guess >= lower_bound) {//
    			lower_bound = guess; // assigns the value of guess to lower_bound
    			lower_bound_set = true; // assigns the value true to lower_bound_set
    		} // a closing curly bracket
    		std::cout << (lower_bound_set ? std::to_string(lower_bound) : "???"s) << " < X < " // inserts (lower_bound_set ? std::to_string(lower_bound) : "???"s), " < X < ",
    			<< (upper_bound_set ? std::to_string(upper_bound) : "???"s) << "\n\n"; // (upper_bound_set ? std::to_string(upper_bound) : "???"s) and "\n\n" into the object referred to by std::cout
    	// a line without any statement
    	} while ((guess != number_to_guess) && guess >= 0 && // ... while statement evaluating (guess != number_to_guess) && guess >= 0 &&
    		(!setup.get_max_attempts() || result.attempts < setup.get_max_attempts())); // (!setup.get_max_attempts() || result.attempts < setup.get_max_attempts())
    	// a line without any statement
    	result.time = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - start_time).count(); // assigns the result of std::chrono::duration_cast<std::chrono::seconds>(std::chrono::high_resolution_clock::now() - start_time).count() to result.time
    	result.won = guess == number_to_guess; // assigns the result of guess == number_to_guess to result.won
    	// a line without any statement
    	if (guess >= 0) // an if statement evaluating guess >= 0
    		std::cout << "\nYour guessed: " << guess; // inserts "\nYour guessed: " and guess into the object referred to by std::cout
    	std::cout << "\nNumber to guess: " << number_to_guess // inserts "\nNumber to guess: ", number_to_guess, 
    		<< "\nAttempts: " << result.attempts << "\nTime: " << result.time << '\n'; // "\nAttempts: ", result.attempts, "\nTime: ", result.time and '\n' into the object referred to by std::cout
    	// a line without any statement
    	return result; // returns the value of the variable result
    } // a closing curly bracket
     // a line without any statement
    int main() // begins the definition of a function named main
    { // an opening curly bracket
    	highscore_t highscore; // declares a variable of type highscore_t named highscore
    	setup_t setup; // declares a variable of type setup_t named setup
    	// a line without any statement
    	std::cout << "Name: "; // inserts "Name: " into the object referred to by std::cout
    	std::string player_name; // declares a variable of type std::string named player_name
    	std::cin >> player_name; // extracts a std::string from the object referred to by std::cin and stores it in the variable player_name
    	// a line without any statement
    	int choice{}; // declares and defines a variable of type int named choice
    	do { // a do ...
    		do { // a do ...
    			std::cout << "\n1. Play\n2: Highscore\n3: Setup\n4: Exit\n\nYour choice: "; // inserts "\n1. Play\n2: Highscore\n3: Setup\n4: Exit\n\nYour choice: " into the object referred to by std::cout
    			if (!(std::cin >> choice)) { // an if statement evaluating !(std::cin >> choice)
    				std::cin.clear(); // calls the function clear on the object referred to by std::cin
    				std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // calls the function ignore on the object referred to by std::cin passing the result of the function called std::numeric_limits<std::streamsize>::max() and '\n' as parameters
    				std::cerr << "Input Error!\n\n"; // inserts "Input Error!\n\n" into the object referred to by std::cerr
    			} // a closing curly bracket
    		} while (choice < 1 || choice > 4); // ... while statement evaluating choice < 1 || choice > 4
    		// a line without any statement
    		switch (choice) { // a switch statement evaluating the variable choice
    		case 1: // a case label for value 1
    			highscore.insert(player_name, play(setup)); // calls the functio insert on the object highscore with player_name and the result of a call to play(setup) as its parameters
    			break; // a break statement exiting the switch statement
    		case 2: // a case label for value 2
    			std::cout << "\nHighscore:\n" << highscore; // inserts "\nHighscore:\n" and highscore into the object referred to by std::cout
    			break; // a break statement exiting the switch statement
    		case 3: // a case label for value 3
    			setup.print(); // calls the function print on the object setup
    			setup.alter(); // calls the function alter on the object setup
    			setup.write(); // calls the function write on the object setup
    			{ // an opening curly bracket
    				char ch; // declares a variable of type char named ch
    				while (std::cout << "Clear highscore list (y/n)? ", // a while statement inserting "Clear highscore list (y/n)? " into the object referred to by std::cout and then
    					!(std::cin >> ch) || (ch != 'y' && ch != 'n')) { // evaluating !(std::cin >> ch) || (ch != 'y' && ch != 'n')
    					std::cin.clear(); // calls the function clear on the object referred to by std::cin
    					std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // calls the function ignore on the object referred to by std::cin passing the result of the function called std::numeric_limits<std::streamsize>::max() and '\n' as parameters
    					std::cerr << "Input Error!\n\n"; // inserts "Input Error!\n\n" into the object referred to by std::cerr
    				} // a closing curly bracket
    				if (ch == 'y') // an if statement evaluating ch == 'y'
    					highscore.clear(); //calls the function clear on the object highscore
    			} // a closing curly bracket
    			break; // a break statement exiting the switch statement
    		} // a closing curly bracket
    	} while (choice != 4); // ... while statement evaluating choice != 4
    	// a line without any statement
    	std::cout << "\nHighscore:\n" << highscore; // inserts "\nHighscore:\n" and highscore into the object referred to by std::cout
    	highscore.write(); // calls the function write on the object highscore
    	setup.write(); // calls the function write on the object setup
    } // a closing curly bracket
    

Anmelden zum Antworten