Projekt:2021/LightsOut: Unterschied zwischen den Versionen

Aus Informatik-Box
Zur Navigation springen Zur Suche springen
 
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 7: Zeile 7:
== Projektziel ==
== Projektziel ==
Programmiert das Spiel [http://www.matheundfraktale.de/MathemSpielereien/LightsOut/LightsOut.php LightsOut] mit Python. Nutzt TigerJython als Entwicklungsumgebung und orientiert euch an eurer Implementierung von Tic Tac Toe ([[#Tic-Tac-Toe_Musterl.C3.B6sung|unten findest ihr auch eine Musterlösung]]).
Programmiert das Spiel [http://www.matheundfraktale.de/MathemSpielereien/LightsOut/LightsOut.php LightsOut] mit Python. Nutzt TigerJython als Entwicklungsumgebung und orientiert euch an eurer Implementierung von Tic Tac Toe ([[#Tic-Tac-Toe_Musterl.C3.B6sung|unten findest ihr auch eine Musterlösung]]).
Benutze [[#GameGrid|die Vorlage]] für den Start des Projektes.


[[Bild:20210526204049 TigerJython.gif|center]]
[[Bild:20210526204049 TigerJython.gif|center]]
Zeile 19: Zeile 21:
from gamegrid import *
from gamegrid import *


# Wird aufgerufen, wenn die Maus im Fenster geklickt wird.
# e.getX() und e.getY() sind die Koordinaten des Pixels, der angeklickt wurde.
def mausklick(e):
def mausklick(e):
loc = toLocation(e.getX(), e.getY())
    loc = toLocation(e.getX(), e.getY())
# Hier die Aktionen bei Mausklick programmieren
 
    aendereZelle(loc)
   
    # Nutze aendereZelle um die Zellen links, rechts, ober- und
    # unterhalb der geklickten Zelle zu ändern.
    aendereZelle(Location(loc.x-1,loc.y))  # Zelle links
   
    bg.drawGridLines(getGridColor())
    refresh()
    return True
 
# Ändert die Zelle "loc" von schwarz nach grün
# oder von grün nach schwarz
def aendereZelle(loc):
    pass


# 3x3 Quadrate mit der Kantenlänge 50.
makeGameGrid(5, 5, 80, Color.gray, False, mousePressed = mausklick)
# Das Gitter wird in grau (gray) gezeichnet und Steuerungselemente werden ausgeblendet (False).
setTitle("LightsOut")
# Bei Mausklicks wird die Funktion "mausklick" aufgerufen.
makeGameGrid(3, 3, 50, Color.gray, False, mousePressed = mausklick)


# Hole den Hintergrund, um damit zu arbeiten
bg = getBg()
bg = getBg()
 
bg.clear(Color.green)
# Zeige das Spielfenster
bg.drawGridLines(getGridColor())
show()
show()
</syntaxhighlight>
</syntaxhighlight>
Zeile 42: Zeile 53:


; <code>makeGameGrid(Spaltenzahl, Zeilenzahl, Kantenlänge, Color, Steuerung, mousePressed=Funktionsname)</code>
; <code>makeGameGrid(Spaltenzahl, Zeilenzahl, Kantenlänge, Color, Steuerung, mousePressed=Funktionsname)</code>
: Erzeugt ein Spielfenster mit <code>Spaltenzahl</code> mal <code>Zeilenzahl</code> Quadraten der Größe <code>Kantenlänge </code>. Das Gitternetz wird in der Farbe <code>Color</code> gezeichnet (um kein Gitter zu zeichnen, kann <code>None</code> angegeben werden). Steuerung ist ein Wahrheitswert (<code>True</code> oder <code>False</code>) der angibt, ob im Spielfenster Stuerungselement angezeigt werden. Mit <code>mousePressed</code> wird eine Funktion angegeben, die aufgerufen wird, wenn mit der Maus in das Fenster geklickt wird.
: Erzeugt ein Spielfenster mit <code>Spaltenzahl</code> mal <code>Zeilenzahl</code> Quadraten der Größe <code>Kantenlänge </code>. Das Gitternetz wird in der Farbe <code>Color</code> gezeichnet (um kein Gitter zu zeichnen, kann <code>None</code> angegeben werden). Steuerung ist ein Wahrheitswert (<code>True</code> oder <code>False</code>) der angibt, ob im Spielfenster Steuerungselement angezeigt werden. Mit <code>mousePressed</code> wird eine Funktion angegeben, die aufgerufen wird, wenn mit der Maus in das Fenster geklickt wird.
; <code>bg = getBg()</code>
; <code>bg = getBg()</code>
: Speichert den Hintergrund in der Variablen <code>bg</code>. Der Hintergrund hat verschiedene Funktionen, die mit <code>bg.funktionsname()</code> aufgerufen werden können:
: Speichert den Hintergrund in der Variablen <code>bg</code>. Der Hintergrund hat verschiedene Funktionen, die mit <code>bg.funktionsname()</code> aufgerufen werden können:
Zeile 52: Zeile 63:
:: Ermittelt die Farbe des Quadrats an der Position <code>Location</code>.
:: Ermittelt die Farbe des Quadrats an der Position <code>Location</code>.
; <code>loc = Location(i, j)</code>
; <code>loc = Location(i, j)</code>
: Speichert eine Position mit der Spaltennummer <code>i</code> und der Zeilennummer <code>y</code> in der Variablen <code>loc</code>. Positionen können für verschiedne andere Funktionen als Parameter benutzt werden.
: Speichert eine Position (Zelle) mit der Spaltennummer <code>i</code> und der Zeilennummer <code>y</code> in der Variablen <code>loc</code>. Positionen können für verschiedene andere Funktionen als Parameter benutzt werden.
:; <code>loc.x</code>
:; <code>loc.x</code>
:: Die x-Koordinate der Position.
:: Die Spaltennummer der Zelle.
:; <code>loc.y</code>
:; <code>loc.y</code>
:: Die y-Koordinate der Position.
:: Die Zeilennummer der Zelle.
; <code>toLocation(x, y)</code>
; <code>toLocation(x, y)</code>
: Ermittelt für den Pixel an der Koordinate <code>x</code>, <code>y</code> die Position, in der der Pixel liegt.
: Ermittelt für das Pixel an der Koordinate <code>x</code>, <code>y</code> die Position, in der der Pixel liegt.
; <code>refresh()</code>
; <code>refresh()</code>
: Aktualisiert den Zeichenbereich und zeichnet alle Elemente neu.
: Aktualisiert den Zeichenbereich und zeichnet alle Elemente neu.
Zeile 66: Zeile 77:
: Die Farbe der Gitternetzlinien (die zu Beginn an <code>makeGamegrid</code> übergeben wurden).
: Die Farbe der Gitternetzlinien (die zu Beginn an <code>makeGamegrid</code> übergeben wurden).


== Mögliche Erweiterungen ==
# Der Spieler kann die Größe des Spielfeldes zu Beginn wählen (erinnere dich an die <code>input()</code> Funktion).
# Führe eine zweite Farbe ein, auf die die Zellen zunächst wechseln, bevor sie ausgehen. (Wie eine Ampel mit drei Phasen.)


=== Tic-Tac-Toe Musterlösung ===
== Tic-Tac-Toe Musterlösung ==
<syntaxhighlight lang="python" line="1">
<syntaxhighlight lang="python" line="1">
from gamegrid import *
from gamegrid import *
Zeile 77: Zeile 92:
     loc = toLocation(e.getX(), e.getY())
     loc = toLocation(e.getX(), e.getY())
      
      
     # Programmiere hier, was passieren soll
     # Zelle des Mausklicks prüfen und ggf. Farbe setzen
    if bg.getColor(loc) == Color.black:
        if player == 1:
            bg.fillCell(loc, Color.green)
        else:
            bg.fillCell(loc, Color.blue)
           
    # Sieg prüfen und ggf. Feld einfärben
    if pruefeSieg():
        if player == 1:
            bg.clear(Color.green)
        else:
            bg.clear(Color.blue)
    # ... sonst Unentschieden prüfen und ggf. färben
    elif pruefeUnentschieden():
        bg.clear(Color.yellow)
      
      
     # Tipps: https://qr-lernhilfen.de/mobileUrl?url=ef8305935be33077
     # Spieler wechseln
    if player == 1:
        player = 2
    else:
        player = 1
      
      
     refresh()
     refresh()
    return True
def pruefeSieg():
    # Zeilen und SPalten prüfen
    for i in range(3):
        if pruefeZeile(i):
            return True
        elif pruefeSpalte(i):
            return True
    # Diagonalen prüfen
    return pruefeDiagonalen()
# prüft beide Diagonalen
def pruefeDiagonalen():
    if bg.getColor(Location(0,0)) != Color.black and bg.getColor(Location(0,0)) == bg.getColor(Location(1,1)) and bg.getColor(Location(1,1)) == bg.getColor(Location(2,2)):
        return True
    if bg.getColor(Location(2,0)) != Color.black and bg.getColor(Location(2,0)) == bg.getColor(Location(1,1)) and bg.getColor(Location(1,1)) == bg.getColor(Location(0,2)):
        return True
    return False
# Prüft genau eine Zeile
def pruefeZeile(y):
    return bg.getColor(Location(0,y)) != Color.black and bg.getColor(Location(0,y)) == bg.getColor(Location(1,y)) and bg.getColor(Location(1,y)) == bg.getColor(Location(2,y))
# Prüft genau eine Spalten
def pruefeSpalte(x):
    return bg.getColor(Location(x,0)) != Color.black and bg.getColor(Location(x,0)) == bg.getColor(Location(x,1)) and bg.getColor(Location(x,1)) == bg.getColor(Location(x,2))
# Prüft, ob noch schwarze (freie) Felder existieren
def pruefeUnentschieden():
    for i in range(3):
        for j in range(3):
            if bg.getColor(Location(i,j)) == Color.black:
                return False
     return True
     return True



Aktuelle Version vom 6. April 2022, 21:36 Uhr

Seite zum Projekt LightsOut des Informatik 9 Diff im Schuljahr 2021/22.

Projektziel

Programmiert das Spiel LightsOut mit Python. Nutzt TigerJython als Entwicklungsumgebung und orientiert euch an eurer Implementierung von Tic Tac Toe (unten findest ihr auch eine Musterlösung).

Benutze die Vorlage für den Start des Projektes.

20210526204049 TigerJython.gif

GameGrid

TigerJython kommt mit verschiedenen Modulen, zum Beispiel dem bekannten gturtle Modul, das Du bisher mit from gturtle import * eingebunden hast. Für die Entwicklung von Spielen gibt es die Bibliothek gamegrid, die mit from gamegrid import * importiert wird.

Die folgende Programmvorlage kannst du als Startpunkt für dein Spiel benutzen:

from gamegrid import *

def mausklick(e):
    loc = toLocation(e.getX(), e.getY())

    aendereZelle(loc)
    
    # Nutze aendereZelle um die Zellen links, rechts, ober- und 
    # unterhalb der geklickten Zelle zu ändern.
    aendereZelle(Location(loc.x-1,loc.y))  # Zelle links
    
    bg.drawGridLines(getGridColor())
    refresh()
    return True

# Ändert die Zelle "loc" von schwarz nach grün 
# oder von grün nach schwarz
def aendereZelle(loc):
    pass

makeGameGrid(5, 5, 80, Color.gray, False, mousePressed = mausklick)
setTitle("LightsOut")

bg = getBg()
bg.clear(Color.green)
bg.drawGridLines(getGridColor())
show()

Wichtige Funktionen

Du kannst dir die Hilfe zu GameGrid in TigerJython anzeigen lassen (wie die Hilfe zu GTurtle). Um "LightsOut" zu implementieren, reichen aber theoretisch diese Funktionen:

makeGameGrid(Spaltenzahl, Zeilenzahl, Kantenlänge, Color, Steuerung, mousePressed=Funktionsname)
Erzeugt ein Spielfenster mit Spaltenzahl mal Zeilenzahl Quadraten der Größe Kantenlänge . Das Gitternetz wird in der Farbe Color gezeichnet (um kein Gitter zu zeichnen, kann None angegeben werden). Steuerung ist ein Wahrheitswert (True oder False) der angibt, ob im Spielfenster Steuerungselement angezeigt werden. Mit mousePressed wird eine Funktion angegeben, die aufgerufen wird, wenn mit der Maus in das Fenster geklickt wird.
bg = getBg()
Speichert den Hintergrund in der Variablen bg. Der Hintergrund hat verschiedene Funktionen, die mit bg.funktionsname() aufgerufen werden können:
bg.fillCell(Location, Color)
Färbt das Quadrat an der Position Location in der Farbe Color ein.
bg.drawGridLines(Color)
Zeichnet die Gitternetzlinien in der Farbe Color.
bg.getColor(Location)
Ermittelt die Farbe des Quadrats an der Position Location.
loc = Location(i, j)
Speichert eine Position (Zelle) mit der Spaltennummer i und der Zeilennummer y in der Variablen loc. Positionen können für verschiedene andere Funktionen als Parameter benutzt werden.
loc.x
Die Spaltennummer der Zelle.
loc.y
Die Zeilennummer der Zelle.
toLocation(x, y)
Ermittelt für das Pixel an der Koordinate x, y die Position, in der der Pixel liegt.
refresh()
Aktualisiert den Zeichenbereich und zeichnet alle Elemente neu.
Color.green
Die Farbe "Grün". green kann durch andere (englische) Farbnamen ersetzt werden (red, blue, ...). Farben können wie gewohnt mit == verglichen werden (z.B. Color.green == Color.red ist False).
getGridColor()
Die Farbe der Gitternetzlinien (die zu Beginn an makeGamegrid übergeben wurden).

Mögliche Erweiterungen

  1. Der Spieler kann die Größe des Spielfeldes zu Beginn wählen (erinnere dich an die input() Funktion).
  2. Führe eine zweite Farbe ein, auf die die Zellen zunächst wechseln, bevor sie ausgehen. (Wie eine Ampel mit drei Phasen.)

Tic-Tac-Toe Musterlösung

from gamegrid import *

player = 1

def mausklick(e):
    global player
    loc = toLocation(e.getX(), e.getY())
    
    # Zelle des Mausklicks prüfen und ggf. Farbe setzen
    if bg.getColor(loc) == Color.black:
        if player == 1:
            bg.fillCell(loc, Color.green)
        else:
            bg.fillCell(loc, Color.blue)
            
    # Sieg prüfen und ggf. Feld einfärben
    if pruefeSieg():
        if player == 1:
            bg.clear(Color.green)
        else:
            bg.clear(Color.blue)
    # ... sonst Unentschieden prüfen und ggf. färben
    elif pruefeUnentschieden():
        bg.clear(Color.yellow)
    
    # Spieler wechseln
    if player == 1:
        player = 2
    else:
        player = 1
    
    refresh()
    return True

def pruefeSieg():
    # Zeilen und SPalten prüfen
    for i in range(3):
        if pruefeZeile(i):
            return True
        elif pruefeSpalte(i):
            return True
    # Diagonalen prüfen
    return pruefeDiagonalen()

# prüft beide Diagonalen
def pruefeDiagonalen():
    if bg.getColor(Location(0,0)) != Color.black and bg.getColor(Location(0,0)) == bg.getColor(Location(1,1)) and bg.getColor(Location(1,1)) == bg.getColor(Location(2,2)):
        return True
    if bg.getColor(Location(2,0)) != Color.black and bg.getColor(Location(2,0)) == bg.getColor(Location(1,1)) and bg.getColor(Location(1,1)) == bg.getColor(Location(0,2)):
        return True
    return False

# Prüft genau eine Zeile
def pruefeZeile(y):
    return bg.getColor(Location(0,y)) != Color.black and bg.getColor(Location(0,y)) == bg.getColor(Location(1,y)) and bg.getColor(Location(1,y)) == bg.getColor(Location(2,y))

# Prüft genau eine Spalten
def pruefeSpalte(x):
    return bg.getColor(Location(x,0)) != Color.black and bg.getColor(Location(x,0)) == bg.getColor(Location(x,1)) and bg.getColor(Location(x,1)) == bg.getColor(Location(x,2))

# Prüft, ob noch schwarze (freie) Felder existieren
def pruefeUnentschieden():
    for i in range(3):
        for j in range(3):
            if bg.getColor(Location(i,j)) == Color.black:
                return False
    return True

makeGameGrid(3, 3, 100, Color.gray, False,
    mousePressed = mausklick)
setTitle("TicTacToe")

bg = getBg()

show()