Newbie hat Tic Tac Toe programmiert

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Newbie hat Tic Tac Toe programmiert

Beitragvon bremer » Dienstag 27. Mai 2008, 02:37

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.
Zuletzt geändert von bremer am Dienstag 27. Mai 2008, 10:10, insgesamt 2-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7471
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Beitragvon Hyperion » Dienstag 27. Mai 2008, 07:27

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.ä.?)
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Beitragvon veers » Dienstag 27. Mai 2008, 08:27

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
My Website - 29a.ch
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Beitragvon bremer » Dienstag 27. Mai 2008, 10:16

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.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 27. Mai 2008, 11:05

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Beitragvon Y0Gi » Dienstag 27. Mai 2008, 12:06

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`).
Zuletzt geändert von Y0Gi am Donnerstag 29. Mai 2008, 13:45, insgesamt 1-mal geändert.
bremer
User
Beiträge: 109
Registriert: Sonntag 25. Mai 2008, 00:13

Beitragvon bremer » Dienstag 27. Mai 2008, 23:11

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
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Dienstag 27. Mai 2008, 23:17

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...
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Beitragvon veers » Mittwoch 28. Mai 2008, 07:33

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:
My Website - 29a.ch

"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Mittwoch 28. Mai 2008, 07:54

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 :]
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Mittwoch 28. Mai 2008, 07:57

Bools als Ints sind sehr praktisch. zB um zwischen zwei Implementierungen zu wechseln:

Code: Alles auswählen

(unicode, str)[not use_unicode]
TUFKAB – the user formerly known as blackbird
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Mittwoch 28. Mai 2008, 08:23

hm...das stimmt natürlich wieder :]
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Mittwoch 28. Mai 2008, 08:44

mitsuhiko hat geschrieben:

Code: Alles auswählen

(unicode, str)[not use_unicode]

Das hat was von Rubys und Perls nachgestelltem ``if``-Statements ;)
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder