[[0]*3]*3 versus [[0,0,0],[0,0,0],[0,0,0]]

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
MissMapeL
User
Beiträge: 22
Registriert: Mittwoch 30. Oktober 2019, 10:26

Hallo,
als Python-Neuling habe ich mir mal ein TicTacToe-Spiel von https://projectgurukul.org/python-tic-tac-toe-game/ mal angeschaut.
Warum kann ich aber in Zeile 21 grd bzw. curr nicht durch grd = [[0]*3]*3 bzw. curr = [[0]*3]*3 ersetzen?
Laut Variablen-Ansicht müsste dies doch das Gleiche bewirken???


import sys
import os.path
from tkinter import *

top_width = 580
top_hight = 400
top_title = 'mein Fenster'
x_btn = 8
y_btn = 10

def vp_start_gui():
'''Starting point when module is the main routine.'''
root = Tk()
root.title("ProjectGurukul Tic Tac Toe")

global usr, gamestatus, grd, curr

usr="O"
gamestatus=True
grd=[[0,0,0],
[0,0,0],
[0,0,0]]

curr=[[0,0,0],
[0,0,0],
[0,0,0]]

for i in range(3):
for j in range(3):
curr[j]=Button(font=('arial',30,'bold'),width=4,command=lambda r=i, c=j:click(r,c))
curr[j].grid(row=i,column=j)
root.mainloop()

def click(r,c):
global usr
global gamestatus
if(usr=='X' and grd[r][c]==0 and gamestatus==True):
grd[r][c]='X'
usr='O'
curr[r][c].configure(text='X',bg="white")

if(usr=='O' and grd[r][c]==0 and gamestatus==True):
grd[r][c]='O'
usr='X'
curr[r][c].configure(text='O',bg="gray")

checkWin()

def checkWin():
global gamestatus
for i in range(3):
if grd[0]==grd[1]==grd[2]!=0:
for j in range(3):
curr[j].config(bg="snow4",fg="white")
gamestatus=False
for i in range(3):
if grd[0]==grd[1]==grd[2]!=0:
for j in range(3):
curr[j].config(bg="snow4",fg="white")
gamestatus=False
if grd[0][2]==grd[1][1]==grd[2][0]!=0:
curr[0][2].config(bg="snow4",fg="white")
curr[1][1].config(bg="snow4",fg="white")
curr[2][0].config(bg="snow4",fg="white")
gamestatus=False
if grd[0][0]==grd[1][1]==grd[2][2]!=0:
for j in range(3):
curr[j][j].config(bg="snow4",fg="white")
gamestatus=False

if __name__ == '__main__':
vp_start_gui()
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

`sys` und `os.path` werden importiert aber nicht benutzt. Statt os.path würde man auch nur os importieren, weil damit os.path automatisch mit importiert wird; würde man aber trotzdem nicht importieren, weil man statt os.path etwas aus pathlib benutzen würde.

*-Importe macht man nicht, weil man keinen Einfluß darauf hat, welche Namen tatsächlich importiert werden und es unmöglich wird nachzuvollziehen, woher welcher Name kommt.
top_width, top_height, x_btn und y_btn werden nicht benutzt und können weg. Würden sie benutzt, wären das wohl Konstanten und würden komplett gross geschrieben werden: TOP_WIDTH.

Vergiß gleich wieder, dass es `global` überhaupt gibt. Das benutzt man nicht. Statt dessen bekommt eine Funktion alles was sie braucht über ihre Argumente.
Jedes einigermaßen komplexe GUI-Programm (und so eines hast Du) braucht Klassendefinitionen.

`[[0]*3]*3` nimmt die eine Liste mit 3 Nullen und packt sie drei Mal in eine weitere Liste. Das ist aber nur EINE Listen-Instanz.

Benutze keine Abkürzungen. Vokale sind nicht teurer also Konsonanten: grid, user, etc. Was curr bedeuteten soll, wird mir nicht klar, vielleicht so etwas wie buttons?
`gamestatus` wäre besser ein `game_running` dann wüßte jeder gleich, was True und False bedeutet.

