Skip to content

Projekt

Programmieren mit Python

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?

Klassen

Welche Klassen wollen wir definieren? Welche Eigenschaften und Methoden sollen die Objekte haben?

Aufgabe: Design

  1. Erarbeitet einen Vorschlag in Zweier- oder Dreiergruppen und notiert diesen.
  2. Stellt den Vorschlag den anderen vor

Wir werden die Vorschläge gemeinsam diskutieren und uns hoffentlich auf ein Design einigen.

Lösung: Design
UML-Diagramm
Schwarze Pfeile
zeigen die Verwendung der Objekte der Klassen an. So besitzt das Board eine Liste von Crate, ein Objekt vom Typ Character und eine zwei-dimensionale Liste von Tile.
Weisse Pfeile
weisen auf Vererbung hin. So erben Ground, Goal und Wall von der Klasse Tile und Crate und Character erben von Movable.

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 des xsb-Formates
ZeichenElement
#Wand
@Spieler
$Kiste
.Zielfeld
leerer Raum (Boden)
+Spieler auf Zielfeld
*Kiste auf Zielfeld

Der einfachste lösbare Level würde wie folgt aussehen:

txt
#####
#@$.#
#####

Ein etwas spannender Level ist hier abgebildet:

txt
    #####
    #   #
    #$  #
  ###  $##
  #  $ $ #
### # ## #   ######
#   # ## #####  ..#
# $  $          ..#
##### ### #@##  ..#
    #     #########
    #######

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:

python
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 mögliche Exceptions kümmern (try-Block) und sicherstellen, dass die Datei nach dem Zugriff wieder geschlossen wird (close im finally-Block):

python
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:

SpielerKisteZielWandBoden

Die Bilder stammen von kenney.nl. In seinem Sokoban-Paket findet ihr weitere Bilder womit ihr die oben dargestellte Auswahl anpassen könnt:
👉 Kenney

Andere mögliche Grafikpakete die eingesetzt werden können.
👉 OpenGameArt
👉 PlanetCute

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.

👉 https://www.pygame.org

Darstellung

python
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

python
...
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.up()
			elif event.key == pygame.K_DOWN:
				player.down()
...

Aufgabe: Steuerung

Baue die Steuerung ein und bewege damit deinen Spieler auf dem Spielfeld

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.

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 Stat-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
⭐⭐⭐⭐

Gymnasium Kirchenfeld, fts & lem