Methoden (Funktionen in Klassen)
Tic Tac Toe
Diese Aufgabe entspricht dieser Aufgabe im Kapitel Funktionen.
- Schreiben Sie eine Klasse
TicTacToe
mit einem Konstruktor, der ein leeres 3×3-Feld anlegt:
class TicTacToe: def __init__(self): # Konstruktor, wird beim Anlegen einer neuen Instanz aufgerufen. # Ein 3x3 Feld initialisieren self.feld = [] # TODO t = TicTacToe() # Neue Instanz print(t) # Noch nicht spannend...
- Fügen Sie eine Methode
__str__(self)
hinzu, die einen String zurückgibt, die das aktuelle Spielfeld darstellt. Z.B. wennfeld=[[0,1,1], [2,1,2], [0,2,2]]
dann soll die Ausgabe wie folgt sein:
| X | ---+---+--- O | O | X ---+---+--- O | X | X
Damit kann das Feld einfach mit
print(t)
ausgegeben werden. Die Methode __str__
wird automatisch aufgerufen, falls diese existiert. Genau genommen, wird sonst die __str__
Methode der Grund-Klasse object
aufgerufen, von der alle Klassen erben.
Bauen Sie die Klasse mit folgenden Methoden aus:
isEmpty(self, x,y)
: LiefertTrue
, wenn das entsprechende Feld existiert und noch leer ist.place(self, x,y,player)
: Platziert ein 'O' oder 'X', je nach Wert vonplayer
(1 oder 2).winner(self, )
: Liefert 0, wenn niemand gewonnen hat, oder 1 oder 2, wenn der entsprechende Spieler gewonnen hat.full(self, )
: LiefertTrue
, wenn das Feld voll ist.reset(self, )
: löscht das Spielfeld
Sudoku
Schreiben Sie eine Klasse Sudoku
mit einem Konstruktur init(self,sudoku)
, der als Eingabe einen String erwartet, wie in der
Originalaufgabe beschrieben.
Die Klasse soll zwei Attribute haben: eine 9×9-Liste self.feld
, der aktuelle Zusand des Felds darstellt und eine 9×9-Liste self.given
, mit Einträgen True
oder False
, je nachdem, ob der entsprechende Eintrag bereits im Rätsel vorgegeben ist.
Fügen Sie der Klasse eine Methode __str__(self)
hinzu, die einen String wie in der Originalaufgabe zurückgibt. Damit sollte folgendes Programm (nach der Klassendefinition) dann lauffähig sein:
s = Sudoku("200080300\n060070084\n030500209\n000105408\n\n000000000\n402706000\n301007040\n720040060\n004010003") print(s)
Bauen Sie die Klasse mit folgenden Methoden aus:
allowed(self, x,y, w)
liefertTrue
, wenn der Wertw
an der Stellex
,y
eingetragen werden kann, d.h. in der selben Spalte, Kolonne und Unterquadrat derw
noch nicht vorkommt.
Solver
Eine mögliche Strategie zum Lösen eines Sudokus geht wie folgt:
- Man setzt die Position $p$ auf das erste noch freie Feld.
- Wiederholen
- Bestimme die nächste mögliche Zahl im Feld $p$, die grösser ist, als die Zahl, die schon da steht (die kleinste, wenn das Feld leer war).
- Wenn es diese gibt, schreibe die Zahl ins Feld und rücke $p$ auf das nächste freie Feld vor. Sind alle Felder voll ist das Sudoku gelöst. Ende.
- Sonst lösche das Feld und gehe zurück auf das letzte Feld, das nicht vorgegeben ist. Wenn nicht weiter zurückgegangen werden kann, ist das Sudoku unlösbar. Ende
Diese Strategie ist ausreichend, um einfache Sudokus zu lösen. Die Strategie kann noch viel effizienter gemacht werden, wenn die Reihenfolge der Feld dynamisch angepasst wird, d.h. es werden erst jene Felder abgearbeitet, die am wenigsten mögliche Zahlen haben. Entweder merkt man sich die Reihenfolge oder man programmiert das rekursiv (und merkt sich die Reihenfolge so in den lokalen Variablen der Funktionsaufrufen).