Hilfe wo ist mein Logikfehler?



  • HI

    Ich versuche mich gerade an einer MinMax Ki für 4 gewinnt!

    Leider ist meine KI total doof obwohl sie eigentlich richtig sein sollte!

    Total doof = Setzt immer in die letzte spalte auch wenn da schon steht:
    x
    0
    x
    0
    oder bei
    ___o
    xxxo

    es also für o sinnlos ist dort noch zu setzen weil bzw es für x zum gewinn führt

    Kurz: Ich habe einen logikfehler den ich nicht finde!
    Vieleicht kann mal jemand ausenstehend draufsehen warscheinlich ist der Fehler ganz offensichtlich!

    Hier mein Code:

    Globale Variablen:

    char cMatrix[6][7];
    char cSpielerSymbole[2];
    int iEbene;
    

    Die KI funktionen:

    int getKIZug()
    {
      int i = 0;
      int iSpalte;
      int iMax = -10000;
      int iResult;
      iEbene = 4; //Wieviele runden soll er vorausberechnen -1 also 3
      for(i = 0; i < 7; i++)
      {
         if(cMatrix[0][i] == ' ') //ist in der Zeile überhaupt noch platz?
         {
            iResult = SimuliereZug(i);
            if(iResult > iMax)   // ist der zug besser als der letze?
            {
               iMax = iResult;
               iSpalte = i;
            }
         }
      }
      return iSpalte;
    }
    
    //-------------------------------------------------------------------------
    int SimuliereZug(int iSpalte)
    {
       //EIn möglicherZug wird simuliert und bewertet
       int x;
       int iWertigkeit = 0;  //Wie gut oder schlecht ist der Zug
       setzeSteine(iSpalte, cSpielerSymbole[1]);  // den Stein in die Spalte legen
       iWertigkeit = checkZug(cSpielerSymbole[1]);//Wertigkeit ermitteln
    
       //Den Stein wieder löschen
       for(x = 0; x < 6; x++)
       {
          if(cMatrix[x][iSpalte] != ' ')
          {
             cMatrix[x][iSpalte] = ' ';
             x = 10;
          }
       }
       return iWertigkeit;
    }
    //-------------------------------------------------------------------------
    int checkZug(char cStein)
    {
       int iWertigkeit = 0;
       int i = 0;
       int x;
       int iTempGewinner;
       //Das Symbol des neuen Spielers nehmen
       if(cStein == cSpielerSymbole[0])
       {
          cStein = cSpielerSymbole[1];
       }
       else
       {
          cStein = cSpielerSymbole[0];
       }
    
       //wir sind einen Zug weiter
       iEbene--;
       for(i = 0; i < 7;i++)
       {
          //darf in die spalte noch ein stein?
          if(cMatrix[0][i] == ' ')
          {
             //Stein legen
             for(x = 5; x >=0; x--)
             {
                if(cMatrix[x][i] == ' ')
    	    {
                   cMatrix[x][i] = cStein;
    	       x = -1;
    	    }
             }
             //prüfen ob einer gewonnen hat (PC = 2 User = 1)
             iTempGewinner = CheckGewonnen();
    
             //Stein wieder löschen
             for(x = 0; x < 6; x++)
             {
                if(cMatrix[x][i] != ' ')
                {
                   cMatrix[x][i] = ' ';
                   x = 10;
    	    }
             }
             if(iTempGewinner == 2)
             {
                return iEbene * iEbene * iEbene;
             }
             else
             {
                return (iEbene * iEbene * iEbene) * -1;
             }
          }
       }
       //Wenn keiner der Züge zu einem Gewinner geführt hat und wir noch nicht alle
       //Ebenen durch haben noch eine ebene Tiefer gehen!
       if(iEbene > 0)
       {
          //alle spalten durchegehen
          for(i = 0; i < 7;i++)
          {
             if(cMatrix[0][i] == ' ')
             {
                //zug durchführen ( Stein setzen)
                setzeSteine(i, cStein);
                //Wertigkeit des zugs addieren
                iWertigkeit = iWertigkeit + checkZug(cStein);
                //Zug rückgängig machen
                for(x = 0; x < 6; x++)
    	    {
                   if(cMatrix[x][i] != ' ')
    	       {
                      cMatrix[x][i] = ' ';
                      x = 10;
    	       }
    	    }
    	 }
          }
       }
       //Wir gehen wieder eine eben hoch
       iEbene++;
       return iWertigkeit;
    }
    

    Hoffe ihr habt mehr erfolg als ich!

    THX

    Dagsta



  • wo ist denn da der minmax algorithmus??
    http://de.wikipedia.org/wiki/Minimax-Algorithmus
    lies dir das doch mal durch und guck dir vor allem den pseudocode an 🤡



  • Also ich habe den Code jetzt so umgesetzt aber die ist kein Stück schlauer nur das er jetzt immer auf linken rand und nicht am rechten türme baut!

    Hier Mein Code

    int maxWert(int iRestTiefe)
    {
      int iZugWert, iErmittelt, i;
      iErmittelt = INT_MIN;
      for(i = 0; i < 7; i++)
      {
         {
            if(cMatrix[0][i] == ' ') //ist in der Zeile überhaupt noch platz?
            {
               setzeSteine(i, cSpielerSymbole[1]);
               if(iRestTiefe <= 1 || spielEnde == 1)
               {
                  iZugWert = SpielBewertung();
    
               }
               else
               {
                  iZugWert = minWert(iRestTiefe - 1);
               }
               SteinLoeschen(i);
               if(iZugWert > iErmittelt)
               {
                  iZugWert = iErmittelt;
                  igKISpalte = i;
               }
            }
         }
         return iErmittelt;
      }
    
    }
    
    int minWert(int iRestTiefe)
    {
       int iErmittelt, iZugWert, i;
       iErmittelt = INT_MIN;
       for(i = 0; i < 7; i++)
       {
          if(cMatrix[0][i] == ' ') //ist in der Zeile überhaupt noch platz?
          {
             setzeSteine(i, cSpielerSymbole[0]);
             if(iRestTiefe <= 1 || spielEnde == 1)
             {
                iZugWert = SpielBewertung();
             }
             else
             {
                iZugWert = maxWert(iRestTiefe -1);
             }
             SteinLoeschen(i);
             if(iZugWert < iErmittelt)
             {
                iErmittelt = iZugWert;
             }
          }
       }
    }
    /*Gibt 0 Zurück wenn noch Züge möglich sind
      und 1 wenn keine Züge mehr möglich sind */
    int spielEnde(void)
    {
       int i, iRueck;
       iRueck = 1;
       for(i = 0; i < 7; i++)
       {
          if(cMatrix[0][i] == ' ')
          {
             i = 7;
             iRueck = 0;
          }
       }
       return iRueck;
    }
    
    int SpielBewertung(void)
    {
       int iRueck, iGewinner;
       iGewinner = CheckGewonnen();
       if(iGewinner == 0)
       {
          return 0;
       }
       if(iGewinner == 1)
       {
          return -1;
       }
       if(iGewinner == 2)
       {
          return 1;
       }
    }
    

    müsste es nicht iZugWert = iZugwert - minWert(...) bzw iZugWert = iZugwert + maxWert(...) heisen?

    Also langsam verstehe ich garnichts mehr!



  • int getZugWert(int tiefe, bool color)
    {
      if(tiefe == 0)
    	  return SpielBewertung();
    
      int bestValue;
      if(color)
    	  bestValue = INT_MIN;
      else
    	  bestValue = INT_MAX;
    
      for(i = 0; i < 7; i++)
      {
    
            if(cMatrix[0][i] == ' ') //ist in der Zeile überhaupt noch platz?
            {
               setzeSteine(i, cSpielerSymbole[color]);
               int zugWert = getZugWert(iRestTiefe - 1,!color);           
               SteinLoeschen(i);
               if(color && zugWert > bestValue || !color && zugWert < bestValue)
               {
                  bestValue = zugWert;
    			  if(tiefe == igMaxTiefe)
    				igKISpalte = i;
               }
            }     
      }
      return bestValue;
    }
    


  • dagsta schrieb:

    int maxWert(int iRestTiefe)
    {
      iErmittelt = INT_MIN;
    
    ...
    
    int minWert(int iRestTiefe)
    {
       iErmittelt = INT_MIN;
    

    da ist der fehler.



  • nein da sind ganz viele fehler..



  • thx die ki klappt ich obtimire noch nen bischen und werde den code dann posten!



  • wenn du schon optmieren willst, kannste gleich mal alphabeta cutoff reinbaun :>


Anmelden zum Antworten