Seite 1 von 1

Newbie hat Tic Tac Toe programmiert

Verfasst: Dienstag 27. Mai 2008, 02:37
von bremer
Hi.
Ich habe das komplette Pythontutorial gelesen, damit ein bisschen rumgespielt und dann Tic Tac Toe programmiert.

Dabei habe ich mir keine großen Gedanken über OOP (womit ich eh noch nicht umgehen kann) oder Qualität des Codes gemacht. Ich habe keinerlei Beispiele dazu gelesen, damit es ein komplettes Eigengewächs wird und ich meine Fehler klar erkennen kann.

Das ist die erste funktionierende Version und ich habe 2 Bitten an euch.


1. Könnt ihr analysieren, was alles hässlicher Code ist?

2. Was könnte man durch OOP daran auf den ersten Blick verbessern?

Code: Alles auswählen

def field(one,two,three,four,five,six,seven,eight,nine):
    print (one+"|"+two+"|"+three)
    print "-+-+-"
    print (four+"|"+five+"|"+six)
    print "-+-+-"
    print (seven+"|"+eight+"|"+nine)

code = {"X":1,"O":4," ":0}
field("1","2","3","4","5","6","7","8","9")
decision = 10
one,two,three,four,five,six,seven,eight,nine = " "," "," "," "," "," "," "," "," "
player = "x"
while decision != "q":
    decision = raw_input("\nPlease enter a number from \'1\' to \'9\'. You can cancel the programm with \'q\'.\n")
    if decision == "1":
        if player == "x" and one != "X" and one != "O":
            one = "X"
            player = "o"
        elif player == "o" and one != "X" and one != "O":
            one = "O"
            player = "x"
    elif decision == "2":
        if player == "x" and two != "X" and two != "O":
            two = "X"
            player = "o"
        elif player == "o" and two != "X" and two != "O":
            two = "O"
            player = "x"
    elif decision == "3":
        if player == "x" and three != "X" and three != "O":
            three = "X"
            player = "o"
        elif player == "o" and three != "X" and three != "O":
            three = "O"
            player = "x"
    elif decision == "4":
        if player == "x" and four != "X" and four != "O":
            four = "X"
            player = "o"
        elif player == "o" and four != "X" and four != "O":
            four = "O"
            player = "x"
    elif decision == "5":
        if player == "x" and five != "X" and five != "O":
            five = "X"
            player = "o"
        elif player == "o" and five != "X" and five != "O":
            five = "O"
            player = "x"
    elif decision == "6":
        if player == "x" and six != "X" and six != "O":
            six = "X"
            player = "o"
        elif player == "o" and six != "X" and six != "O":
            six = "O"
            player = "x"
    elif decision == "7":
        if player == "x" and seven != "X" and seven != "O":
            seven = "X"
            player = "o"
        elif player == "o" and seven != "X" and seven != "O":
            seven = "O"
            player = "x"
    elif decision == "8":
        if player == "x" and eight != "X" and eight != "O":
            eight = "X"
            player = "o"
        elif player == "o" and eight != "X" and eight != "O":
            eight = "O"
            player = "x"
    elif decision == "9":
        if player == "x" and nine != "X" and nine != "O":
            nine = "X"
            player = "o"
        elif player == "o" and nine != "X" and nine != "O":
            nine = "O"
            player = "x"
    if decision != "q":
        print ""
        field(one,two,three,four,five,six,seven,eight,nine)
    checkrow1 = code[one]+code[two]+code[three]
    checkrow2 = code[four]+code[five]+code[six]
    checkrow3 = code[seven]+code[eight]+code[nine]
    checkcolumn1 = code[one]+code[four]+code[seven]
    checkcolumn2 = code[two]+code[five]+code[eight]
    checkcolumn3 = code[three]+code[six]+code[nine]
    checkdiag1 = code[one]+code[five]+code[nine]
    checkdiag2 = code[three]+code[five]+code[seven]
    if checkrow1 == 3 or checkrow2 == 3 or checkrow3 == 3 or checkcolumn1 == 3 or checkcolumn2 == 3 or checkcolumn3 == 3 or checkdiag1 == 3 or checkdiag2 == 3:
        decision = "q"
        print "\nPlayer \"X\" has won!"
    if checkrow1 == 12 or checkrow2 == 12 or checkrow3 == 12 or checkcolumn1 == 12 or checkcolumn2 == 12 or checkcolumn3 == 12 or checkdiag1 == 12 or checkdiag2 == 12:
        decision = "q"
        print "\nPlayer \"O\" has won!"
edit: So, der Code wurde etwas aufgehübscht. Die Einrückungen habe ich in Ordnung gebracht.

Verfasst: Dienstag 27. Mai 2008, 07:27
von Hyperion
Naja, also erstens halte Dich mehr an PEP8, vor allem die unterschiedlichen Tab-Einrückungen sehen nicht gut aus!

Dann versuche mal, das ganze auf ein 4x4 Feld umzuschreiben - dann siehst Du schon mal an der Logik, dass das Konzept unschön ist. Selbst wenn das noch geht - ein 5x5 oder gar 9x9 Feld wird so langsam unmöglich mit Deinem Konzept ;-)

