Array auf Lücke durchsuchen
-
Hi,
mir stellt sich gerade die Schwierigkeit, dass ich ein Array habe, von dem ich die Dimensionen NICHT kenne. Es ist 2-Dimensional.
Ich muss jetzt prüfen, ob eine Kombination (Waagrecht, Senkrecht, Diagonal) im Array vorliegt. Es soll aber auch möglch sein, eine "Lücke" zu erlauben. z.B. so
findCombinations(Owner* ow, int startX, int startY, int dirX, int dirY, int length, int space_length)
Wenn mein Array jetzt so aussieht (N = NULL, also leer => Lücke)
O | N | O
N | N | N
N | N | NDann muss diese Kombination in der 1. Reihe aber trotzdem erkannt werden.
Es ist jedoch nicht immer so, dass ich ein 3x3-Array habe.Meine Funktion, die bisher alle "vollen" Kombinationen erkennt:
bool Controller::isCombination(Spieler* player, int startX, int startY, int dirX, int dirY, unsigned int length, unsigned int space_length) { //Teste, ob Startkoordinaten gültig sind if(!this->model->isValidCoord(startX, startY)) { return false; //Ungültige Koordinaten } //Teste, ob Endkoordinaten gültig sind if(!this->model->isValidCoord(startX + (dirX*(length-1)), startY + (dirY*(length-1)))) { return false; //Ungültige Koordinaten } //jetzt wird eine Schleife length mal wiederholt. for(unsigned int i = 0; i < length; i++) { //Es wird geprüft, ob das Feld NICHT vom Spieler ist. if(this->model->getFeld(startX + (dirX*i), startY + (dirY*i))->getPlayer() != player) { return false; } } return true; //Eine Kombination existiert! }
Wie stelle ich es jetzt an, dass ich die Lücken erlauben kann?
Ich komme auf keine Idee..MfG
Simon
-
Achso: Wichtig ist noch, dass die Lücke nicht am Anfang und nicht am Ende der Kombination liegen darf. Es muss also immer noch ein Stein davor UND danach kommen
Ich komm einfach nicht drauf!
-
Keiner ne Idee?
-
So funktioniert es, aber es ist so sehr starr...
for(int y = 0; y < CONST__anzY; y++) { for(int x = 0; x < CONST__anzX; x++) { if(this->model->isValidCoord(x,y) && this->model->isValidCoord(x+2, y+2)) { if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x+2, y+2)->getPlayer() && !this->model->getFeld(x,y)->isEmpty() && this->model->getFeld(x+1, y+1)->isEmpty()) { feld = this->model->getFeld(x+1, y+1); } else if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x+2, y)->getPlayer() && !this->model->getFeld(x,y)->isEmpty() && this->model->getFeld(x+1, y)->isEmpty()) { feld = this->model->getFeld(x+1, y); } else if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x, y+2)->getPlayer() && !this->model->getFeld(x,y)->isEmpty() && this->model->getFeld(x, y+1)->isEmpty()) { feld = this->model->getFeld(x, y+1); } } } }
WIe gehts besser?
-
this->model->getFeld(x,y)->isEmpty()
sagt dir doch ob das Feld leer ist oder nicht ?
Musst du nicht nur volle Kombinationen erkennen (ob der Spieler waagerecht, senkrecht oder diagonal ein Feld besetzt hat ?
Ich verstehe jetzt nicht das Problem. Wenn der Spieler auf ein Feld setzen will, dann überprüfst du auf leer oder nicht.
Wenn besetzt dann Meldung sonst Spieler auf das Feld und auf volle Kombination abfragen.
-
Es geht darum, dass meine Pseudo-KI erkennen soll, dass ein Spieler zuerst die äußeren Steine setzt und am Schluss den 3. setzen will, um die Kombination zu erzeugen. Das soll die KI dann verhindern.
Da ich den Algorithmus aber auch für 4 Gewinnt und noch andere Spiele einsetzen will, muss er allgemein gültig sein. Und hier liegt das Problem!
-
Der Algorithmus ist jetzt dynamisch und kann beliebig benuttz werden.
Allerdings ist der Code noch ein wenig redundant, was ich jetzt beheben werde (zumindest versuche ich es)int space_length = 1, cnt = 0, length = 3; for(int y = 0; y < CONST__anzY; y++) { for(int x = 0; x < CONST__anzX; x++) { if(this->model->isValidCoord(x,y) && this->model->isValidCoord(x+length-1, y+length-1)) { if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x+length-1, y+length-1)->getPlayer() && !this->model->getFeld(x,y)->isEmpty()) { for(int i = 1; i <= space_length; i++) { if(this->model->getFeld(x+i, y+i)->isEmpty()) { cnt++; } else { cnt = 0; } } if(cnt >= space_length) { feld = this->model->getFeld(x+space_length, y+space_length); } cnt = 0; } else if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x+length-1, y)->getPlayer() && !this->model->getFeld(x,y)->isEmpty()) { for(int i = 1; i <= space_length; i++) { if(this->model->getFeld(x+i, y)->isEmpty()) { cnt++; } else { cnt = 0; } } if(cnt >= space_length) { feld = this->model->getFeld(x+1, y); } cnt = 0; } else if(this->model->getFeld(x,y)->getPlayer() == this->model->getFeld(x, y+length-1)->getPlayer() && !this->model->getFeld(x,y)->isEmpty()) { for(int i = 1; i <= space_length; i++) { if(this->model->getFeld(x, y+i)->isEmpty()) { cnt++; } else { cnt = 0; } } if(cnt >= space_length) { feld = this->model->getFeld(x, y+1); } cnt = 0; } } } }
-
Benutze für deine KI am besten den MinMax (bzw. Alpha-Beta-Pruning) Algorithmus und erzeuge dafür eine korrekte Bewertungsfunktion (welche die Gewinnlogik enthält) - diese beiden Algos funktionieren für alle Nullsummen-Spiele (z.B. TicTacToe, Vier gewinnt, Reversi, ..., Schach(!)).
Dann brauchst du auch nicht solch einen Aufwand betreiben und von Hand die Gewinnstrategie auszuprogrammieren.