Jython

LightsOut Game


Das Spiel besteht aus 25 Lampen, die in einem 5 x 5 Grid angeordnet sind. Zu Beginn des Spiels sind alle Lampen eingeschaltet. Wenn man auf eine Lampe klickt, wird sie und die 4 benachbarten Lampen "invertiert", z. B.:

Ziel des Spiels ist es, alle Lampen auszuschalten.

 
Ausführen mit Webstart
# LightsOut.py

from gamegrid import *
            
def pressCallback(e):
     loc = toLocationInGrid(e.getX(), e.getY())
     locs  = [0] * 5
     locs[0] = Location(loc.x, loc.y)
     locs[1] = Location(loc.x, loc.y - 1)
     locs[2] = Location(loc.x, loc.y + 1)
     locs[3] = Location(loc.x - 1, loc.y)
     locs[4] = Location(loc.x + 1, loc.y)
 
     for i in range(5):
         a = getOneActorAt(locs[i])
         if a != None:
              a.showNextSprite()
     refresh()
     return True    

makeGameGrid(5, 5, 50, Color.black, False, 
     mousePressed = pressCallback)
setTitle("LightsOut")
for i in range(5):
     for k in range(5):
          lamp = Actor("sprites/lightout.gif", 2)
          addActor(lamp, Location(i, k))
          lamp.show(1)     
show()
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

Das Spielfenster besteht aus 5 Zeilen und 5 Spalten. Zuerst erzeugen wir in jeder der 25 Zellen eine eingeschaltete Lampe (lamp.show(1)
In der Callbackfunktion pressCallback() wird zuerst die Location loc des Mausklicks bestimmt. Diese hat die Koordinaten x, y.
Dann wird eine Liste mit den Locations der 5 betroffenen Lampen erstellt:

locs = [0] * 5
erzeugt eine Liste mit 5 Elementen (Locations)

Die Locations der benachbarten Zellen werden gemäss rechts stehender Skizze festgelegt.
 
Schliesslich werden die betroffenen Lampen, mit showNextSprite() invertiert.
Da beim Klick in die Randzellen einige benachbarte Zellen ausserhalb des Spielfensters liegen, muss mit
if a != None:
überprüft werden, ob eine Lampe in dieser Zelle existiert.
refresh(): Da wir keine Animation starten, müssen wir nach jedem Klick die Spielsituation aktualisieren

 

Mit der Methode getNeighbourLocations(distance), die alle benachbarten Locations im gegebenen Abstand zurückgibt, ergibt sich eine zweite, elegantere Lösungsvariante:

# LightsOut1.py

from gamegrid import *
            
def pressCallback(e):
     loc = toLocationInGrid(e.getX(), e.getY())
     locs = toList(loc.getNeighbourLocations(0.5))
     locs.append(loc)
     for i in range(5):
         a = getOneActorAt(locs[i])
         if (a != None):
              a.showNextSprite()
     refresh()
     return True    

makeGameGrid(5, 5, 50, Color.black, False, 
     mousePressed = pressCallback)
setTitle("LightsOut")
for i in range(5):
     for k in range(5):
          lamp = Actor("sprites/lightout.gif", 2)
          addActor(lamp, Location(i, k))
          lamp.show(1)     
show()
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

Erklärungen zum Programmcode:

Im pressCallback wird die Liste mit den Locations der 5 betroffenen Lampen wird wie folgt erstellt:
Zuerst wird die Location des Mausklicks als loc erfasst..
toList(loc.getNeigbourLocations(0.5)) gibt eine Liste aller Locations Abstand 0.5
Die mittlere Zelle wird mit append() hinzugefügt.



 
Die Invertierung der Zellen ist gleich programmiert, wie in der Lösungsvariante 1

 

 


Aufgaben:

1)


Tic-Tac-Toe ist ein bekanntes Spiel, bei dem zwei Spieler abwechslungsweise Kreuze oder Kringel in die Felder eines 3x3-Gitters setzen mit dem Ziel, als erster drei eigene Zeichen in einer horizontalen, vertikalen Linie oder einer der Diagonalen zu haben.

Für die Markierung der Felder verwendest du die Sprites mark_0.gif und mark_1.gif.
mark = Actor("sprites/mark.gif", 2)

 

 



Damit die Marke nach jedem Klick umschaltet, führst du eine Variable player ein, die zwischen dem Wert 1 und 2 umschaltet. Im Hauptprogramme ordnest du dem player zuerst den Wert 1. Damit du den Wert der Variable in der Calback-Funktion verändern kannst, musst du sie als global bezeichnen (global player).

In der einfachsten Version des Spieles setzen die Spieler abwechslungweise ihre Marken und kontrollieren selbst das Ergebnis.

 


2)

Ergänze das Tic-Tac-Toe-Spiel mit einer Überprüfung der Spielsituation. Diese kann zum Beispiel nach jedem Zug mit folgendem Trick erfolgen: Die horizontale, vertikale und diagonale Belegung des Spielbretts wird in einem kommagetrennten Stringmuster der Form XOX,XX- ,O-O, ... dargestellt (leere Zellen erhalten das Zeichen '-'). Wenn XXX bzw. OOO in diesem String vorkommen, hat ein Spieler gewonnen.