Ich hatte gerade Lust dazu...
Es gibt 4 Spieler, Rot, Blau, Grün und Gelb. Ich repräsentiere sie durch die Zahlen 0 bis 3. Beginnend bei dem Startfeld von Rot (0) nummeriere ich die Felder von 0 bis 39 durch. Die Startfelder von Blau, Grün und Geld sind somit 10, 20 und 30 (oder Nummer * 10). Nun gibt es noch 16 Zielfelder, die ich von 40 bis 55, wieder beginnend mit dem ersten Zielfeld von Rot nummeriere. Ich repräsentiere das Spiel somit als Liste von 56 Elementen. Eine -1 soll ein leeres Feld bedeuten. Eine 0, 1, 2 oder 3 bedeutet, dass dort ein Spielstein des jeweiligen Spielers steht. Die Startposition kann bis zu 4 Spielsteine aufnehmen. Das präsentiere ich durch eine Zahl zwischen 0 und 4.
Ein Spiel fasst alle Felder, alle Startpositionen und den aktuellen Spieler zusammen. Das Spiel kann einen Zug durchführen und dabei automatisch schlagen. Es weiß, wann wer gewonnen hat:
Code: Alles auswählen
class Game:
NO_ONE = -1
def __init__(self):
self.starts = [4] * 4
self.fields = [NO_ONE] * 56
self.player = 0
def start(self):
if starts[self.player]:
starts[self.player] -= 1
self.set(self.player * 10)
else:
raise RuleError("no pieces left")
def move(self, from_field, steps):
to_field = (from_field + steps) % 40
dest_field = to_field - self.player * 10
if dest_field >= 4:
raise RuleError("overshot")
if dest_field >= 0:
self.set(dest_field * self.player + 40)
else:
self.set(to_field)
def set(self, to_field):
other = self.fields[to_field]
if other == self.player:
raise RuleError("occupied")
if other != NO_ONE:
self.starts[other] += 1
self.fields[to_field] = self.player
def winner(self):
for i in range(4):
if all(self.fields[j + i * 40] for j in range(4)):
return i
return NO_ONE
Jetzt muss ich noch die Regeln implementieren: Bei einer Sechs muss ich, wenn ich noch Figuren auf der Startposition habe und mein Startfeld nicht von einer eigenen Figur belegt ist, eine neue heraussetzen. Andernfalls muss ich das Startfeld frei machen. Andernfalls kann ich eine meiner Figuren bewegen. Dann kann ich noch mal würfeln. Bei jeder anderen Zahl bewege ich einfach nur.
Will man mit Schlagzwang spielen, ist es vielleicht hilfreich, wenn das Spiel dies auch prüfen kann. Dafür ist meine einfache Datenstruktur jedoch nicht optimal. Ich muss nach meinen Figuren auf dem Brett suchen:
Code: Alles auswählen
def can_throw(self, die):
fields = []
for field in range(40):
if self.fields[field] == self.player:
to_field = (field + die) % 40
if to_field < self.player * 10:
other = self.fields[to_field]
if other != NO_ONE and other != self.player:
fields.append(field)
return fields
Ist jetzt die ausgewählte Feld nicht in der Liste der Felder mit Schlagzwang, ist das entweder ein Fehler und der Zug ist nicht möglich, oder aber, wenn laut Wikipedia dann ein andere Spieler die Möglichkeit haben soll, Einspruch zu erheben, muss man das nachträglich prüfen.
Und jetzt implementiere bitte jemand "Igel Ärgern", das finde ich ja viel interessanter
Stefan