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()
[[0]*3]*3 versus [[0,0,0],[0,0,0],[0,0,0]]
`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:
*-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.
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?
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?
- 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 ...
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 ...