Soa ihr Lieben!
Nachdem ich euch nun solange warten gelassen habe, kann ich nun (endlich) verkünden dass der erste AI Fight starten kann. Vorab: Das Allgemeine Regelwerk findet ihr in diesem Thread. Das erste Spiel ist ein Klassiker und eine etwas einfachere Aufgabe. Ihr sollt für ein Multiplayer Snake Game eine AI schreiben welche eure Schlange solange wie Möglich wachsen lässt. Für alle die Snake nicht kennen, hier eine kurze Erklärung:
Snake ist ein Singleplayer Spiel. Ihr steuert eine Schlange die immer weiter wächst. Jedes mal wenn Ihr ein Futterstück auf der Karte einsammelt, wächst eure Schlange um ein Feld und ihr erhaltet Punkte. Ziel ist es seine Schlange so lang wie möglich zu füttern. Das Spiel endet sobald sich die Schlange selber beißt. Je nach Variation könnt ihr am Spielfeldrand hinaus und kommt auf der gegenüberliegenden Seite wieder hinein.
In der hier angebotenen Multiplayer Variante spielen 2 AI's gegeneinander. Das Ziel bleibt das Gleiche, eure Schlange soll so lang werden wie nur möglich. Jedoch endet das Spiel sobald ihr gegen die Wand am Spielfeldrand steuert oder ihr in den eigenen oder fremden Schlangenkörper beißt. Beide Schlangen bewegen sich zeitgleich, dadurch ist es möglich dass auch beide Schlangen verlieren. Dies wird als unentschieden gewertet.
Die AI's treten in einen Punkte basierenden KO System an. Das bedeutet, 2 AI's spielen mehrere Runden gegeneinander und sammeln Punkte, jene AI welche die meisten Punkte sammeln konnte, rückt in die nächste Runde vor. Dies wird solange wiederholt bis wir einen endgültigen Sieger haben. Die Punkte werden je nach Spielfeldgröße vergeben. Dabei erhaltet ihr 1% multipliziert mit der Anzahl der Felder an Punkten für jedes gefressene Futterstück. Und 25% an Punkten für jede gewonnene (kein unentschieden) Runde. Ein Beispiel: Bei einer Spielfeldgröße von 20x20 (also 400 Felder) erhaltet ihr für jedes Futterstück 4 Punkte und für jeden Sieg 100 Punkte.
Die Interaktion zur AI habe ich euch so angenehm wie möglich gestaltet. Ihr registriert eure AI einfach mit der Funktion _AIFight_Register ( $sUser, $hFunction [, $sDatabase = Null ]). In dem ersten Parameter übergebt ihr einfach euren AutoIt Benutzernamen. In dem zweiten Parameter wird der Funktionshandle zu eurer AI entgegen genommen. Im dritten Parameter (falls benötigt) könnt ihr den Dateinamen zu eurer Datenbank angeben. Achtung! Bitte keine Pfadangaben, diese wird selbständig in der Ordnerstruktur gesucht. Tatsächlich nur den Namen mit der entsprechenden Dateiendung. Im angehängten ZIP Archiv findet ihr die gesamten Wettbewerbsdateien. Darunter auch einen Ordner namens User. Dort habt ihr eine Beispiel AI wie ihr eure AI registriert. Ihr könnt die Dateien einfach umbenennen und dies als Vorlage nutzen.
Eure AI nimmt 4 Parameter entgegen: User_AI ( $aMap, $aSnakeMe, $aSnakeRival, $hTime ). Im ersten Parameter erhaltet ihr ein 2 dimensionales Array mit der kompletten Map. Damit ihr wisst was was ist, habe ich euch schon Konstanten vordefiniert, dazu komme ich aber gleich erst. Im zweiten Parameter erhaltet ihr ein 2 Dimensionales Array zu eurer eigenen Schlange. Das Array ist folgendermaßen aufgebaut:
$aSnakeMe[0][0] = Anzahl der Elemente
$aSnakeMe[0][1] = Blickrichtung der Schlange
$aSnakeMe[1][0] = Schlangenkopf x-Koordinate
$aSnakeMe[1][1] = Schlangenkopf y-Koordinate
$aSnakeMe[i][0] = Körperteil x-Koordinate
$aSnakeMe[i][1] = Körperteil y-Koordinate
Über den dritten Parameter erhaltet ihr die Position das Array der gegnerischen Schlange. Dieses Array ist genauso aufgebaut wie der euren Schlange. Im vierten und letzten Parameter erhaltet ihr ein Timerhandle. Mithilfe der Built-in Funktion TimerDiff ( handle ) könnt ihr immer nachmessen wie viel Zeit seit dem Funktionsaufruf vergangen ist. Zum testen eurer AI registriert eure Funktion bitte 2 mal da ich keine eigene AI als Testgegner integriert habe.
In der AIFight.au3 findet ihr das eigentliche Spiel. Dieses erstellt lediglich eine Log Datei. Dies hat spielt später für die Auswertung und das Debuggen eurer AI eine Rolle. Einmal soll das die Auswertung fix gehen und zum anderen könnt ihr so jede Aktion nachlesen. Auch später nach der Auswertung erhaltet ihr alle Log Dateien damit ihr sehen könnt, wie die anderen AI's (sowie eure eigene) agiert haben. In Zeile 12 braucht ihr nur eure eigene au3 Datei inkludieren, damit ihr eure eigene AI testen könnt. In der AIFight_GUI.au3 könnt ihr euch die Bewegungen ansehen. Einfach mal ausprobieren.
Soa, nun steht euch aber auch noch eine andere Funktionen zur Verfügung. Mithilfe der Funktion _AIFight_LogFile ( $sData ) könnt ihr in der Log Datei eigene Einträge verfassen. Wichtig ist nur, dass ihr nicht das Zeichen größer als („>“) nutzen dürft. Ansonsten steht euch frei was ihr da rein schreibt. Um nicht ständig zwischen eurer au3 und der AIFight.au3 wechseln zu müssen, könnt ihr in eure AI die Funktion _AIFight_Run( $sWorkingDir ) benutzen. Ihr müsst lediglich einen relativen Pfad zu der AIFight.au3 angeben. Danach wird diese bei jedem ausführen selbständig gestartet. So könnt ihr euch ganz auf eure AI konzentrieren.
Zu guter Letzt kommen wir noch zu den Konstanten. Ihr habt einmal allgemeine Informationen zu den Spielbedingungen.
[autoit]Global Const $AIFight_DBSize = 0x00100000
Global Const $AIFight_Time = 3000
Global Const $AIFight_MapX = 10
Global Const $AIFight_MapY = 10
Global Const $AIFight_Rounds = 1
Global Const $AIFight_PointsFeed = Ceiling($AIFight_MapX * $AIFight_MapY * 0.01)
Global Const $AIFight_PointsWin = Ceiling($AIFight_MapX * $AIFight_MapY * 0.25)
Die erste Konstante gibt an welche Dateigröße (in diesem Fall 1MB) eure Datenbank (falls vorhanden) in Byte nicht überschreiten darf. Die zweite Variable steht für die Anzahl der Millisekunden die ihr für einen Funktionsaufruf zur Verfügung habt. Später wird der Durchschnitt berechnet, im Grunde könnt ihr auch einmal 5 Sekunden und einmal 1 Sekunde nutzen, bleibt ja bei 3 Sekunden im Durchschnitt. Die nächsten Beiden geben die Spielfeldgröße an, und die letzte die Anzahl der Runden die 2 AI's gegeneinander spielen.
Die nächsten 4 Konstanten $AIFight_Top, $AIFight_Right, $AIFight_Bottom und $AIFight_Left geben die Blickrichtung der Schlange an. Einer dieser Werte ist in dem Array des 2ten bzw. 3ten Parameters gespeichert ($aSnake[0][1]).
Nun kommen wir zum Rückgabewert eurer AI, ihr müsst einen der 3 Konstanten zurückgeben:
[autoit]Global Const $AIFight_MoveStraight = 0
Global Const $AIFight_MoveRight = 1
Global Const $AIFight_MoveLeft = 3
Ihr gebt also an in welche Richtung (ausgehend von der Blickrichtung) sich eure Schlange bewegen soll. Entweder gerade aus, nach rechts oder nach links.
Die nächsten 4 Konstanten sind die allgemeinen Werte. Mithilfe einer BitAND Abfrage könnt ihr im Array (welches ihr im 1. Parameter übergeben bekommt) ermitteln ob ein Feld besetzt ist oder nicht.
[autoit]Global Const $AIFight_MapFree = 0
Global Const $AIFight_MapFeed = 1
Global Const $AIFight_MapSolid = 2
Global Const $AIFight_MapWall = 6 ; 4 or MapSolid
MapFree und MapFeed kommen lediglich alleine vor. Ist ein Feld frei, so ist es mit MapFree (0) gekennzeichnet, liegt auf dem Feld ein Futterstück, so ist es mit MapFeed (1) belegt. Mit MapSolid (2) sind alle Felder gekennzeichnet die durch eine Schlange oder durch eine Mauer verdeckt sind. Dafür benötigt ihr die BitAND Funktion. Im Grunde relativ einfach zu benutzen: If BitAND($aMap[x][y], $AIFight_MapSolid) Then .... Die MapWall (6) kennzeichnen die Wände. Diese sollten nach Möglichkeit vermieden werden.
Ansonsten stehen euch noch die Körperteil spezifischen Konstanten zur Verfügung. Ich denke dass weitere Erklärungen nicht notwendig sind. Alles was also in der AIFightConst.au3 enthalten ist, dürft ihr nach Herzenslust einsetzen. Falls Fragen auftauchen, immer nachfragen.
Die Spielfeldgröße sowie Anzahl der Runden lege ich nach dem Abgabetermin fest. Lediglich die erlaubte Datenbankgröße sowie die 3 Sekunden Ausführungszeit stehen schon fest. Abgabetermin ist der 18. März 2015 um 23:59 Uhr. Wer mir später seine Einsendung schickt nimmt nicht am Wettbewerb teil. Ich wünsche viel Spaß und gutes gelingen!
PS: Dies ist mein erster Wettbewerb in dieser Form. Daher brauchte ich diese lange Vorbereitungszeit um erst mal alles zu planen. Die kommenden Wettbewerbe werden auch in dieser Form ablaufen. Jedoch werde ich immer versuchen euch alles so angenehmer wie möglich zu machen. Falls Bugs auftreten bitte sofort melden damit ich's schnellstmöglich fixen kann. Und denkt daran eure reservierten Präfixe zu nutzen bzw. noch einen zu registrieren!