# Java Bot - Achtung die Kurve



## CurBty (8. Nov 2011)

Hi,

Ich würde gerne einen Bot für das Spiel "Achtung die Kurve" bzw "IPcurve" programmieren. (Wer es nicht kennt, sollte es mal googlen, dieses Spiel ist über LAN echt super!)

Ich habe schon ein bisschen drüber nachgedacht, wie ich jetzt an die Sache herangehen soll:

Ich könnte jedes mal Screenshots machen, analysiere die einzelnen Pixel und reagiere je nach dem, was die anderen machen, mit einem Tastendruck. Dies kommt mir jedoch relativ unpraktisch und unnötig kompliziert vor, vorallem, da ich vorher nicht unbedingt meine eigene Farbe wissen muss (auch wenn man das Problem natürlich durch ein Farb-Auswahlmenü beim Start vom Bot beheben könnte).

Mein zweiter Gedanke war, dass Spiel erstmals über einen Sniffer zu analysieren und dann nur noch die Befehle abzufangen und somit die Strecke der anderen zu berechnen und einen Befehl zurückzuschicken (oder mehrere). Jedoch sehe ich ja dann nicht mehr, was der Bot spielt (zumindest nicht an meinem Computer), da er ja eigentlich direkt eine Verbindung (über einen Socket?) zum Server aufbaut. Oder kann (und sollte) man sich irgendwie zwischen das Spiel und den Server schalten?
Dies müsste doch rein theoretisch über einen eigenen Serversocket funktionieren, zu dem sich das Spiel dann "lokal" verbindet. Der Bot schickt dann die Befehle - die vom Server bekommenen Befehle werden dann einfach an das Spiel weitergeleitet und somit müsste man noch alles sehen können.

Ich würde jetzt gerne von euch wissen, welche der beiden Möglichkeiten euch für sinnvoller erscheint oder ob euch vielleicht doch eine 3. Möglichkeit besser gefällt. 
Außerdem würde mich interessieren, wie ich mich zwischen das Spiel und den Server schalten kann, ob mein Ansatz richtig ist und wie ich solch eine Analyse angehen sollte. (Auch wenn dies hier nicht gebraucht wird)

Schonmal Danke für die Antworten, wenn noch Fragen bestehen einfach fragen.

lg CurBty


----------



## XHelp (8. Nov 2011)

Du könntest Monate opfern und die Arbeitsweise des alten Clients nachzuvollziehen und dann deinen eigenen schreiben, der sowohl spielen als auch cheaten kann.
Die Frage ist natürlich wieviel Zeit du da opfern willst. Alleine schon einen Algo zu entwickeln, der eine perfekte Route berechnet wird schon dauern.


----------



## CurBty (8. Nov 2011)

Danke für deine Antwort. 
Natürlich möchte ich nur ungern Monate opfern, jedoch möchte ich unbedingt auch mal etwas in diese Richtung programmieren, auch wenn es ein bisschen dauert. 
Und um den Algorithmus mache ich mir sorgen, wenn ich weiß, wie ich die Befehle überhaupt übergebe und dies auch umgesetzt habe.


----------



## Dow Jones (8. Nov 2011)

Ich habe beide Methoden bereits verwendet um Programme automatisch bedienen zu können. Allerdings hatte ich dazu zumeist C verwendet, das macht ein paar Dinge einfacher.

Ich denke für deinen Zweck funktionieren beide Methoden. Lass mal überlegen... welche Informationen benötigt man denn alles. Am wichtigsten ist es wohl zu wissen wo bereits Spuren verlaufen, denn diese darf man ja nicht berühren. Das kann man vermutlich prima aus einer Bitmap (Screenshot) ablesen. Dann muss man wissen wo sich der eigene "Cursor" zur Zeit befindet; am besten zusammen mit der aktuellen Laufrichtung. Das kann man eigentlich auch ganz gut aus zwei oder drei aufeinanderfolgenden Screenshots ablesen. Ich glaube, ich würde die Methode mit den Screenshots bevorzugen.

