Mehrdimensionale Liste in TicTacToe verhält sich strange

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
ford
User
Beiträge: 19
Registriert: Dienstag 2. Januar 2018, 19:07

Hey,

ich möchte ein TicTacToe-Spiel zur Übung (ist echt keine Hausaufgabe, wir haben in der Ausbildung leider kein Python) programmieren.

Jedoch verhält sich die Liste strange.

Also sortiert sich irgendwie anders um oder so.

Ich habe den output als Link am Anfng von den gist reinkopiert. Dann könnt ihr sehen was ich meine. :)

https://gist.github.com/ford42/083eca17 ... 5874f42452


Vielen Dank
LG ford
Benutzeravatar
__blackjack__
User
Beiträge: 14033
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ford: Deine `check_full()` ist das Problem. Unsinnig ist ``card_buffer = self.card[:][:][:]`` weil das die Liste kopiert, und dann nochmal kopiert, und dann noch mal kopiert. Einmal würde ausreichen. Und der Fehler ist dann ``card_buffer[0].sort()``, denn damit sortierst Du eine Liste die auch in `self.card` ist, also keine Kopie. ``liste[:]`` erzeugt eine flache Kopie. Egal wie oft man das macht, falls das die Idee dahinter gewesen sein sollte diese Aktion dreimal zu machen.

Ich finde das mit dem sortieren für das Testen sowieso etwas um die Ecke gedacht. Testen ob keine 0 enthalten ist wäre IMHO eher das was logisch einfacher nachzuvollziehen ist. Also beispielsweise einfach ein ``return all(all(value != 0 for value in row) for row in self.cards)``.

Wo ich gerade `row` schreibe: `line` bedeutet auf deutsch Zeile, und `row` bedeutet auf deutsch Zeile. Ein ``self.card[line][row]`` ist also falsch, denn man hat ja Zeilen und *Spalten* (`column`). `card` ist auch etwas eigenartig. Das ist eine Spielkarte in einem Kartenspiel. In einem Brettspiel („boardgame“) hiesse das `board`, und wenn es so etwas wie eine Weltkarte ist `map`. Bei letzterem muss man aufpassen, dass das auch eine eingebaute Funktion ist, die man nicht verdecken sollte.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
ford
User
Beiträge: 19
Registriert: Dienstag 2. Januar 2018, 19:07

Danke :)

Argh, stimmt. Da nimmt Python ja einfach nen Pointer oder?

Kannst du mir bitte dein return snippet erklären?

Ok, die Namen passe ich ebenfalls an. Mein Englisch ist nicht so gut und google translator spuckt bei Spielkarte playing card aus. Wobei nachdem was du geschrieben hast er wahrscheinlich mit Spielkarte die Karte beim Poker meint...

Ich werde das jetzt mal verbessern und dann auf github laden. Dann könnt ihr es euch ja wenn Ihr wollt nochmal anschauen und ggf. verbesserrn :)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Doppelte Indirektion ist ein bisschen verwirrend. Warum kopierst du Code & output nicht einfach hier rein, dann kann man es direkt lesen?

Reihe und Zeile sind schon mal massiv verwirrend, da das gleiche. Spalte und Zeile waeren deutlich klarer.

Dein Problem ist, das du dein Spielfeld umsortierst. Warum ist mir nicht klar, und du versuchst ja auch eine Kopie zu machen, aber das geht in die Hose.

Ein paar Anmerkungen zum Code:

- die Aufteilung in zwei Module ist unnoetig und macht allen beteiligten das Leben nur schwerer.
- du trennst nicht zwischen Spiellogik und Ein/Ausgabe. Das waere deutlich besser, denn dann kannst du statt komischem reset-Code einfach immer eine neue Spielinstanz machen, wenn ein neues spiel beginnen soll.
- dadurch wird dann auch dein Code klarer.
- der Code zum setzen des Tokens ist viel zu kompliziert. Du kennst doch die Spielernummer, warum fragst du erst ab, ob es 1 oder 2 ist, um danach muehselig den gleichen Code auszufuehren, der dann 1 oder 2 enthaelt? Da kannst du gleich die Spielernummer geben.
- deine Eingabepruefung ist unvollstaendig, du erlaubst Eingaben von zB 33/34, und dann kracht das Programm.

Alles in allem aber wirklich kein schlechter Versuch! Das "nur" Kritik kommt liegt daran, dass ein solches Problem fuer die alten Hasen hier natuerlich keines ist, und man da jetzt nix macht, was irgendwie besonders beeindruckend waere.
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

__blackjack__ hat geschrieben: Donnerstag 1. November 2018, 10:49 Ich finde das mit dem sortieren für das Testen sowieso etwas um die Ecke gedacht. Testen ob keine 0 enthalten ist wäre IMHO eher das was logisch einfacher nachzuvollziehen ist. Also beispielsweise einfach ein ``return all(all(value != 0 for value in row) for row in self.cards)``.
Das Verschachteln von zwei all()-Aufrufen ist nicht mal nötig. Man kann das auch so schreiben:

Code: Alles auswählen

all(value != 0 for row in self.cards for value in row)
Benutzeravatar
__blackjack__
User
Beiträge: 14033
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@snafu: Ich komme bei so etwas immer mit der Reihenfolge durcheinander, weil ich das so selten benutze. Und ich benutze das so selten, weil ich da immer mit der Reihenfolge durcheinander komme. :-)
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

@ford: eine Funktion/Methode sollte nur eine Aufgabe haben, Deine Methoden sind zu tief verschachtelt. `player_change` wechselt nicht nur den Spieler, sondern prüft auch ob das Feld voll ist und `full` prüft nicht nur, ob das Feld voll ist, sondern beendet auch das Spiel und `quit_game` beendet nicht nur das Spiel, sondern fängt auch ein neues an.
Niemand der player_change aufruft, erwartet, dass bei der Rückkehr das Spielfeld wieder leer ist.
Programmiere flacher:
`turns` ist für genau ein Spiel. Das startet mit einem leeren Spielfeld, Für jeden Zug wird dann geprüft, ob das Feld leer ist, wenn ja, wird das Feld gesetzt und danach geprüft, ob es einen gewinner gibt, wenn ja, endet turns, sonst wenn das Feld voll ist, endet turns, sonst wird der Spieler gewechselt.
Antworten