Sōkoban, japanisch «Lagerhausverwalter» ist ein Spiel, dass 1982 in Japan erstmals erschien. (https://www.sokoban.jp)
Bis heute sind zahlreiche Adaptionen und Erweiterungen erschienen.
Prinzip
Der Spieler befindet sich auf einem Raster, er kann sich in alle 4 Himmelsrichtungen bewegen, sofern keine Hindernisse dort stehen. Ziel ist es, alle Kisten auf ihren Ziel-Platz zu schieben. Kisten können nur vom Spieler weggestossen werden und dies nur, wenn auf der anderen Seite der Kiste keine Mauer und auch keine andere Kiste steht.
Aufgabe: Kennenlernen
Hier kannst du eine Runde Sokoban spielen:
👉 https://sokoban.info
Spiel-Logik
Wie wollen wir das Spiel programmieren? Wer entscheidet welche Spielzüge möglich sind und wann ein Level beendet ist?
Aufgabe: Regeln
Haltet die Regeln des Spieles möglichst kurz aber komplett schriftlich fest.
Klassen
Welche Klassen wollen wir definieren? Welche Eigenschaften und Methoden sollen die Objekte haben?
Aufgabe: Design
- Erarbeitet einen Vorschlag in Zweier- oder Dreiergruppen und notiert diesen.
- Stellt den Vorschlag den anderen vor
Wir werden die Vorschläge gemeinsam diskutieren und uns hoffentlich auf ein Design einigen.
Lösung: Design
- Diamanten-Pfeile
- zeigen die Verwendung der Objekte der Klassen an. So besitzt das
Board
eine Liste mit den Kistencrates
, ein Objekt vom TypPlayer
und eine zwei-dimensionale Liste mit Elementen vom TypTile
. - dreieckige Pfeile
- weisen auf Vererbung hin. So erben
Ground
,Goal
undWall
von der KlasseTile
;Crate
undPlayer
erben vonMovable
.
Levels
Sokoban-Levels können im sogenannten xsb
-Format gespeichert werden. Dabei handelt es sich um eine Text-Datei mit speziellen Zeichen. Die Zeichen beschreiben die Felder des Levels sowie die Start-Position des Spielers.
Zeichen | Element |
---|---|
# | Wand |
@ | Spieler |
$ | Kiste |
. | Zielfeld |
| leerer Raum (Boden) |
+ | Spieler auf Zielfeld |
* | Kiste auf Zielfeld |
Der einfachste lösbare Level würde wie folgt aussehen:
#####
#@$.#
#####
Ein etwas spannender Level ist hier abgebildet:
#####
# #
#$ #
### $##
# $ $ #
### # ## # ######
# # ## ##### ..#
# $ $ ..#
##### ### #@## ..#
# #########
#######
Hier findest du eine Sammlung von 50 Sokoban-Levels im xsb-Format als ZIP-Datei.
aus Datei lesen
Levels können direkt aus den Textdateien gelesen werden. Das macht unser Spiel interessant: wir können auf zahlreiche vorgefertigte Levels zugreifen.
Das folgende Code-Beispiel liest eine Textdatei und gibt diese Zeile um Zeile aus:
with open('level1.xsb') as f:
for line in f:
print(line)
mehr: «with»
Das with
-Statement wird in Python zur Behandlung von Exceptions verwendet. Wenn wir nämlich auf eine Datei zugreifen, kann diverses schief gehen: Z.B. wenn die Datei gar nicht existiert, oder das System keine Rechte hat, diese zu lesen.
Wir können auch ohne with
von einer Datei lesen. Dann müssen wir uns aber selber um eventuelle Exceptions kümmern (try
-Block) und sicherstellen, dass die Datei nach dem Zugriff wieder geschlossen wird (close
im finally
-Block):
file = open('level1.xsb', 'w')
try:
for line in f:
print(line)
finally:
file.close()
Aufgabe: Levels lesen
Versuche die Level einzulesen. Gehe dazu die Textdatei Zeile um Zeile durch. Die Zeilen wiederum gehst du Zeichen um Zeichen durch.
- Gib für jedes Zeichen des Levels das zugehörige Element aus (mit
print
) - Gib auch die Position auf dem Spielbrett aus, also Koordinaten jedes Elementes
Grafiken
Es können die folgenden Grafiken verwendet werden:
Die Bilder stammen von kenney.nl. In seinem Sokoban-Paket findet ihr weitere Bilder womit ihr die oben dargestellte Auswahl anpassen könnt:
Andere mögliche Grafikpakete die eingesetzt werden können.
Aufgabe: Grafiken
Erzeuge eine für dich passenden Bilder-Auswahl:
- Schau dir die Bilder in den Links an, ev. suchst du weitere Grafik-Pakete
- speichere für jedes Element des Spiels ein passendes Bild auf deinem Computer ab
Die Bilder sollten natürlich zusammenpassen – vor allem auch in ihren Dimensionen. Sonst wird das Darstellen dann komplizierter!
Pygame
Wir verwenden Pygame, um das Spiel darzustellen und den Spieler zu steuern.
Du kannst Pygame in Thonny als Paket importieren.
Darstellung
Das folgende Beispiel initialisiert Pygame, setzt die Grösse des Fensters, lädt eine Grafik als Spielfigur und zeichnet diese dann in einer Endlosschleife (game-loop) immer wieder an der Position (100,100).
import sys, pygame
pygame.init()
size = width, height = 320, 240
screen = pygame.display.set_mode(size)
player = pygame.image.load("player.png")
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(player, (100,100))
pygame.display.flip()
Aufgabe: Level zeichnen
Nimm das Programm der Aufgabe «Level lesen» und versuche den eingelesenen Level mit den richtigen Grafiken anzuzeigen
Steuerung
Im game-loop werden auch immer wieder Ereignisse abgefragt – so kann das Spiel gesteuert werden. Wir bauen dazu ein if
ein, um das keydown
-Event zu überprüfen. Dieses wird beim Runterdrücken einer Taste erzeugt. Wir müssen nur noch überprüfen, um welche Taste es sich handelt:
...
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
player.tryMovePlayer(0,-1)
elif event.key == pygame.K_DOWN:
player.tryMovePlayer(0,1)
...
Aufgabe: Steuerung
Baue die Steuerung ein und bewege damit deinen Spieler auf dem Spielfeld – noch ohne Einschränkungen.
Logik
Nun muss noch sichergestellt werden, dass nur gültige Züge gemacht werden können, dass sich die Kisten entsprechend verschieben und dass das Spiel merkt, wann der Level gelöst ist.
Aufgabe: Logik
Versuche die Spiellogik einzubauen:
- Implementiere dazu die Methoden
canMove()
undmove()
der KlassenPlayer
undCrate
. - Zähle wie viele Kisten noch verschoben werden müssen (
todo
)
Erweiterungen
Einige Ideen für Erweiterungen von Sokoban inkl. Abschätzung des Aufwands resp. der Schwierigkeit (1 bis 4 ⭐):
- Score
- zählen wie viele Schritte der Spieler bis zur Lösung des Levels braucht
- ⭐
- Stats-Overlay
- Spiel-Info als Text oder als Status-Bar anzeigen (z.B. Level-Name, Anzahl gemachte Schritte, Anzahl Boxen die noch platziert werden müssen, …)
- ⭐⭐
- Co-Op
- Ein kooperativer Modus, wo zwei Spieler einander helfen. Man könnte sich die Kisten übergeben und müsste dann weniger grosse Distanzen zurücklegen.
- ⭐⭐
- Richtung
- Den Spieler nicht nur mit einem Bild darstellen, sondern mit 4 Bildern – eines für jede Richtung.
- ⭐⭐⭐
- Auto-Level
- bei Level-Ende automatisch den nächsten Level laden
- ⭐⭐⭐
- Undo
- Eine Undo-Funktion, so dass man die letzten Schritte rückgängig machen kann
- ⭐⭐⭐⭐