Der andere Weg wäre es einen eigenen Client oder Proxy zu implementieren. Beim Proxy hätte man das Problem, das dieser zwar den Netzwerkverkehr abhören und interpretieren kann, aber er kann das Spiel nicht selber bedienen (soll heissen: wenn der Proxy von sich aus einen Befehl an den Server sendet bekommt der parallel laufende original Spielclient das nicht mit). Ein eigener Spielclient hätte dieses Problem nicht, allerdings müsstest du dann selber eine graphische Darstellung der aktuellen Spielsituation implementieren (wenn du sehen möchtest was gerade passiert). Und damit kommen wir auch zu dem großen Manko der Client/Proxy Lösung: Je nachdem was genau der Server an Daten überträgt wäre deine Interpretation der Daten im Zweifelsfall nur eine Approxmation der tatsächlichen Spielsituation. Ich meine, wenn du z.B. versucht die Kurve die ein Spieler gerade läuft nur anhand seiner Links-/Rechts-Kommandos zu ermitteln, dann müsstest du den Krümmungsradius der Kurven schon _exakt_ kennen. Ansonsten werden sich recht schnell Fehler einschleichen. Und wenn diese Fehler dafür sorgen, das du eine Kurve falsch zeichnest (also z.B. einen Pixel zu weit rechts), dann kann das für deinen Bot schon das Aus bedeuten. Das kann dir bei der Screenshot-Methode nicht passieren. Außerdem dürfte es weniger Arbeit sein einen Screenshot zu analysieren als ein Netzwerkprotokoll zu reenginern. 

Was ich aber interessanter finde - wie sieht die Strategie aus, die der Bot verfolgen soll? Ich meine, wenn man den aktuellen Spielstand ersteinmal erkannt hat: Wie ermittelst du wie der Bot auf die gegebene Situation reagieren soll? Erzähl mal, wenn du magst, ich fänd's interessant.


----------



## CurBty (8. Nov 2011)

Danke für deine Antwort Don Jones 

Du hast mich überzeugt, die Screenshot-Methode zu benutzen. Vorallem das Argument der Ungenauigkeit hat mich stutzig gemacht.

Jedoch noch zu der Client-Proxy Version:
Wenn die Daten vom Server über den Proxy an den Client weitergeleitet werden, sollte dieser normal auch die richtigen Informationen der Kurven haben und diese somit richtig zeichnen können. Je nachdem ob der Client die eigenen Daten auch vom Server geschickt bekommt oder nicht, müsste man eben diese Daten an den Client ebenfalls weitergeben (Im Notfall eben einen Tastendruck simulieren). Es dürfen ja nur nicht die Daten vom Client zum Server übertragen werden (bzw es dürften normalerweiße auch keine vorhanden sein, solange man nichts drückt, außer die simulierten vom Bot).

Und an den Algorithmus setze ich mich jetzt mal dran. Wenn ich einen habe, werde ich mich melden.
Falls du, oder jemand anderes, eine Idee für den Algorithmus hat, darf er diesen natürlich auch gerne schreiben.


----------



## CurBty (9. Nov 2011)

Hi ,

Was haltest du/haltet ihr von der Idee in bestimmten Zeitabständen Screenshots zu machen, und die Daten von dem Screenshot in einem Array-Enum zu speichern.
Die Spielfläche in der man sich bewegen kann ist ja schwarz, der rest blau. Also theoretisch müsste es reichen, am anfang einen Screenshot zu machen, der die Fläche des schwarzen Bereiches ausliest. Dann bräuchte man nur noch Screenshots von dem schwarzen Bereich machen. 
Danach könnte man ein Enum erzeugen, dass den Status frei hat. Jetzt wird zB alle 0,2 sec ein Screenshot gemacht und ausgelesen. Alles was nicht mehr schwarz ist, wird mit blockiert o.ä. belegt (Array).

