Bei Tic Tac Toe nach einem Gewinner suchen



  • Wie sucht man am einfachsten nach einem Gewinner?
    Ich habe jetzt schon einige Zeit herumprobiert, aber Probleme das ganze in ner Schleife zu erledigen (da ich das ganze nicht auf 3x3 fixieren möchte).
    Irgendwie fehlt mir da grad der Denkansatz wobei es ja eigentlich klar ist wie man vorzugehen hat 😞

    Meine Anfänge für die Senkrechten und Waagrechten sind derzeit folgende (haben aber noch ein paar Bugs außer, dass sie nicht alle waagrechten erkennen):

    EMPTY steht für leeres Feld
    CROSS der Spieler mit dem Kreuz
    CIRCLE der Spieler mit dem Kreis
    FIELD die Feldbreite (sowie die Höhe)

    public void findWinner ()
    	{
    
    		int winner = EMPTY;
    
    		// Waagrechte
    		for (int j = 0, i = 0; j < FIELD; j++)
    		{
    			winner = game[i][j]; 
    
    			for (i = 0; i < FIELD; ++i)
    			{
    				System.out.println ((i+1) + " , " + (j+1));
    				if (game[i][j] == game[0][0])
    					winner = game[i][j];
    				else
    					winner = EMPTY;
    
    			}
    
    			--i; // i steht nach der inneren for-schleife auf FIELD darf aber nur auf FIELD-1 stehen
    
    		if (winner != EMPTY)
    			System.out.println ("winner is " + winner);
    
    		}
    
    		// Senkrechte
    		for (int i = 0; i < FIELD; ++i)
    		{
    			for (int j = 0; j < FIELD; ++j)
    				if (game[i][j] == game[0][0])
    					winner = game[i][j];
    				else
    					winner = EMPTY;	
    
    			if (winner != EMPTY)
    				i = FIELD;
    		}
    
    		if (winner != EMPTY)
    			System.out.println ("winner is " + winner);
    
    	}
    


  • Tolle Frage 🙄 Bei den Spiel gibt es keine Gewinner (wenn doch war ein Spieler ein Loser).



  • bist du sicher dass das ueberhaupt funktioniert? 😕

    Die Hauptabfrage lautet ja

    if (game[i][j] == game[0][0])
                        winner = game[i][j];
                    else
                        winner = EMPTY;
    

    kann da der Spieler, der in game[0][0] NICHT sein Zeichen hat ueberhaupt gewinnen?

    (hab das ganze jetzt nur mal 5 Minuten lang durchgedacht und wahrscheinlich was essenzielles uebersehen 😞 )

    Ich hab das Seinerzeit so geloest (sind 2 Funktionen, eine fuer horizontale, eine fuer vertikale Reihen... also insgesamt 4 schleifen)

    Player VierVerliert::checkForVerticalWins() const
    {
    	int points1 = 0;
    	int points2 = 0;
    
    	// check vertically
    	for (int i = 0; i < status_.cols(); ++i)
    	{
    		for (int j = 0; j < status_.rows(); ++j)
    		{
    			switch (status_.at(i,j))
    			{
    				case Player1:
    					++points1;
    					points2 = 0;
    					break;
    				case Player2:
    					++points2;
    					points1 = 0;
    					break;
    			}
    
    			// as this is VierVerliert and not VierGewinnt, the looser 
    			// is the one who would win a VierGewinnt-Game
    			if (points1 == maxPoints_)
    			{
    				return Player2;
    			}
    			if (points2 == maxPoints_)
    			{
    				return Player1;
    			}
    		}
    		points1 = 0;
    		points2 = 0;
    	}
    	return NoPlayer;
    }
    

    Fuer Diagonale hab ich leider nichts funktionierendes, weil ich irgendwo anders im Projekt stecken geblieben bin und danach aufgegeben hab 😞



  • *g* ich seh grad fuer die Horizontale hab ich ein "etwas" anders System, das jetzt im Nachhinein irgendwie schwerer nachvollziehbar ist, aber vielleicht interessierts dich ja trotzdem:

    Player VierVerliert::checkForHorizontalWins() const
    {
    	int points[maxPoints_];
    	for (int i = 0; i < maxPoints_; ++i) points[i] = 0;
    	int k = 0;
    	int sum = 0;
    
    	for (int i = 0; i < status_.cols(); ++i)
    	{
    		for (int j = 0; j < status_.rows(); ++j)
    		{
    			points[k++] = (status_[j][i]);     // TO DO: something wrong with [j][i]?!?
    			k %= maxPoints_;
    			sum = points[0] + points[1] + points[2] + points[3];
    
    			if (sum == loosingPoints1)
    			{
    				return Player2;
    			}
    			else if (sum == loosingPoints2)
    			{
    				return Player1;
    			}
    		}
    	}
    	return NoPlayer;
    }
    

    Beruht dabei darauf, dass das enum Player einen ordentlichen Abstand zwischen den einzelnen moeglichen Werten hat

    enum Player
    {
    	NoPlayer = 0,
    	Player1 = 1,
    	Player2 = 5
    };
    

    und den 2 Variablen:

    loosingPoints1(maxPoints_ * Player1),
    loosingPoints2(maxPoints_ * Player2)
    

    (maxPoints_ gibt an, wieviel Punkte man braucht um zu gewinnen (eigentlich verlieren, weil das Ganze ein "VierVerliert" ist, kein Vier Gewinnt 😉 ) )



  • Hoppla sorry, natürlich muss beim ersten game[0][j] stehen und beim zweiten game[i][0] war noch aus der Version wo nur die erste Reihe bzw. Spalte getestet wurde.

    Werd mir mal eure Vorschläge anschauen und mich wieder melden 🙂

    Edit:
    Hm deine Idee ist gut, einfach Punkte hochzählen und die des anderen resetten und die freien Felder ignorieren 🙂

    Kann ich auch Perfekt bei TicTacToe anwenden, Danke! 🙂



  • Führ dir den Thread mal zu Gemüte http://www.delphipraxis.net/topic28714_siegerpruefung+vier+gewinnt.html&highlight=vier+gewinnt, geht zwar um "Vier gewinnt" aber das sollte keinen Unterschied machen.



  • Danke, das mit dem String hört sich interressant an, werd ich mal testen find ich pers. sogar besser als die mathematische Version, die ist mit dem zählen auch net wirklich elegant.



  • Wie ich dachte ist es so um einiges kürzer und eleganter als mit der mathematischen Methode

    Vielen Dank 🙂

    Edit:

    So jetzt hab ich alle Möglichkeiten und falls mal wer das gleiche Problem hat hier mal meine ganze Überprüfung

    public void findWinner ()
    	{
    
    		String tmp;
    
    		String cross  = generatePattern (CROSS, FIELD);
    		String circle = generatePattern (CIRCLE, FIELD);
    
    		// Waagrechte
    		for (int i = 0; i < FIELD; ++i)
    		{
    			tmp = "";
    			for (int j = 0; j < FIELD; ++j)
    			{
    
    				tmp += game[i][j];
    			}
    
    			if (tmp.matches (cross))
    				System.out.println ("Kreuz");
    			else if (tmp.matches (circle))
    				System.out.println ("Circle");
    
    		}
    
    		// Senkrechte
    		for (int i = 0; i < FIELD; ++i)
    		{
    			tmp = "";
    			for (int j = 0; j < FIELD; ++j)
    			{
    
    				tmp += game[j][i];
    			}
    
    			if (tmp.matches (cross))
    				System.out.println ("Kreuz");
    			else if (tmp.matches (circle))
    				System.out.println ("Circle");
    
    		}
    
    		// Diagonale links -> rechts
    		tmp = "";
    		for (int i = 0, j = 0; i < FIELD; i++, j++)
    			tmp += game[i][j];
    		if (tmp.matches (cross))
    			System.out.println ("Kreuz");
    		else if (tmp.matches (circle))
    			System.out.println ("Circle");
    
    		// Diagonale rechts -> links
    		tmp = "";
    		for (int i = 0, j = FIELD-1; i < FIELD; i++, j--)
    			tmp += game[i][j];
    		if (tmp.matches (cross))
    			System.out.println ("Kreuz");
    		else if (tmp.matches (circle))
    			System.out.println ("Circle");
    
    		System.out.println ("\n\n");
    
    	}
    


  • Also, ich habs nur mal in Java geproggt und da hab ichs mit for schleifen gemacht.

    static void dreiInReihe() 
    	   { 
    	      for ( int i = 0; i<3; i++ ) 
    	      {    int Kreise = 0, Kreuze = 0, kreise = 0, kreuze = 0; 
    	         for ( int j = 0 ; j <3 ; j++) 
    	         { 
    	            if ( Spielfeld[i][j] == 1 ) Kreise++; 
    	            else if ( Spielfeld[i][j] == 2 )Kreuze++; 
    	            if ( Spielfeld[j][i] == 1 ) kreise++; 
    	            else if ( Spielfeld[j][i] == 2) kreuze++; 
    	            if ( Kreise == 3 || kreise == 3)beenden(1); 
    	            if ( kreuze == 3 || Kreuze == 3 )beenden(2); 
    	         } 
    	      } 
    	      int Kreise = 0, Kreuze = 0, kreise = 0, kreuze = 0; 
    	      for ( int i = 0, j = 0; i < 3; i++, j++ ) 
    	      { 
    	         if ( Spielfeld[i][j] == 1 ) Kreise++; 
    	         else if ( Spielfeld[i][j] == 2) Kreuze++; 
    	         else break; 
    	         if ( Kreise == 3 )beenden(1); 
    	         if ( Kreuze == 3 )beenden(2);       
    	      } 
    	      if (Spielfeld[0][2]==Spielfeld[1][1]&&Spielfeld[1][1]==Spielfeld[2][0]) 
    	      {if (Spielfeld[1][1] == 1) 
    	      beenden(1); else if (Spielfeld[1][1] == 2) beenden(2); 
    	      } 
    	      return; 
    	   }
    

    ist jetzt nicht gerade c++, aber vllt verstehts einer trotzdem


Anmelden zum Antworten