ubuntuusers.de

Python: TicTacToe Spiel

Status: Ungelöst | Ubuntu-Version: Nicht spezifiziert
Antworten |

secretwz

Anmeldungsdatum:
10. November 2007

Beiträge: 306

http://paste.ubuntu.com/212025/

Das ist mein Code... Er ist etwas lang, ich weiß aber nicht wie man das zusammenfassen kann. Mein Problem allerdings ist eher, dass das Programm noch nciht so funktioniert... Es fängt zwar super an, es erscheint aber schon bei einer bzw. zwei Runde.

1
2
3
4
5
6
7
8
Willkommen zu TitatoBs, einem Konsolen TicTacToe Spiel!
Du spielst das Kreuz(X)!
Bitte waehle ein Feld: C3
Du hast gewonnen!
Herzlichen Glueckwunsch!
_ _ _
_ _ _
_ _ X

Dabei habe ich doch überall in den Bedingungen ein "and"? Kann mir da bitte jemand helfen? Danke!

rocco_storm Team-Icon

Avatar von rocco_storm

Anmeldungsdatum:
3. November 2005

Beiträge: 1811

Wohnort: Ruhrpott

Hi,

ich erspare mir mal das Kommentieren des Codes und beschränke mich auf das wesentliche: Klammern!

Denk an den alten Satz aus der Schule: Punktrechnung vor Strichrechnung. Dieses Prinzip gilt auch an anderen Stellen...

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

keks() ist doch nicht dein Ernst, oder?!

secretwz

(Themenstarter)

Anmeldungsdatum:
10. November 2007

Beiträge: 306

Tut mir leider, aber das versteh ich jetzt nicht... Ich verwende doch garnicht sollche Operatoren?

Edit:

Lunar schrieb:

keks() ist doch nicht dein Ernst, oder?!

nein ist nicht mein Ernst 😉 Hatte bloß was ausprobiert..

rocco_storm Team-Icon

Avatar von rocco_storm

Anmeldungsdatum:
3. November 2005

Beiträge: 1811

Wohnort: Ruhrpott

secretwz schrieb:

Tut mir leider, aber das versteh ich jetzt nicht... Ich verwende doch garnicht sollche Operatoren?

Also

1
A1.field and A2.field == "x"

ist nicht das gleiche wie

1
A1.field == "x" and A2.field == "x"

Lunar

Anmeldungsdatum:
17. März 2006

Beiträge: 5792

Ich meinte nicht den Namen, sondern die if-elif-else-Kaskade in dieser Funktion ...

secretwz

(Themenstarter)

Anmeldungsdatum:
10. November 2007

Beiträge: 306

Lunar schrieb:

Ich meinte nicht den Namen, sondern die if-elif-else-Kaskade in dieser Funktion ...

achso xD Naja ich hatte das ja erst zusammengefasst, aber das ging nicht, und was anderes ist mir nicht eingefallen..

rocco_storm schrieb:

Also

1
A1.field and A2.field == "x"

ist nicht das gleiche wie

1
A1.field == "x" and A2.field == "x"

Achso! Stimmt hatte ich schonmal gelesen, aber vergessen.. Danke für den Hinweis!

rocco_storm Team-Icon

Avatar von rocco_storm

Anmeldungsdatum:
3. November 2005

Beiträge: 1811

Wohnort: Ruhrpott

Trotzdem solltest du dir Lunars letzten Beitrag mal zu Herzen nehmen...

secretwz

(Themenstarter)

Anmeldungsdatum:
10. November 2007

Beiträge: 306

Ja ich weiß... meine Form ist schlecht, aber ich weiß nicht wie es immer richtig ist.. Vielleicht sollte ich kleinere Dinge machen? Aber wie soll ich es dann lernen, denn nur theoretisches Zeug davor lernt man ja auch nciht wo man was wie anwendet..

gkuhl

Avatar von gkuhl

