Seite 1 von 1
Tetris AI
Verfasst: Freitag 28. September 2007, 10:13
von Rebecca
Ich wollte gerne einen Tetrinet-Bot haben, da ich gerne mal zwischendurch ein kleines Spielchen spielen moechte, ohne immer Internet-Zugang zu haben. Das Herz der Tetris-AI findet sich hier:
Sourcecode. Man kann es als eigenstaendiges Programm ausfuehren und zusehen, wie das Programm allein vor sich hin spielt... (Windows-User sollten in der main-Methode das display_colour() durch display() ersetzen.)
Im Moment ist nur der Classic Mode implementiert, d.h. es gibt keine Spezialbloecke. Die AI basiert auf der Idee, zu einem zu plazierenden Block an allen moeglichen Positionen die leeren und besetzten Nachbarn mit bestimmten Gewichtungen zu zaehlen. Zu jedem moeglichen Tetris-Block speichere ich dazu drei "Matrizen": Eine fuer die Abmessungen des Blocks selbst, eine fuer die Gewichtung der besetzten Nachbarn und eine fuer die Gewichtung der leeren Nachbarn. Dieses einfache Prinzip funktioniert schon ziemlich gut, alleine spielt die AI eigentlich endlos.
Wenn man allerdings gegen die AI spielt, ist sie noch relativ einfach zu besiegen. Was die AI im Gegensatz zum Menschen noch nicht kann:
- * An ueberlappenden Bloecken vorbeimanoevrieren
* Den naechsten zu spielenden Block schon mit einbeziehen ("Vorschau")
* Es darauf anlegen, mehr als eine Zeile auf einmal abzubauen
Das erste ist noch relativ einfach zu implementieren, der Rest schon ziemlich kompliziert. Naja, man kann die AI natuerlich auch dadurch schwerer zu besiegen machen, indem man sie sehr schnell spielen laesst. Oder man spielt gegen mehrere AIs im Team...
Verfasst: Freitag 28. September 2007, 11:47
von abgdf
Hallo,
muß erstmal begreifen, was das so macht ...
In Zeile 743 erhalte ich noch eine Fehlermeldung.
Meintest Du:
Code: Alles auswählen
if lines > 1:
if lines < 4:
addlines = lines - 1
else:
addlines = 4
?
Verfasst: Freitag 28. September 2007, 11:53
von Rebecca
Ja. Ab Python 2.5 kann man das in einer Zeile schreiben.

Verfasst: Freitag 28. September 2007, 12:39
von BlackJack
Müsste ``addlines = max(lines - 1, 4)`` nicht auch gehen? Wenn man es denn unbedingt in einer Zeile haben möchte.

Verfasst: Freitag 28. September 2007, 13:21
von Rebecca
BlackJack hat geschrieben:max(lines - 1, 4)
Das waere immer 4...
Verfasst: Freitag 28. September 2007, 15:37
von rayo
Verfasst: Dienstag 2. Oktober 2007, 15:35
von Rebecca
Ich habe es jetzt erweitert, sodass auch an ueberhaengenden Bloecken vorbeimanoevriert werden kann, allerdings wird dabei der Block nicht nochmal gedreht.
Ich habe ein paar Unittests dafuer geschrieben, habe aber ein Problem mit
failUnlessRaises:
Code: Alles auswählen
import unittest
import game
class Field(unittest.TestCase):
def test_add_line(self):
field = game.Field()
field.fill_random()
self.failUnlessRaises(game.PlayerDeadException, field.add_line(),
"Can't insert line into full field.")
if __name__ == "__main__":
unittest.main()
Nach meinem Verstaendnis sollte der Test erfolgreich sein, aber ich bekomme einen Error wegen der geschmissenen PlayerDeadException:
Code: Alles auswählen
======================================================================
ERROR: test_add_line (__main__.Field)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test1.py", line 11, in test_add_line
self.failUnlessRaises(game.PlayerDeadException, field.add_line(),
File "/suse/home/rbreu/zeugs/python/tetribot/game.py", line 498, in add_line
raise PlayerDeadException()
PlayerDeadException

Verfasst: Dienstag 2. Oktober 2007, 15:48
von mkesper
Rebecca hat geschrieben:Ich habe ein paar Unittests dafuer geschrieben, habe aber ein Problem mit failUnlessRaises:
Nach meinem Verstaendnis sollte der Test erfolgreich sein, aber ich bekomme einen Error wegen der geschmissenen PlayerDeadException:
Vage Vermutung: Liegt es daran, daß nicht game.PlayerDeadException sondern PlayerDeadException geraist wird?
Verfasst: Dienstag 2. Oktober 2007, 15:54
von Rebecca
Bau ich den obigen Code um und fange die Exception ab:
Code: Alles auswählen
import unittest
import game
class Field(unittest.TestCase):
def test_add_line(self):
field = game.Field()
field.fill_random()
try:
self.failUnlessRaises(game.PlayerDeadException, field.add_line(),
"Can't insert line into full field.")
except Exception, e:
print type(e)
if __name__ == "__main__":
unittest.main()
erhalte ich:
Das ist exakt dasselbe. (Oder ich habe Tomaten auf den Augen.)
Verfasst: Dienstag 2. Oktober 2007, 15:58
von BlackJack
Vielleicht solltest Du `field.add_line` nicht aufrufen sondern nur übergeben!?
Verfasst: Dienstag 2. Oktober 2007, 16:11
von Rebecca
BlackJack hat geschrieben:Vielleicht solltest Du `field.add_line` nicht aufrufen sondern nur übergeben!?
Hehe, guter Tipp. Jaja, die Tomaten... War mich voll am Wundern, weil ich ja auch noch faelschlicherweise einen String mit uebergeben habe und er schon wegen falscher Anzahl von Paramter haette meckern sollen...

Verfasst: Donnerstag 4. Oktober 2007, 14:52
von mkesper
D'oh!