Ansonsten solltest Du Dir evtl. doch mal Beispiele angucken und daraus lernen - vom Tutorial merkt man nicht wirklich viel ehrlich gesagt (z.B. bei one, two, three, ... - wieso nicht Listen o.ä.?)

Verfasst: Dienstag 27. Mai 2008, 08:27
von veers
Hi bremer,

Ich habe auch mal ein TicTacToe gebastelt. Das kannst du hier finden:
http://paste.pocoo.org/show/54509/

Ist auch zumindest Objekt basiert. Der konkrete Vorteil da: Es ist möglich verschiedene Spieler zu implementieren (Mensch, KI, Netzwerk) aber es sollte es auch einfach machen ein anderes UI zu entwickeln ;)


Was an deinem Code hässlich ist:
- Die Formatierung - siehe PEP8
- Du solltest Listen an Stelle von nummerierten Variablen verwenden.
- Das kannst du eigentlich als Faustregel ansehen: Wenn du Variablen nummerierst solltest du eine Liste nehmen ;)

Gruss,
Jonas

Verfasst: Dienstag 27. Mai 2008, 10:16
von bremer
Das mit den Listen gucke ich mir mal an und den Code werde ich PEP8-konformer gestalten.

Verbesserungen füge ich dann nach und nach hinzu.

Verfasst: Dienstag 27. Mai 2008, 11:05
von Leonidas
veers hat geschrieben:Was an deinem Code hässlich ist:
- Die Formatierung - siehe PEP8
- Du solltest Listen an Stelle von nummerierten Variablen verwenden.
- Das kannst du eigentlich als Faustregel ansehen: Wenn du Variablen nummerierst solltest du eine Liste nehmen ;)
- Wenn du lange if-elif Kaskaden verwendest, dann machst du was falsch. Dann ist nämlich deine Programmstruktur für die Tonne.

Verfasst: Dienstag 27. Mai 2008, 12:06
von Y0Gi
Zur Darstellung der Feldinhalte könnte man die boolschen Werte (`True`/"X", `False`/"O") sowie `None` (kein Wert/"leeres Feld") verwenden. Nicht unbedingt kürzer, aber für mich irgendwie von den Typen her passender.

P.S.: Wobei, kürzer werden dann die Vergleiche (`if feldwert`, `if not feldwert`, `if feldwert is None`).

Verfasst: Dienstag 27. Mai 2008, 23:11
von bremer
Wenn ich Listen verwende, bekomme ich einen Syntaxfehler.

Code: Alles auswählen

content = [" "," "," "," "," "," "," "," "," "]
def field(content[0],content[1],content[2],content[3],content[4],content[5],content[6],content[7],content[8]):
    print (content[0]+"|"+content[1]+"|"+content[2])
    print "-+-+-"
    print (content[3]+"|"+content[4]+"|"+content[5])
    print "-+-+-"
    print (content[6]+"|"+content[7]+"|"+content[8])
def field(content[0],content[1],content[2],content[3],content[4],content[5],content[6],content[7],content[8]):
^
SyntaxError: invalid syntax

Verfasst: Dienstag 27. Mai 2008, 23:17
von audax
http://docs.python.org/tut/node5.html#S ... 0000000000

http://docs.python.org/tut/node6.html#S ... 0000000000

Arbeite bitter erst einmal gewissenhaft das verlinkte Tutorial durch. Das Komplette bitte.

Das wird alles dort besprochen...

Verfasst: Mittwoch 28. Mai 2008, 07:33
von veers
Y0Gi hat geschrieben:Zur Darstellung der Feldinhalte könnte man den boolschen (`True`/"X", `False`/"O") sowie `None` (kein Wert/"leeres Feld") verwenden. Nicht unbedingt kürzer, aber für mich irgendwie von den Typen her passender.

P.S.: Wobei, kürzer werden dann die Vergleiche (`if feldwert`, `if not feldwert`, `if feldwert is None`).
Habe das ganze jetzt neu geschrieben und Integer verwendet:
- Ich kann und will damit rechnen
- Ich kann die als Index in einer List verwenden
:wink:

Verfasst: Mittwoch 28. Mai 2008, 07:54
von audax
veers hat geschrieben: - Ich kann und will damit rechnen
- Ich kann die als Index in einer List verwenden
:wink:

Code: Alles auswählen

In [1]: True == 1
Out[1]: True

In [2]: True + True
Out[2]: 2
Letzeren Punkt kann ich allerdings nicht ganz nachvollziehen...
An und Aus als Index? Oo

Und ich hab noch nen generellen Tip:
Bau dir lieber einen allgemeinen Algorithmus umd zu finden, wer gewonnen hat. Da lernst du mehr bei und du kannst man ein spannenderes 4x4 TicTacToe in Angriff nehmen :]

Verfasst: Mittwoch 28. Mai 2008, 07:57
von mitsuhiko
Bools als Ints sind sehr praktisch. zB um zwischen zwei Implementierungen zu wechseln:

Code: Alles auswählen

(unicode, str)[not use_unicode]

Verfasst: Mittwoch 28. Mai 2008, 08:23
von audax
hm...das stimmt natürlich wieder :]

Verfasst: Mittwoch 28. Mai 2008, 08:44
von Leonidas
mitsuhiko hat geschrieben:

Code: Alles auswählen

(unicode, str)[not use_unicode]
Das hat was von Rubys und Perls nachgestelltem ``if``-Statements ;)