Listen belegt man nicht mit Dummywerten, um sie dann mit den richtigen zu füllen, sondern erzeugt die Listen gleich so, wie sie gebraucht werden.
lambda sollte man nicht verwenden, wenn man auch functools.partial benutzen könnte, das hat nämlich mit Namespaces deutlich weniger Probleme.

Warum wird `grid` überhaupt gebraucht. Die ist doch schon als Text auf den Buttons sichtbar?
In `click` steht im if-Block und im else-Block quasi das selbe, das kann also zu einem werden.

Notfalls könnte man alles über den Inhalt der Button-Knöpfe erledigen:

Code: Alles auswählen

import tkinter as tk
from functools import partial

def vp_start_gui():
    '''Starting point when module is the main routine.'''
    root = tk.Tk()
    root.title("ProjectGurukul Tic Tac Toe")
    grid = []
    for i in range(3):
        row = []
        for j in range(3):
            button = tk.Button(font=('arial',30,'bold'),width=4, command=partial(click, grid, i, j))
            button.grid(row=i,column=j)
            row.append(button)
        grid.append(row)
    root.mainloop()

def click(grid, i, j):
    round = sum(b['text'] != "" for row in grid for b in row)
    player = 'X' if round % 2 == 0 else 'O'
    button = grid[i][j]
    if button['text'] == "":
        button['text'] = player
    check_win(grid)

def check_win(grid):
    for j in range(3):
        if grid[0][j]['text'] == grid[1][j]['text'] == grid[2][j]['text'] != "":
            for i in range(3):
                grid[i][j].config(bg="snow4",fg="white")
    for i in range(3):            
        if grid[i][0]['text'] == grid[i][1]['text'] == grid[i][2]['text'] != "":
            for j in range(3):
                grid[i][j].config(bg="snow4",fg="white")
    if grid[0][2]['text'] == grid[1][1]['text'] == grid[2][0]['text'] != "":
        grid[0][2].config(bg="snow4",fg="white")
        grid[1][1].config(bg="snow4",fg="white")
        grid[2][0].config(bg="snow4",fg="white")
    if grid[0][0]['text'] == grid[1][1]['text'] == grid[2][2]['text'] != "":
        grid[0][0].config(bg="snow4",fg="white")
        grid[1][1].config(bg="snow4",fg="white")
        grid[2][2].config(bg="snow4",fg="white")
            
if __name__ == '__main__':
    vp_start_gui()
Zuletzt geändert von Sirius3 am Dienstag 22. Dezember 2020, 12:15, insgesamt 2-mal geändert.
MissMapeL
User
Beiträge: 22
Registriert: Mittwoch 30. Oktober 2019, 10:26

Danke, das ging ja fix...
Wie gesagt, das Programm ist nicht von mir - mir war vor allem das mit der Liste nicht klar.
Noch eine ganz 'dumme' Frage. Nachdem ich das Programm eingefügt hatte waren wieder die Einrückungen weg.
Ich weiß ich (inzwischen), das ich Code-Tags verwenden soll - aber - das finde ich weder bei Thonny noch bei Python-IDLE.
Wie statte ich ein, in diesen Editoren geschriebenes Programm damit aus?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Das hat nichts mit einem Editor zu tun. Du mußt die Code-Tags hier im Forum benutzen. Unter "Vollständigen Editor & Vorschau" hier im Forum gibt es den </>-Knopf.
MissMapeL
User
Beiträge: 22
Registriert: Mittwoch 30. Oktober 2019, 10:26

- smile - ...
oh, da habe ich wohl was falsch verstanden und - mich jetzt ganz schön lächerlich gemacht....

Hoffe das bleibt unter uns - und den Millionen Python-Programmierern, die irgendwann dieses Forum besuchen ...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es gibt Leute, die nach dutzenden Posts noch nicht mal auf die Idee kommen, dass es da etwas wie code-Tags gaebe. Du bist da also noch lange nicht am nach oben offenen Ende der Peinlichkeitsskala angekommen.
Antworten