10.7


Nach Optimierung komm ich jetzt auf ca 0,29s für ein 15-Gewinnt im 30x30-Feld :slight_smile:
(Intel Core Duo 1,67 GHz)


Absurd-Mind (und andere): Mich würden die Zusatzimplementierungen interresieren, wen ich zeit finde (hab sie leider nicht wie gewünscht zu Weihnachten bekommen :frowning: ) schnürr ich dann evtl ein N-Gewinnt Paket daraus.


Beträge länger als eine bestimmte Zeitspanne zu editieren wäre echt toll :confused:
Ich habe jetzt die Zeit für 30x30 15-Gewinnt auf 0,14s gedrückt, das reicht jetzt hoffentlich :slight_smile:


gebt ihr eigentlich die Rechenzeit zeit folgendermaßen aus? also vorher zeit messen, nachher zeit messen, dann abziehen und wegen millisecs dann durch 1000 teilen…

à la:

double time1 = System.currentTimeMillis();
ngewinnt.spiele(a, b, 15);
double time2 = System.currentTimeMillis();
double time = time2 - time1;
System.out.println(time/1000+" secs");

ich finde das irgendwie umständlich…


das ist die übliche methode im Programm, auf der Konsole gebe es die Möglichkeit time java DeineKlasse
Nachteil: der Start der VM wird mitgerechnet!

PS. hassandor: dann müsst ich vorher den Code ein bisschen aufräumen *hüstel, wie soll ich ihn dir übermitteln? (ich würd ihn ungern hier posten da er die gleiche istGewonnen methode wie NGewinnt hat)


email… ?!


Jo, weil die Zeit die VM braucht bis mal gestartet ist interessiert mich nicht :wink:


Ich habs jetzt geschafft die Zeit für ein 15-Gewinnt-Spiel mit einem 30x30 Feld auf 3,3ms zu drücken, indem immer vom letzten Zug in alle Richtungen gesucht wird anstatt das ganze Feld nach Reihen zu durchsuchen.
Um die Zeit zu messen mach ich 1000 Spiele und berechne dann den Durchschnitt:

final int COUNT = 1000; NGewinnt n = new NGewinnt(30, 30); long timeDif = 0; for (int i = 0; i < COUNT; i++) { long startTime = System.currentTimeMillis(); n.spiele(new ZufallsSpieler(), new ZufallsSpieler(), 15); long endTime = System.currentTimeMillis(); timeDif += endTime-startTime; } System.out.println((double)timeDif/COUNT);


Ich hab zwar nicht so die Ahnung von Java, aber wahrscheinlich wird hier die Kompilierungszeit für die Funktion ngewinnt.spiele mitgemessen. Das ist ja nicht Sinn der Sache. Also besser mehrmals messen wie mrjazz.


wozu überhaupt messen…


So ähnlich geh ich auch vor. Wie prüfst Du denn z.B. eine Spalte? Einmal von zuletzt eingefügten Stein nach oben und dann nach unten? Ich geh direkt von oben nach unten durch, d.h. ich prüf in einem Durchgang auf 2 „Seiten“.
Die Methode hatte ich mir auch überlegt, aber war mir dann zu viel Aufwand. Allerdings, mit der Rumrechnerei, um nicht über den Rand hinaus zu prüfen (und dadurch die Zeit zu sparen, die die geworfenen Exceptions auffangen kosten würde), kommt das vermutlich aufs selbe raus.


Ja genau. Als Beispiel will ich mal den code zeigen, der nach rechts-unten sucht:

if (lastY+1 >= n && width-lastX >= n) { //ist eine Reihe überhaupt möglich? int count = 0; //zum Zählen der zusammenhängenden Felder for (int i = 0; true; i++) { //i als Durchlaufvariable int x = lastX+i; //x ist gleich das x des letzen Zuges plus i, da nach rechts gegangen wird int y = lastY-i; //y ist gleich das y des letzen Zuges minus i, da nach unten gegangen wird if (x >= width || y < 0) break; //ist das x und y im Spiel-Feld? if (field[y][x] == symbol) count++; //das aktuelle Feld ist das Symbol else count = 0; //das aktuelle Feld ist nicht das Symbol, als Zähler wieder auf 0 setzen if (count == n) return true; //Reihe gefunden. } }
(Bei einem zu kleinen Monitor einfach in den Editor ohne Zeilenumbruch kopieren.)


Ich hab das gerade auch implementiert, ist um den Faktor ca 3 schneller als mein alter (117ms → 37ms) o.O
Die String-Operationen, auf denen mein Vergleichen vorher beruhte, sind offenbar deutlich langsamer als ich dachte.
Ich prüf allerdings momentan nicht, ob eine Reihe überhaupt möglich wär, sondern fange ggf. die Exceptions auf und beende dann diesen Prüfvorgang. Vermutlich ist vorher schauen, ob überhaupt eine Reihe möglich ist, so wie Du es hast, sogar noch einen Tick performanter. Mal ausprobieren :slight_smile:

Edit: Woah, mit den Prüfungen von 37ms auf 5,7ms runter o.O
Noch ein Edit: Meine Funktion für nach rechts unten:

if(n - 1 <= this.board[0].length - 1 - spalte && n - 1 <= this.board.length - 1 - zeile) {
	count = 0;
	for(int i = 0; i < n; i++) {
		if(this.board[zeile + i][spalte + i] == symbol) count++;
	}
	if(count == n) return true;
}

Ich vermute, dass die Exceptions bremsen. Außerdem finde ich es irgendwie stilbesser, Exceptions nur in echten Ausnahmesituationen zu verwenden und nicht als Arbeitstier in einer Algorithmus-Umsetzung.

Mein Code hatte noch Redundanz, ohne die ich jetzt auf 2,9ms komme. Hier die neue Version von „nach rechts-unten“:

if (lastY+1 >= n && width-lastX >= n) { for (int i = 0; true; i++) { int x = lastX+i; int y = lastY-i; if (field[y][x] != symbol) break; if (i+1 == n) return true; } }


Willkommen im Club! :slight_smile:


110ms nach der zeit mess methode von mrjazz bei mir, is mir schnell genug und werd bei meinen prüf methoden nix mehr ändern ^^


Bei deinen Ungleichungen kannst du die -1en weglassen, weil die kürzen sich weg. Noch eine Kleinigkeit wäre, dass man Variablen immer dort deklarieren sollte, wo man sie braucht, also anstatt count irgendwo am Anfang der Funktion zu deklarieren und dann in den if-scopes count=0 lieber erst in den if-scopes mit int count=0 count deklarieren.


Stimmt, das kommt vom kopieren der Zeilen und ersetzen, ohne groß nachzudenken ^^
Bringt die Zeit runter auf 5,4ms.

Ist klar, aber ich hab mehrere von diesen if-abfragen mit for-schleifen untereinander in einer großen Funktion, d.h. keine kleinen Funktionen, die jede nur eine Richtung prüft.
Edit: Gerade probiert: In jedem if neu deklarieren treibt die Zeit wieder auf 5,6ms hoch.


Ja, diese große Funktion hab ich auch gemeint, als ich geschrieben hab, dass es schlecht wäre, count irgendwo am Anfang eben dieser Funktion zu deklarieren. Man sollte halt Variablen immer so spät wie möglich deklarieren (also in diesem Fall in jedem if-scope (wie heißt das auf deutsch?) einzeln). Hier ist es jetzt noch nicht so schlimm, aber man sollte es sich gleich von vornherein angewöhnen, weil das Wartbarkeit vom Code erhöht - gerade wenn es komplizierter wird.


hab noch nen kleinen fehler gefunden ^^ → 80ms