j'essai de créer un mastermind avec Tkinter sauf que je me heurte à certains problème tel que ma fonction préférence qui ne fonctionne pas et accessoirement la volonté de donner un effet 3D à mes pions de couleurs si qqun voudrais bien m'aider sur ce qu'il faut faire en tenant en compte ce que j'ai fait je lui serais très reconnaissant
Merci
import tkinter as tk
import random
from tkinter.messagebox import showinfo
def interpolate_color(color1, color2, weight):
r = int(color1[0] * (1 - weight) + color2[0] * weight)
g = int(color1[1] * (1 - weight) + color2[1] * weight)
b = int(color1[2] * (1 - weight) + color2[2] * weight)
return f'#{r:02x}{g:02x}{b:02x}'
def create_oval_with_gradient(canvas, x, y, size, color1, color2):
oval = canvas.create_oval(x, y, x + size, y + size, outline='black', width=0)
for i in range(size):
gradient_color = interpolate_color(color1, color2, i / size)
canvas.create_line(x, y + i, x + size, y + i, fill=gradient_color, width=1)
return oval
root = tk.Tk()
frame = tk.Frame(root)
canvas = tk.Canvas(frame, width=400, height=600, highlightthickness=0, highlightbackground="black", relief=tk.FLAT, bg='#B3C890', bd=0)
def about():
showinfo("À propos", "Bienvenue dans ce Mastermind avec Tkinter.\n\n"
"Ce jeu consiste à trouver un code secret composé de plusieurs couleurs, sachant que "
"chaque couleur ne peut pas apparaître plusieurs fois.\n\n"
"Vous pouvez configurer la taille du code secret "
"et le nombre de tentatives que vous pouvez effectuer, dans le menu Préférences.\n\n"
"pour choisir les couleurs à mettre dans la grille vous avez deux options soit vous référer au tableau soit utiliser les flèches directionnelles.")
about_button = tk.Button(root, text="À propos", command=about)
about_button.pack()
tk.Label(root, text='[F1] À propos - [F2] Préférences - [F5] Nouvelle partie - [ESC] Quitter',
foreground="white", background="green").pack(anchor=tk.N, fill=tk.X)
global noOfGuesses, codeLength, colorSize, colorpadding, row, cpos
global board, response, colorpicks, codedColor, selectColors, tops, bots
noOfGuesses = 12
codeLength = 4
colorSize = 40
colorpadding = 50
row = 0
cpos = 0
selectColors = []
board = []
response = []
colorpicks = [[-1 for _ in range(codeLength)] for _ in range(noOfGuesses)]
class SettingWindow:
def __init__(self, master, callback):
self.master = master
self.callback = callback
self.window = tk.Toplevel(master)
self.window.title("Paramètres")
self.guesses_options = [6, 8, 10, 12]
self.label_guesses = tk.Label(self.window, text="Nombre de tentatives:")
self.label_guesses.pack()
self.guesses_var = tk.StringVar(self.window)
self.guesses_var.set(self.guesses_options[0])
self.guesses_menu = tk.OptionMenu(self.window, self.guesses_var, *self.guesses_options)
self.guesses_menu.pack()
self.length_options = [4, 5, 6]
self.label_length = tk.Label(self.window, text="Longueur du code:")
self.label_length.pack()
self.length_var = tk.StringVar(self.window)
self.length_var.set(self.length_options[0])
self.length_menu = tk.OptionMenu(self.window, self.length_var, *self.length_options)
self.length_menu.pack()
self.apply_button = tk.Button(self.window, text="Appliquer", command=self.apply_settings)
self.apply_button.pack()
def application_settings(self):
no_of_guesses = int(self.guesses_var.get())
code_length = int(self.length_var.get())
self.callback(no_of_guesses, code_length)
self.window.destroy()
def settings_changement(no_of_guesses, code_length):
global noOfGuesses, codeLength, row, cpos, colorpicks, codedColor, selectColors, tops, bots, board, response
noOfGuesses = no_of_guesses
codeLength = code_length
for i in range(noOfGuesses):
for j in range(codeLength):
canvas.delete(board[i][j])
if i < noOfGuesses - 1:
canvas.delete(response[i][j])
board = []
response = []
for i in range(noOfGuesses):
newRow = []
newResponse = []
for j in range(codeLength):
x = colorpadding * j + 5
y = 600 - colorpadding * i - colorSize - 5
create_oval_with_gradient(canvas, x, y, colorSize, '#8888dd', '#000066')
newRow.append(canvas.create_oval(x, y, x + colorSize, y + colorSize, fill='#8888dd', outline='black', width=0))
if i < noOfGuesses - 1:
x = colorpadding / 2 * j + 255
y += colorSize / 8
newResponse.append(canvas.create_oval(x + colorSize / 4, y + colorSize / 4, x + colorSize / 2, y + colorSize / 2, fill='#8888dd', outline='black', width=0))
board.append(newRow)
if i < noOfGuesses - 1:
response.append(newResponse)
initGame()
def open_settings_window():
SettingWindow(root, settings_changement)
settings_button = tk.Button(root, text="Paramètres", command=open_settings_window)
settings_button.pack()
basecolors = ['white', 'green', 'red', 'maroon1', 'gold', 'dark orange', 'dodger blue', 'grey60', "purple"]
def userAction():
canvas.unbind('<space>')
canvas.bind('<Left>', lambda _: selectPos(-1))
canvas.bind('<Right>', lambda _: selectPos(1))
canvas.bind('<Up>', lambda _: switchColor(1))
canvas.bind('<Down>', lambda _: switchColor(-1))
canvas.bind('<Return>', lambda _: switchrow())
canvas.bind('1', lambda _: setcolor(board[row][cpos], basecolors[0]))
canvas.bind('2', lambda _: setcolor(board[row][cpos], basecolors[1]))
canvas.bind('3', lambda _: setcolor(board[row][cpos], basecolors[2]))
canvas.bind('4', lambda _: setcolor(board[row][cpos], basecolors[3]))
canvas.bind('5', lambda _: setcolor(board[row][cpos], basecolors[4]))
canvas.bind('6', lambda _: setcolor(board[row][cpos], basecolors[5]))
canvas.bind('7', lambda _: setcolor(board[row][cpos], basecolors[6]))
canvas.bind('8', lambda _: setcolor(board[row][cpos], basecolors[7]))
canvas.bind('9', lambda _: setcolor(board[row][cpos], basecolors[8]))
def userInAction():
canvas.unbind("<Left>")
canvas.unbind("<Right>")
canvas.unbind("<Up>")
canvas.unbind("<Down>")
canvas.unbind("<Return>")
canvas.unbind('1')
canvas.unbind('2')
canvas.unbind('3')
canvas.unbind('4')
canvas.unbind('5')
canvas.unbind('6')
canvas.unbind('7')
canvas.unbind('8')
canvas.unbind('9')
def creation_Code():
selection = [x for x in range(len(basecolors))]
code = []
for i in range(codeLength):
codeIndex = random.randint(0, len(selection) - 1)
code.append(selection[codeIndex])
selection.pop(codeIndex)
return code
codedColor = creation_Code()
def initRow():
global selectColors, tops, bots
selectColors = [x for x in range(len(basecolors))]
tops = 0
bots = 0
def initGame():
global row, cpos, colorpicks, codedColor
canvas.itemconfig(board[row][cpos], width=0)
for i in range(noOfGuesses):
for j in range(codeLength):
canvas.itemconfig(board[i][j], fill='#DBDFAA')
if i < noOfGuesses - 1:
canvas.itemconfig(response[i][j], fill='#DBDFAA')
colorpicks = [[-1 for i in range(codeLength)] for j in range(noOfGuesses)]
row = 0
cpos = 0
canvas.itemconfig(board[row][cpos], width=1)
userAction()
codedColor = creation_Code()
initRow()
board = []
response = []
for i in range(noOfGuesses):
newRow = []
newResponse = []
for j in range(codeLength):
x = colorpadding * j + 5
y = 600 - colorpadding * i - colorSize - 5
create_oval_with_gradient(canvas, x, y, colorSize, '#8888dd', '#000066')
newRow.append(canvas.create_oval(x, y, x + colorSize, y + colorSize, fill='#8888dd', outline='black', width=0))
if i < noOfGuesses - 1:
x = colorpadding / 2 * j + 255
y += colorSize / 8
newResponse.append(canvas.create_oval(x + colorSize / 4, y + colorSize / 4, x + colorSize / 2, y + colorSize / 2, fill='#8888dd', outline='black', width=0))
board.append(newRow)
if i < noOfGuesses - 1:
response.append(newResponse)
initGame()
canvas.itemconfig(board[row][cpos], width=1)
def select(colorPosition):
canvas.itemconfig(colorPosition, width=5)
def deselect(colorPosition):
canvas.itemconfig(colorPosition, width=0)
def setcolor(colorPosition, color):
canvas.itemconfig(colorPosition, fill=color)
def selectPos(increment):
global cpos
canvas.itemconfig(board[row][cpos], width=0)
cpos += increment
if cpos < 0: cpos = codeLength - 1
if cpos >= codeLength: cpos = 0
canvas.itemconfig(board[row][cpos], width=1)
def switchColor(increment):
colorpicks[row][cpos] += increment
if colorpicks[row][cpos] > len(basecolors) - 1: colorpicks[row][cpos] = 0
if colorpicks[row][cpos] < 0: colorpicks[row][cpos] = len(basecolors) - 1
canvas.itemconfig(board[row][cpos], fill=basecolors[colorpicks[row][cpos]])
def switchrow():
global row, tops, bots, colorpicks
for i in range(codeLength):
if colorpicks[row][i] == -1:
print("Couleurs non définies {},{}:".format(row, i))
return False
for j in range(codeLength):
if (j == i and codedColor[j] == colorpicks[row][i]): tops += 1
if (j != i and codedColor[j] == colorpicks[row][i]): bots += 1
if tops < codeLength and row < noOfGuesses - 2:
print("Tops : {}, Bots : {}".format(tops, bots))
for i in range(tops):
canvas.itemconfig(response[row][i], fill="black")
for i in range(bots):
canvas.itemconfig(response[row][i + tops], fill="white")
canvas.itemconfig(board[row][cpos], width=0)
row += 1
canvas.itemconfig(board[row][cpos], width=1)
initRow()
return False
else:
print("Ligne {}, Tops : {} et Bots : {}".format(row, tops, bots))
output = True
if row == noOfGuesses - 2:
output = False
for i in range(tops):
canvas.itemconfig(response[row][i], fill="black")
for i in range(bots):
canvas.itemconfig(response[row][i + tops], fill="white")
for i in range(codeLength):
canvas.itemconfig(board[noOfGuesses - 1][i], fill=basecolors[codedColor[i]])
userInAction()
canvas.bind("<space>", lambda _: initGame())
return output
initGame()
frame.pack()
canvas.pack()
root.title("Mastermind")
canvas.focus_set()
userAction()
canvas.bind("<F5>", lambda _: initGame())
root.bind("<F1>", lambda _: about())
root.bind("<F2>", lambda _: open_settings_window())
settings_button.destroy()
about_button.destroy()
root.mainloop()
je voudrais faire en sorte que je puisse changer les setting du jeu c'est a dire augmenter le nombre d'essai ou la taille du code secret a trouver et que ca affect le jeu en consequence
Quand on fait de la POO, on essaye de se rapprocher au maximum du projet en le rendant concret.
En l’occurrence dans le jeu du mastermind, il y a un vocabulaire (plateau, pion, couleur, rangées, ...) que l'on peut utiliser afin d'y voir une cohérence entre code et projet.
Les fonctions, classes et code principal sont mélangées, ça ne suit pas les conventions de la PEP8 et je pense même qu'au niveau architecture du code, on devrait pouvoir séparer interface graphique et cœur du jeu.
Ce code est mal engagé et on peut comprendre que les difficultés commencent à montrer le bout de leur nez.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard) La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)
si qqun voudrais bien m'aider sur ce qu'il faut faire en tenant en compte ce que j'ai fait je lui serais très reconnaissant
Quand on rencontre des erreurs, on commence par étudier le message d'erreur pour comprendre ce qui ne va pas. Votre code plante ligne 8 avec le message d'erreur TypeError: can't multiply sequence by non-int of type 'float' lorsqu'il exécute: color1[0] * (1 - weight).
On sait en remontant dans la pile d'appels que color1 est '#8888dd'.
On peut confirmer que l'erreur vient bien de là:
>>> '#8888dd'[0]*2.0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'float'
Il y a donc un petit travail à faire sur color1 (et 2) avant de réaliser l'opération souhaitée. Mais je ne le ferais pas pour vous.
Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)