Dartspiel mit Mittelwert Ermittlung



  • LowesRacing schrieb:

    Mit C jedoch schöner 😉

    Nu mach mich nicht fertig!
    Dachte, C++ statt C. Haste doch auch im erstwen Posting geschrieben.
    Falls nur C geht, sags schnell. Dann müßte der Thread nochmal wandern, um die Leute zu erreichen, die C aber kein C++ lesen.



  • volkard schrieb:

    Der Code wird wirklich übersichtlich. Ich hoffe, daß jemand ihn aus Spaß gerade mal fertigmacht, kann 30 Minuten dauern oder wenn jemand so lahm wie ich ist auch 3 Stunden, die aber viel Spaß machen.

    Aber klar. Wenn man sich an die tolle konzeptionelle Vorarbeit von Euch beiden hält, ist das wirklich ein Klax. Muss man ja dank Euch nur noch hinschreiben! 👍

    #include <limits>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    
    enum mode_t { MODE_SUM, MODE_SINGLE, MODE_MAX };
    
    std::istream & operator>>( std::istream & is, mode_t & mode )
    {
    	unsigned m;
    	is >> m;	
    	if( 0 < m && m <= MODE_MAX )
    		mode = static_cast< mode_t >( m - 1 );
    	else is.setstate( std::ios::badbit );
    	return is;
    }
    
    void clear( std::istream & is, char const * error_msg = nullptr )
    {	
    	if( error_msg )
    		std::cerr << error_msg;
    	is.clear();
    	is.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );
    }
    
    int main()
    {
    	char const * modes[]   { "[1] enter the sum", "[2] enter single darts" };
    	char const * error_msg { "Input error!\n\n" };
    
    	mode_t mode;
    	std::size_t num_players;
    
    	while( std::cout << "Do you want to ...\n",
    	       [&](){ for( auto m : modes ) std::cout << m << '\n'; }(),
    		   std::cout << "per player? ",
    		   !( std::cin >> mode ) ||
    		   std::cout << "\nNumber of players: ",
    	       !( std::cin >> num_players ) || !num_players
    	) clear( std::cin, error_msg );
    
    	std::vector< unsigned > scores( num_players, 501 );
    	std::size_t round  {};
    	std::size_t winner {};
    
    	while( !winner ) {
    		std::cout << "\n\nRound #" << ++round << ":\n";
    		unsigned player{};
    		std::transform( std::begin( scores ), std::end( scores ), std::begin( scores ),
    			[&]( unsigned score ) -> unsigned {
    				if( winner )
    					return score;
    				std::cout << "\nPlayer #" << ++player << ": ";
    				unsigned sum{};
    				switch( mode ) {
    					case MODE_SUM:
    						while( !( std::cin >> sum ) )
    							clear( std::cin, error_msg );
    						winner = score - sum ? 0 : player;
    						break;
    					case MODE_SINGLE:
    						std::cout.put( '\n' );
    						for( unsigned i{}, tmp; i < 3 && !( ( winner = ( score - sum ? i - i:
    						   player ) ) && ( player = num_players ) ) && score - sum <= 501; sum += tmp )
    							while( std::cout << ++i << ": ", !( std::cin >> tmp ) )
    								clear( std::cin, error_msg );
    						break;
    				}
    				return score - sum > 501 ? std::cout << "\nOh, noooo!\n", score : score - sum;
    			}
    		);
    
    		for( auto s : scores )
    			std::cout << ( player == num_players ? player ^= player, "\n\nP" : "P" )
    			          << ++player << ": " << s << ( player + 1 == num_players ? "\n\n" : "\t\t" );	
    	}
    
    	std::cout << "\nThe winner is player #" << winner << "!\n\nAverage scores per round:\n\n";
    	for( std::size_t i{}; i < scores.size(); std::cout << 'P' << i + 1 << ": " <<
    		( 501 - scores[ i ] ) / static_cast< double >( i < winner ? round : round - 1 ) << "\t\t", ++i );
    
    	std::cout << "\n\n";
    }
    

    Zwecks Übersichtlichkeit hab' ich mich auch sehr bemüht, möglichst kurzen und kompakten Code zu schreiben.

    // edit: Einzig über die Rundenbestimmung zur Mittelwertberechnung muss man sich ein bisschen Gedanken machen, haben doch in der Letzten Runde unter umständen nicht mehr alle Spieler punkten können. 🤡



  • Swordfish schrieb:

    Zwecks Übersichtlichkeit hab' ich mich auch sehr bemüht, möglichst kurzen und kompakten Code zu schreiben.

    Was auch zuverlässig dafür sorgt, daß LowesRacing, falls das eine Hausaufgabe war, den Code nicht so abgeben kann, Du Schelm! 😃

    Ich denke, den

    for( auto s : scores )
                std::cout << ( player == num_players ? player ^= player, "\n\nP" : "P" )
                          << ++player << ": " << s << ( player + 1 == num_players ? "\n\n" : "\t\t" );
    

    muss ich ausdrucken und in mein Poesiealbum kleben und irgendwann meinen Enkeln zeigen.



  • volkard schrieb:

    Ich denke, den

    ...
    

    muss ich ausdrucken und in mein Poesiealbum kleben und irgendwann meinen Enkeln zeigen.

    Da finde ich den hier noch besser 😃

    Swordfish schrieb:

    while( std::cout << "Do you want to ...\n",
               [&](){ for( auto m : modes ) std::cout << m << '\n'; }(),
               std::cout << "per player? ",
               !( std::cin >> mode ) ||
               std::cout << "\nNumber of players: ",
               !( std::cin >> num_players ) || !num_players
        ) clear( std::cin, error_msg );
    


  • Schon mal danke für die Bemühungen 🙂 Nein es ist keine Hausaufgabe war nur für den reinen privaten Gebrauch gedacht 🙂
    Noch eine Frage zu dir Swordfish, dein Programm wirft bei mir noch paar Fehler aus, weiß noch nicht so recht wie ich Sie beheben kann. Habe eine neue Projektmappe erstellt, und eingefügt, mit Microsoft Visual Studio. 😕



  • LowesRacing schrieb:

    Schon mal danke für die Bemühungen 🙂 [...]

    Kein Problem, ist doch gern geschehn!

    LowesRacing schrieb:

    Noch eine Frage zu dir Swordfish, dein Programm wirft bei mir noch paar Fehler aus, weiß noch nicht so recht wie ich Sie beheben kann.

    Leider weiß ich nicht, was die "noch ein paar Fehler" bei dir genau sind, und kann dir deshalb zu den Fehlern auch nichts sagen. Im falle von Visual Studio solltest du dir aber unbeding VS2013 + Visual C++ Compiler November 2013 CTP besorgen.



  • [code="cpp"]
    // Dartspielen.cpp : Definiert den Einstiegspunkt für die Anwendung.
    //

    #include "stdafx.h"
    #include "Dartspielen.h"
    #include <limits>
    #include <algorithm>
    #include <vector>
    #include <iostream>

    enum mode_t { MODE_SUM, MODE_SINGLE, MODE_MAX };

    std::istream & operator>>(std::istream & is, mode_t & mode)
    {
    unsigned m;
    is >> m;
    if (0 < m && m <= MODE_MAX)
    mode = static_cast< mode_t >(m - 1);
    else is.setstate(std::ios::badbit);
    return is;
    }

    void clear(std::istream & is, char const * error_msg = nullptr)
    {
    if (error_msg)
    std::cerr << error_msg;
    is.clear();
    is.ignore(std::numeric_limits< std::streamsize >::max(501), '\n');
    }

    int main()
    {
    char const * modes[] { "[1] enter the sum", "[2] enter single darts" };
    char const * error_msg{ "Input error!\n\n" };

    mode_t mode;
    std::size_t num_players;

    while (std::cout << "Do you want to ...\n",
    [&](){ for (auto m : modes) std::cout << m << '\n'; }(),
    std::cout << "per player? ",
    !(std::cin >> mode) ||
    std::cout << "\nNumber of players: ",
    !(std::cin >> num_players) || !num_players
    ) clear(std::cin, error_msg);

    std::vector< unsigned > scores(num_players, 501);
    std::size_t round{};
    std::size_t winner{};

    while (!winner) {
    std::cout << "\n\nRound #" << ++round << ":\n";
    unsigned player{};
    std::transform(std::begin(scores), std::end(scores), std::begin(scores),
    [&](unsigned score) -> unsigned {
    if (winner)
    return score;
    std::cout << "\nPlayer #" << ++player << ": ";
    unsigned sum{};
    switch (mode) {
    case MODE_SUM:
    while (!(std::cin >> sum))
    clear(std::cin, error_msg);
    winner = score - sum ? 0 : player;
    break;
    case MODE_SINGLE:
    std::cout.put('\n');
    for (unsigned i{}, tmp; i < 3 && !((winner = (score - sum ? i - i :
    player)) && (player = num_players)) && score - sum <= 501; sum += tmp)
    while (std::cout << ++i << ": ", !(std::cin >> tmp))
    clear(std::cin, error_msg);
    break;
    }
    return score - sum > 501 ? std::cout << "\nOh, noooo!\n", score : score - sum;
    }
    );

    for (auto s : scores)
    std::cout << (player == num_players ? player ^= player, "\n\nP" : "P")
    << ++player << ": " << s << (player + 1 == num_players ? "\n\n" : "\t\t");
    }

    std::cout << "\nThe winner is player #" << winner << "!\n\nAverage scores per round:\n\n";
    for (std::size_t i{}; i < scores.size(); std::cout << 'P' << i + 1 << ": " <<
    (501 - scores[i]) / static_cast< double >(i < winner ? round : round - 1) << "\t\t", ++i);

    std::cout << "\n\n";
    return 0;
    }
    Hier nochmal der komplette C++ Code, welchen ich übernommen habe von dir. Musste man doch nichts mehr dran ändern oder?



  • Hab grad nochmal eine Neue Mappe angelegt mit den richtigen Parametern jetzt hat es geklappt. 🙂

    lg LowesRacing 😉



  • volkard schrieb:

    Swordfish schrieb:

    Zwecks Übersichtlichkeit hab' ich mich auch sehr bemüht, möglichst kurzen und kompakten Code zu schreiben.

    Was auch zuverlässig dafür sorgt, daß LowesRacing, falls das eine Hausaufgabe war, den Code nicht so abgeben kann, Du Schelm! 😃

    Das war so natürlich so nicht beabsichtigt und irritiert mich jetzt ein wenig. Ich hoffe der Code ist für etwas vortgeschrittene Anfänger doch gut verständlich und ein wahrer Genuß beim Lesen! 😉



  • [code="cpp"]
    while( std::cout << "Do you want to ...\n",
    [&](){ for( auto m : modes ) std::cout << m << '\n'; }(),
    std::cout << "per player? ",
    !( std::cin >> mode ) ||
    std::cout << "\nNumber of players: ",
    !( std::cin >> num_players ) || !num_players
    ) clear( std::cin, error_msg );
    [/code]

    Die Fett markierten Stellen raff ich jetzt nicht ganz, bzw. hab das noch nie gesehen. Ist das weil für die While Bedingung ne For Schleife mit "eingeundet" wird?

    Ps.: Irgendwie wollen die Code Tags nicht



  • Swordfish schrieb:

    Das war so natürlich so nicht beabsichtigt und irritiert mich jetzt ein wenig.

    std::size_t round  {};
    

    statt =0, was gemeint war.

    Jede Verwendung des Komma-Operators.

    Die Runde per transform/lamda zu machen.

    winner = score - sum ? 0 : player;
    

    - statt !=

    return score - sum > 501 ? std::cout << "\nOh, noooo!\n", score : score - sum;
    

    Jede Verwedung von ?:.

    player ^= player
    

    Naja, der ist unbetreitbar.



  • unsure110 schrieb:

    Die Fett markierten Stellen raff ich jetzt nicht ganz, bzw. hab das noch nie gesehen.

    Feature von C++11 namens lambda.



  • Volki, daß Dich Dein sonst brauchbarer Sinn für Humor und Satire jetzt so im Stich lässt, schockiert mich 😃


Anmelden zum Antworten