Könnte man dies so angehen als Programmieransatz? Oder ist dies eine nicht elegante oder sogar nicht richtig Funktionierende Lösung?


Als KI habe ich mir überlegt, dass ich mir erstmal den Winkel der Drehung ausrechne, dass ich den Abstand habe, in der eine Drehung noch möglich ist, ohne mit dem Rand oder einem Strich zu kollisieren.

Jetzt könnte ich mir die beste Fläche ausrechen, also die in der am meisten Platz ist. Wenn der Weg zu diesem frei ist, lenkt der Bot zu diesem und nutzt den Platz dort aus bis er ausgebraucht ist, jedoch noch genug Platz zum "abhauen" ist. 

Wenn diese Fläche auch nicht mehr richtig befahrbar (wenn man hier von fahren sprechen kann, aber mir fällt gerade kein gutes Wor ein ) ist oder der Weg zu diesem beim hinlenken schon vorher blockiert ist, sucht er sich den nächstbesten Platz usw. 

Wenn alle Flächen < x sind dann könnte er einfach knapp am Rand entlang fahren, außer es ist jemand in den Rand gefahren dann lenkt er vorher irgendwo anders hin. Insgesammt lenkt er immer bei einem gewissen Abstand ab, falls jedoch beide Richtungen knapp sind errechnet er sich den Mittelwert und fährt diesen entlang.

Könnte man dies bis dahin etwa so lassen oder spricht etwas dagegen? (Für die Lücken muss ich mir natürlich auch noch was ausdenken ) Ist natürlich nicht perfekt aber für den ersten Test sollte es reichen, er muss ja dann eh verbessert werden, da Schwächen gefunden werden.

PS: Ich hoffe man konnte einigermaßen verstehen was ich meine^^


----------



## CurBty (9. Nov 2011)

Habe mal gerade die ipcurve.ini durchgeschaut, der standard Wendewinkel (turnAngle) ist dort schon angegeben, nämlich turnAngle = 0.024.


----------



## CurBty (12. Nov 2011)

So wies aussieht, haltet ihr wohl gar nichts davon  Dann werd ichs wohl einfach ausprobieren müssen^^


----------



## Gast2 (12. Nov 2011)

Ich hab mir deine Posts jetzt nicht komplett durchgelesen, aber folgendes ist mir beim drüberschaun aufgefallen.


> Jetzt wird zB alle 0,2 sec ein Screenshot gemacht und ausgelesen.


Je nach Auflösung dauert allein das erstellen des Screenshots mit der Robot Klasse schon gerne mal sehr lange. Bei mir (3840x1080) dauert das erstellen des Screenshots >500ms. Bei nem Ausschnitt von 1080x1080 immer noch knapp über 300ms (stark schwankend).
Wenn du das nicht signifikant beschleunigen kannst (evtl. durch JNI/JNA) dann stößt du mit der Methode schnell an die Grenzen.


----------



## CurBty (12. Nov 2011)

Danke für deine Antwort. Das Problem ist, dass der Bot zumindest auf Linux und Windows laufen sollte. Gibt es nicht noch eine andere Möglichkeit? Ich werde morgen bzw später mal testen, wie lange so ein Screenshot bei mir braucht. 
Und ich habe gerade mal geschaut, im Vollbildmodus hat der Spielbereich, den ich ja brauche, nur etwa 900x700 Pixel, was jedoch trotzdem > 200ms seien wird, nach deinen Zahlen.
Gibt es nicht eine Möglichkeit schnellere Screnshots zu machen, obwohl das Programm auf Linux und Windows läuft? Ich werde mich morgen nochmal genauer darüber informieren.

lg


----------



## XHelp (12. Nov 2011)

Du musst ja auch nicht immer einen kompletten Screentshot machen. Du machst 2 Screenshots um zu bestimmen in welche Richtung die Linien laufen und dann machst du einfach nur einen Screenshot von einem kleinen Teil des Bildschirms, wo die Linie in der Zeit hingelaufen sein könnte.


----------

