Würfelspiel Zehntausend



  • Hallo,

    ich arbeite im Moment an einer Konsolenversion des Würfelklassikers Zehntausend.

    Nun meine Frage:

    Aktuell fragt das Spiel zu Beginn nach der Anzahl der Spieler und entsprechend dieser Anzahl werden jeweils 6 Würfel geworfen. Nun soll das Spiel natürlich die Würfel anhand der Regeln auswerten (1 = 100 Punkte, 5 = 50 Punkte, Straßen, Päärchen, etc.) und die Punkte dementsprechend dem jeweiligen Spieler gutschreiben.

    Wie bekomme ich nun die Regeln richtig hinein?

    Mein Source:

    using namespace std;
    
    #pragma comment (lib, "winmm.lib")
    
    //Umlaute
    const unsigned char AE = static_cast<unsigned char>(142); 
    const unsigned char ae = static_cast<unsigned char>(132); 
    const unsigned char OE = static_cast<unsigned char>(153); 
    const unsigned char oe = static_cast<unsigned char>(148); 
    const unsigned char UE = static_cast<unsigned char>(154); 
    const unsigned char ue = static_cast<unsigned char>(129); 
    const unsigned char ss = static_cast<unsigned char>(225);
    //Umlaute
    
    int Spieler ; //Variable für die Anzahl der Spieler
    bool Spielerzahl = false;
    int Spieler_dran;
    int spielerpunkte;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	srand (timeGetTime ()); //Zufallsgenerator initialisieren
    
    int wuerfel; //Würfel initialisieren 
    
    	// = (rand()%6)+1
    	cout << "***********************" << endl;
    	cout << "* Zehntausend 1.0     *" << endl;
    	cout << "***********************" << endl;
    	cout << endl;
    	cout << endl;
    	while(Spielerzahl != true)
    	{//Beginn der While-Schleife
    
    	cout << "Wieviele Spieler wollen spielen? (bis zu 5)" << endl;
        cin >> Spieler;
    
    	if((Spieler < 1) || (Spieler > 5))
    	{ //WENN Spieler zu wenig/zu viel
    		cout << "falsche Spielerzahl" << endl;
    	} //Ende If zu wenig/zu viel
    
    	else
    	{ //ansonsten starten
    	 Spielerzahl = true;
    	 cout << "Es spielen " << Spieler << " Spieler mit." << endl;
    	} //ende else
    	} //Ende While-Schleife
    
    	//Spielbeginn
    
    	for(int i=0; i<Spieler; i++)
    	{
    	Spieler_dran = Spieler_dran + 1;
    	spielerpunkte = i;
    	cout << "Spieler " << Spieler_dran << " ist dran." << endl;
    	// Rundenbeginn
    	for(int i2=1;i2<7; i2++)
    	{
    
    		//Würfel werfen
    
    	wuerfel = (rand()%6)+1;
    
    	// Würfel ausgeben
    
    	cout << "W" << ue << "rfel " << i2 << ":" << wuerfel << endl;
    	if(wuerfel == 1)
    	{
    	spielerpunkte =  spielerpunkte + 100;
    	cout << "Punkte: " << spielerpunkte;
    	} //100 Punkte
    
    	} //Rundenende
    	} //Spielende
    
    	cout << "Das Programm endet hier!" << endl;
    	_getch();
    	return 0;
    
    }
    

    P.S.: Das der Schritt mit der 1 nicht richtig ist, habe ich bereits gemerkt, aber es war ein Versuch. Über einen richtigen Ansatz würde ich mich freuen.



  • Vielleicht ist es sehr leicht, vielleicht ist es gemein, vielleicht ist es unmenschlich schwer und Du mußt es Dir erstmal aus dem Kopf schlagen.
    Ist es unmenschlich schwer wie Kniffel?
    Zeig mal die ganzen Spielregeln.



  • volkard schrieb:

    Vielleicht ist es sehr leicht, vielleicht ist es gemein, vielleicht ist es unmenschlich schwer und Du mußt es Dir erstmal aus dem Kopf schlagen.
    Ist es unmenschlich schwer wie Kniffel?
    Zeig mal die ganzen Spielregeln.

    Die Spielregeln lauten wie folgt:

    Man hat 6 Würfel. Jeder Spieler würfelt zuerst einmal mit allen 6 Würfeln. Dann wird ausgewertet.

    1 x 1 = 100 Punkte
    1 x 5 = 50 Punkte
    2 x 5 = 1 Würfel 100 Punkte, der andere zählt nicht
    3 x 1 = 1000 Punkte und man braucht mindestens eine 5 in diesem Wurf oder eine 1 im nächsten
    3 x 1/2/3/4/5/6 = die gewürfelte Zahl x 100
    4 x 1 = 10.000 Punkte, muss ebenfalls mit einer 5 oder einer 1 im nächsten Wurf bestätigt werden
    4 x jede andere Zahl = die gewürfelte Zahl x 1000, muss bestätigt werden
    Straße (1,2,3,4,5,6) = 2500, bestätigung
    3 Päärchen (3 Zahlen jeweils 2 mal) 2500 Punkte, Bestätigung

    Man würfelt immer nur mit den Würfeln weiter, die keinen Zählwert haben. Ab 400 Punkten kann man seinen Zug beenden und die Punkte notieren. Hat man aber in einer Runde alle 6 Würfel verbraucht, also 6 wertbare Würfe, muss man mit allen weitermachen. Hat man in einem Wurf KEINE wertbaren Zahlen, wird der Zug mit 0 Punkten beendet.

    Ziel des Spiels ist es, als erster über 10.000 Punkte zu bekommen.



  • Also mit nur Menschenspielern ist das machbar und spannend und wird voll spaß machen zu programmieren.

    Jede Zeile der Auswertungsregeln wird eine Funktion. Die gibt ihre Punktzahl zurück, wenn sie zutrifft, oder 0 wenn nicht.
    Und dei Master-Auswertefunktion ruft de der Reihe nach auf und nimmt die beste.
    Manche Auswertefunktionen sind leicht, manche schwierig. Beim Überfliegen habe ich mich an zwei gar nicht rangetraut. Ist aber machbar. Vielleicht werden die schwierigen Auswertfunktionen ja viel leichter, wenn Du erstmal die einfachen hingekriegt hast. Ich drücke Dir die Daumen.

    Mach es erstmal nur mit einem Spieler.

    edit: Aber mit dem Bestätigen-Müssen, uihuihuih.
    Zu viele Variablen. Die würde man zusammen in eine Klasse stopfen und dann objektorientiert herangehen. Das wird doch nicht so einfach.



  • volkard schrieb:

    Also mit nur Menschenspielern ist das machbar und spannend und wird voll spaß machen zu programmieren.

    Jede Zeile der Auswertungsregeln wird eine Funktion. Die gibt ihre Punktzahl zurück, wenn sie zutrifft, oder 0 wenn nicht.
    Und dei Master-Auswertefunktion ruft de der Reihe nach auf und nimmt die beste.
    Manche Auswertefunktionen sind leicht, manche schwierig. Beim Überfliegen habe ich mich an zwei gar nicht rangetraut. Ist aber machbar. Vielleicht werden die schwierigen Auswertfunktionen ja viel leichter, wenn Du erstmal die einfachen hingekriegt hast. Ich drücke Dir die Daumen.

    Mach es erstmal nur mit einem Spieler.

    edit: Aber mit dem Bestätigen-Müssen, uihuihuih.
    Zu viele Variablen. Die würde man zusammen in eine Klasse stopfen und dann objektorientiert herangehen. Das wird doch nicht so einfach.

    Du meinst also, ich soll jetzt z.B. für hundert Punkte eine eigene Funktion erstellen, für 50, 1000 usw.?



  • Ohne auf Bestätigung eingegangen zu sein und nur die allerleichtesten:

    //1 x 1 = 100 Punkte
    for(int i=0;i!=6;++i)
       if(w[i]==1)
          return 100;
    return 0;
    
    //1 x 5 = 50 Punkte
    for(int i=0;i!=6;++i)
       if(w[i]==5)
          return 50;
    return 0;
    
    //Straße (1,2,3,4,5,6) = 2500, bestätigung
    int summe=0;
    for(int i=0;i!=6;++i)
       summe+=w[i];
    if(summe==1+2+3+4+5+6)
       return 2500;
    else
       return 0;
    


  • Das komplizierte ist aber, dass, wenn man jetzt z.B. 2 x 100 würfelt und dann weitermacht, man dann nur noch die restlichen Würfel benutzen kann...



  • Surviver schrieb:

    Das komplizierte ist aber, dass, wenn man jetzt z.B. 2 x 100 würfelt und dann weitermacht, man dann nur noch die restlichen Würfel benutzen kann...

    Der Benutzer klickt die beiden 1-er an und klickt auf "weiter".
    Und dann...
    Nee, ich gebe auf. Ich glaube, ich würde dafür eine Woche brauchen. Und für das einfachere Oberfächenprogrammieren nach C# wechseln. Mist.
    🙄



  • Nimm halt irgend einen Container, der die restlichen Würfel enthält, dann läuft die jeweilige Funktion drüber und die Auswertungsfunktion muss eben abhängig von der Länge sein.



  • Hallo Surviver,

    mittels meines BaseGame-Frameworks http://www.c-plusplus.net/forum/193889 habe ich auch "10000" umgesetzt. Hier ein Screenshot: http://www.bitel.net/dghm1164/screenshots/Dice.jpg

    Meine Score-Berechnung sieht so aus:

    class Game
    {
    public:
      // ...
    
    	enum EState { NoScore, UnScore, Score, Scored };
    
    	int CalcScore();
    
    private:
    	Player m_player[MaxPlayers];
    
    	struct SDie
    	{
    		int nNumber;
    		EState state;
    	};
    
    	SDie m_dice[MaxDice];
    }
    
    int Game::CalcScore()
    {
    	int nNumbers[MaxNumbers+1] = { 0 };
    
    	for(int i=0; i<MaxDice; i++)
    	{
    		SDie &die = m_dice[i];
    		if(die.state != UnScore && die.state != Scored)
    		{
    			if(die.state == Score)
    			{
    				die.state = NoScore;
    				m_nScoredDice--;
    			}
    			nNumbers[die.nNumber]++;
    		}
    	}
    
    	int nScore = 0;
    
    	// long street
    	m_bStreet = true;
    	for(int i=1; i<=MaxNumbers; i++)
    		if(nNumbers[i] != 1)
    		{
    			m_bStreet = false;
    			break;
    		}
    
    	if(m_bStreet)
    	{
    		nScore = 2000;
    		m_nScoredDice = MaxDice;
    		for(int i=0; i<MaxDice; i++)
    			m_dice[i].state = Score;
    	}
    	else
    	{
    		for(int i=1; i<=MaxNumbers; i++)
    		{
    			if(nNumbers[i] >= 4)
    			{
    				nScore += (i == 1)? 10000 : 1000 * i;
    				nNumbers[i] -= 4;
    				SetDiceState(Score, NoScore, i, 4);
    			}
    			else if(nNumbers[i] == 3)
    			{
    				nScore += (i == 1)? 1000 : 100 * i;
    				nNumbers[i] -= 3;
    				SetDiceState(Score, NoScore, i, 3);
    			}
    		}
    
    		nScore += 100 * nNumbers[1];
    		SetDiceState(Score, NoScore, 1, nNumbers[1]);
    
    		nScore +=  50 * nNumbers[5];
    		SetDiceState(Score, NoScore, 5, nNumbers[5]);
    	}
    
    	return nScore;
    }
    

    In Kürze:
    - für jeden der 6 Würfel gibt es einen Status (NoScore, UnScore, Score, Scored), d.h. Unbewerted, vom Spieler verworfener Würfel, aktuell gewertet, in vorherigen Wurf gewertet)
    - dann wird im Array 'nNumbers' die Anzahl jeder der 6 Zahlen ermittelt
    - zuerst wird auf eine "Straße" untersucht (jede Zahl genau 1 mal vorhanden) - ohne Bestätigung(!)
    - ansonsten werden zuerst die 4er und 3er Paschs ermittelt und zuletzt dann noch die einzelnen 1 und 5 (d.h. 100 und 50 Punkte) hinzuaddiert (daher wird bei den Paschs die nNumbers um 4 bzw. 3 erniedrigt, damit diese dann nicht noch bei den 1 und 5 dazugezählt werden, z.B. 5 Einsen zählen also 10000 (4 Einsen) + 100 (1 Eins) = 10100 Punkte)

    (die Funktion 'SetDiceState' sorgt dann dafür, daß der Status der Würfel richtig aktualisiert wird)

    Meine Bewertung unterscheidet sich aber leicht von deiner, aber es gibt ja auch zig Varianten, s.a. http://de.wikipedia.org/wiki/Zehntausend

    Die Änderungen müßtest du also entsprechend einbauen (z.B. Pärchen).

    Du solltest aber auf jeden Fall zuersteinmal dein Programm in Funktionen unterteilen bzw. eine eigene Klasse erzeugen.

    Viel Erfolg!


Anmelden zum Antworten