Anmeldungsdatum:
1. Dezember 2007

Beiträge: 99

Wohnort: Hong Kong

Mach ruhig damit weiter. Zunächst macht es vielleicht Sinn, dass Spielfeld in einer verschachtelten Liste (= Matrix) zu speichern:

1
spielfeld = [[ttt() for i in xrange(3)] for j in xrange(3)]

Damit kannst du dann eine verbesserte keks()-Funktion schreiben. Ehrlich gesagt weiß ich nicht genau, was die Funktion machen soll.

Grüße
Gerrit

PS: Ich empfehle dir ein Python Tutorial durchzuarbeiten.

secretwz

(Themenstarter)

Anmeldungsdatum:
10. November 2007

Beiträge: 306

Die Funktion kontrolliert ob irgendeine Reihe (ob vertikal, waagerecht oder senkrecht) komplett mit "X" (Kreuz) oder "O" (Kreis) gefühlt sind. Wenn ja dann wird die Funktion "False". Dadurch bricht die Spielschleife ab und das Spiel ist beendet.. Nur ich kann mir keine Möglichkeit vorstellen wie man dies abkürzen kann? Vielleicht kann mir da ja auch noch jemand helfen! Wäre natürlich super!

@gkuhl Danke für deine Antwort =)

gkuhl schrieb:

Mach ruhig damit weiter. Zunächst macht es vielleicht Sinn, dass Spielfeld in einer verschachtelten Liste (= Matrix) zu speichern:

1
spielfeld = [[ttt() for i in xrange(3)] for j in xrange(3)]

Ich versteh nicht ganz was damit erreicht wird. Gut, es wird ein Spielfeld erschaffen 3x3, jedoch weiß ich nicht was man damit machen soll? Die einzelnen Felder brauchen ja trotzdem einen extra Namen, oder?! Wäre nett wenn du mir das erklären könntest!

Jerry

Avatar von Jerry

Anmeldungsdatum:
20. April 2006

Beiträge: 595

Wohnort: Gelsenkirchen Buer

secretwz schrieb:

Ich versteh nicht ganz was damit erreicht wird. Gut, es wird ein Spielfeld erschaffen 3x3, jedoch weiß ich nicht was man damit machen soll? Die einzelnen Felder brauchen ja trotzdem einen extra Namen, oder?! Wäre nett wenn du mir das erklären könntest!

Nein, brauchen sie nicht. Du kannst auf jedes Feld über den Index der Matrix zugreifen:

spielfeld[0][0] = X
...
spielfeld[2][2] = O

Lysander

Avatar von Lysander

Anmeldungsdatum:
30. Juli 2008

Beiträge: 2669

Wohnort: Hamburg

Und um Jerry zu ergänzen: Genau solche dynamischen Strukturen machen Computer ja erst stark. Stell Dir mal Deine keks() Funktion vor, wenn Dein TicTacToe-Spielfeld 100x100 Felder hätte!

Über Listen u.ä. kannst Du einfach auf einzelne Elemente zugreifen, ohne den Namen des Eintrags zu kennen.

Mach's Dir doch erst einmal einfacher: Stell Dir einfach mal vor, Du hast eine einfache Liste und willst rausfinden, ob da drei zusammenhängende X drin sind. Das kannst Du imho ganz einfach mit dem Python-Tutorial lösen.

Wenn Du das geschafft hast, dann versuch's eben im 2-dimensionalen ...

secretwz

(Themenstarter)

Anmeldungsdatum:
10. November 2007

Beiträge: 306

@Jerry Stimmt, da habe ich garnicht dran gedacht. Danke!

@Lysander Guter Hinweis. dankeschön! Das ganze python-tut oder ist das an einer bestimmten Stelle erklärt? Ich habe jetzt allerdings schonmal mich ausprobiert, bin aber glaub ich mehr gescheitert xD Weil bei mir kein Vorteil entstanden ist zu dem vorher.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
from random import choice

