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
xxxoes 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 :>