class ttt(object):
    def __init__(self, feld):
        self.feld = "_"
    
    def kreis(self):
        self.feld = "O"
        
    def kreuz(self):
        self.feld = "X"
    
    def leer(self):
        self.feld = "_"
        
spielliste = [11, 12, 13, 21, 22, 23, 31, 32, 33]

#=> Spielfeld erstellen
spielfeld = [[ttt(0) for i in xrange(3)] for j in xrange(3)]

#=> Einleitung
print "Willkommen zu TitatoBs, einem Konsolen TicTacToe Spiel!"
print "Du spielst das Kreuz(X)!"

#=> Runde: Spieler
eingabe = raw_input("Bitte waehle ein Feld: ")
liste = list()
for letter in eingabe:
    liste.append(letter)
spielfeld[int(liste[0])-1][int(liste[1])-1].kreuz()
spielliste.remove(int(eingabe))
print spielliste
liste = []

#=> Runde: Gegner
gegnerwahl = choice(spielliste)
for letter in str(gegnerwahl):
    liste.append(letter)
spielfeld[int(liste[0])-1][int(liste[1])-1].kreis()
spielliste.remove(gegnerwahl)

#=> Spielfeld anzeigen
for x in range(3):
    print spielfeld[0][x].feld, spielfeld[1][x].feld, spielfeld[2][x].feld

Die while-Schleife fehlt natürlich noch. Ausserdem weiß ich immernoch nicht, wie man jetzt den Gewinn überprüfen kann. Ich habs probiert, aber da ist es eher noch 100x komplizierter geworden xD

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
for x in range(3):
    if spielfeld[0][x] == "X":
        x +=1
    if x == 3:
        y = True
    x = 0
    if spielfeld[1][x] == "X":
        x +=1
    if x == 3:
        y = True
...
...

Dann habe ich lieber aufgehört...

Ich glaube ich arbeite das Tut nochmal ganz durch, auch wenn man dann schon soviel weiß und überspringen muss.

DasIch

Avatar von DasIch

Anmeldungsdatum:
2. November 2005

Beiträge: 1130

Das ganze ist eigentlich ziemlich einfach, man braucht nur einen halbwegs eleganten Weg das Spielfeld dynamisch zu erzeugen und man muss an Reihen, Spalten und Diagonalen kommen um zu prüfen ob jemand gewonnen hat.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from functools import partial

def compose(f, g): return lambda *a, **kw: f(g(*a, **kw))

def all_equal(iterable):
    iterable = iter(iterable)
    foo = iterable.next()
    for element in iterable:
        if element != foo:
            return False
    return True

class Field(object):
    def __init__(self, size):
        assert size > 0
        self._field = [["_"] * size for _ in xrange(size)]
        self.size = size

    def __getitem__(self, (row, column)):
        return self._field[row][column]

    def __setitem__(self, (row, column), value):
        if self._field[row][column] == "_":
            self._field[row][column] = value
        else:
            raise ValueError("Already used")

    def row(self, index):
        return self._field[index][:]

    def rows(self):
        return (self.row(i) for i in xrange(self.size))

    def column(self, index):
        return [r[index] for r in self._field]

    def columns(self):
        return (self.column(i) for i in xrange(self.size))

    @partial(compose, list)
    def diagonal(self, left_to_right=True):
        for x in xrange(self.size):
            if left_to_right:
                yield self[(x, x)]
            else:
                yield self[(x, self.size - x - 1)]

    def diagonals(self):
        yield self.diagonal(True)
        yield self.diagonal(False)

    def __str__(self):
        return "\n".join("".join(" {0} ".format(f) for f in row)
                         for row in self._field)


def has_anyone_won(field):
    for iterable in (field.rows(), field.columns(), field.diagonals()):
        for list in iterable:
            if all_equal(list) and list[0] != "_":
                return True
    return False
Antworten |