346 lines
7.8 KiB
Python
346 lines
7.8 KiB
Python
# pylint: disable=W0603
|
|
|
|
# INFOS
|
|
|
|
# Pièces :
|
|
|
|
# [1-6] : Blancs
|
|
# [11-6] : Noirs
|
|
|
|
# X1 : Pion
|
|
# X2 : Tour
|
|
# X3 : Cavalier
|
|
# x4 : Fou
|
|
# X5 : Dame
|
|
# X6 : Roi
|
|
|
|
|
|
# j_ jeu : le logique du jeu lui même
|
|
# g_ GUI : l'interface graphique
|
|
# f_ Frontend : ce qui associe les deux
|
|
# _e : est
|
|
# _c : crée
|
|
# _d : déplace
|
|
|
|
|
|
# IMPORTS
|
|
from tkinter import *
|
|
from random import randint
|
|
|
|
# FONCTIONS
|
|
|
|
|
|
# Jeu
|
|
CASES_COTE = 8
|
|
|
|
j_grille = None
|
|
j_joueur = True
|
|
|
|
def j_eNoir(xD, yD): # TODO Peut être considérablement amélioré
|
|
i = 1
|
|
for x in range(0, CASES_COTE):
|
|
i += 1
|
|
for y in range(0, CASES_COTE):
|
|
i += 1
|
|
if x == xD and y == yD:
|
|
return i%2
|
|
def j_cGrille():
|
|
global j_grille
|
|
j_grille = []
|
|
for x in range(CASES_COTE):
|
|
colonne = []
|
|
for y in range(CASES_COTE):
|
|
colonne.append(0)
|
|
j_grille.append(colonne)
|
|
|
|
def j_remplirGrille():
|
|
global j_grille
|
|
speciales = [2, 3, 4, 6, 5, 4, 3, 2]
|
|
for i in range(0, 8):
|
|
j_grille[i][0] = speciales[i] + 10
|
|
j_grille[i][1] = 11
|
|
j_grille[i][6] = 1
|
|
j_grille[i][7] = speciales[i]
|
|
|
|
def j_nvPartie():
|
|
j_cGrille()
|
|
j_remplirGrille()
|
|
global j_joueur
|
|
j_joueur = True
|
|
|
|
def j_cPion(x, y, piece):
|
|
"""
|
|
"""
|
|
j_grille[x][y] = piece
|
|
return True
|
|
|
|
def j_mvtPossible(x1, y1, x2, y2):
|
|
pion = j_grille[x1][y1]
|
|
if (pion >= 10 and j_joueur == False) or (pion < 10 and j_joueur == True):
|
|
if pion > 0 and j_grille[x2][y2] <= 0:
|
|
tPion = pion%10
|
|
if tPion == 1:
|
|
if x1 == x2:
|
|
if j_joueur:
|
|
if y2 == y1-1:
|
|
return True
|
|
else:
|
|
return -4
|
|
else:
|
|
if y2 == y1+1:
|
|
return True
|
|
else:
|
|
return -4
|
|
else:
|
|
return -4
|
|
elif tPion == 6:
|
|
if x2 <= x1+1 and x2 >= x1-1 and y2 <= y1+1 and y2 >= y1-1 \
|
|
and (x1 != x2 or y1 != y2):
|
|
return True
|
|
else:
|
|
return -4
|
|
else:
|
|
return -3
|
|
|
|
return True
|
|
else:
|
|
return -2
|
|
else:
|
|
return -1
|
|
|
|
def j_dPion(x1, y1, x2, y2):
|
|
test = j_mvtPossible(x1, y1, x2, y2)
|
|
if test == True:
|
|
global j_joueur, j_grille
|
|
j_grille[x2][y2] = j_grille[x1][y1]
|
|
j_grille[x1][y1] = 0
|
|
# j_joueur = not j_joueur # DEBUG
|
|
return True
|
|
else:
|
|
return test
|
|
|
|
# GUI
|
|
DECX = 0
|
|
DECY = 0
|
|
COTE_CASE = 50
|
|
MARGE_PIONS = 5
|
|
TEMPS_ANIM = 200
|
|
INTER_ANIM = 10
|
|
|
|
g_imagesOriginales = []
|
|
g_imagesRedim = []
|
|
|
|
|
|
g_grilleDamier = None
|
|
g_grillePions = None
|
|
g_photos = []
|
|
fen = None
|
|
can = None
|
|
chaine = None
|
|
|
|
# Animation
|
|
g_x1 = None
|
|
g_y1 = None
|
|
g_x2 = None
|
|
g_y2 = None
|
|
g_pion = None
|
|
g_anim = None
|
|
|
|
def g_fen():
|
|
global fen, can, chaine
|
|
fen = Tk()
|
|
fen.title("Jeu d'Échecs")
|
|
can = Canvas(fen, width=COTE_CASE*CASES_COTE, height=COTE_CASE*CASES_COTE, \
|
|
bg="ivory")
|
|
can.grid(row=0, column=1, columnspan=3)
|
|
can.bind('<Button-1>', f_clic)
|
|
chaine = Label(fen, text="Aux blancs")
|
|
chaine.grid(row=2, column=2, padx=3, pady=3)
|
|
Button(fen, text="Nv. Partie", command=f_nvPartie).grid(row=2, column=1, \
|
|
padx=3, pady=3)
|
|
Button(fen, text="Quitter", command=fen.destroy).grid(row=2, column=3, \
|
|
padx=3, pady=3)
|
|
|
|
def g_statut(texte, delai=0):
|
|
chaine.config(text=texte)
|
|
# TODO Timeout effacer si parametre / Liste
|
|
|
|
def g_importerImages():
|
|
global g_imagesOriginales
|
|
for piece in range(0, 21):
|
|
nom = 'sprites/'
|
|
if piece%10 == 1:
|
|
nom += 'pion'
|
|
elif piece%10 == 2:
|
|
nom += 'tour'
|
|
elif piece%10 == 3:
|
|
nom += 'cavalier'
|
|
elif piece%10 == 4:
|
|
nom += 'fou'
|
|
elif piece%10 == 5:
|
|
nom += 'dame'
|
|
elif piece%10 == 6:
|
|
nom += 'roi'
|
|
else:
|
|
g_imagesOriginales.append('')
|
|
continue
|
|
if piece < 10:
|
|
nom += 'B'
|
|
else:
|
|
nom += 'N'
|
|
nom += '.gif'
|
|
g_imagesOriginales.append(PhotoImage(file=nom))
|
|
|
|
def g_redimImages():
|
|
global g_imagesRedim
|
|
sample = int(504/(COTE_CASE-MARGE_PIONS))
|
|
for piece in range(0, 21):
|
|
if g_imagesOriginales[piece] != '':
|
|
g_imagesRedim.append(g_imagesOriginales[piece].subsample(sample))
|
|
else:
|
|
g_imagesRedim.append('')
|
|
|
|
|
|
def g_cCase(x, y):
|
|
if j_eNoir(x, y):
|
|
couleur = '#D18B47'
|
|
else:
|
|
couleur = '#FFCE9E'
|
|
return can.create_rectangle(x*COTE_CASE, y*COTE_CASE, \
|
|
(x+1)*COTE_CASE, (y+1)*COTE_CASE, fill=couleur)
|
|
|
|
def g_cDamier():
|
|
global g_grilleDamier
|
|
g_grilleDamier = []
|
|
for x in range(0, CASES_COTE):
|
|
colonne = []
|
|
for y in range(0, CASES_COTE):
|
|
colonne.append(g_cCase(x + DECX, y + DECY))
|
|
g_grilleDamier.append(colonne)
|
|
|
|
def g_cPion(x, y, piece):
|
|
global g_grillePions
|
|
global g_photos
|
|
if piece > 0:
|
|
g_grillePions[x][y] = can.create_image((x+.5)*COTE_CASE, \
|
|
(y+.5)*COTE_CASE, image=g_imagesRedim[piece])
|
|
else:
|
|
g_grillePions[x][y] = False
|
|
|
|
def g_dPionFinal():
|
|
can.coords(g_pion, g_x2, g_y2)
|
|
|
|
def g_dPionAnim():
|
|
global g_pion, g_anim
|
|
x = g_x1 + (g_x2-g_x1) * (g_anim/TEMPS_ANIM)
|
|
y = g_y1 + (g_y2-g_y1) * (g_anim/TEMPS_ANIM)
|
|
can.coords(g_pion, x, y)
|
|
g_anim += INTER_ANIM
|
|
if g_anim < TEMPS_ANIM:
|
|
fen.after(INTER_ANIM, g_dPionAnim)
|
|
else:
|
|
g_dPionFinal()
|
|
|
|
def g_dPion(x1, y1, x2, y2):
|
|
# TODO Bloquer l'entrée pendant l'anim
|
|
global g_grillePions, g_x1, g_y1, g_x2, g_y2, g_pion, g_anim
|
|
g_x1 = (x1+.5)*COTE_CASE
|
|
g_y1 = (y1+.5)*COTE_CASE
|
|
g_x2 = (x2+.5)*COTE_CASE
|
|
g_y2 = (y2+.5)*COTE_CASE
|
|
g_pion = g_grillePions[x1][y1]
|
|
g_anim = 0
|
|
# can.coords(g_grillePions[x1][y1], (x2+.5)*COTE_CASE, (y2+.5)*COTE_CASE)
|
|
g_grillePions[x2][y2] = g_grillePions[x1][y1]
|
|
g_grillePions[x1][y1] = False
|
|
g_dPionAnim()
|
|
# g_dPionFinal()
|
|
|
|
def g_cGrille():
|
|
global g_grillePions
|
|
g_grillePions = []
|
|
for x in range(0, CASES_COTE): # Crée g_grillePions
|
|
colonne = []
|
|
for y in range(0, CASES_COTE):
|
|
colonne.append(False)
|
|
g_grillePions.append(colonne)
|
|
|
|
def g_remplirGrille(j_grilleF):
|
|
global g_grillePions
|
|
for x in range(0, CASES_COTE): # Remplis g_grillePions
|
|
for y in range(0, CASES_COTE):
|
|
g_cPion(x, y, j_grilleF[x][y])
|
|
|
|
def g_init():
|
|
g_fen()
|
|
g_importerImages()
|
|
g_redimImages()
|
|
|
|
# Frontend
|
|
|
|
f_origine = True
|
|
f_x1 = -1
|
|
f_y1 = -1
|
|
f_x2 = -1
|
|
f_y2 = -1
|
|
|
|
def f_statutPrendre():
|
|
if j_joueur:
|
|
joueur = 'blancs'
|
|
else:
|
|
joueur = 'noirs'
|
|
g_statut('Prendre (' + joueur + ')')
|
|
|
|
def f_init():
|
|
g_init()
|
|
f_nvPartie()
|
|
f_statutPrendre()
|
|
|
|
|
|
def f_cPion(x, y, piece):
|
|
if j_cPion(x, y, piece):
|
|
g_cPion(x, y, piece)
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def f_cPionAlea():
|
|
g_cPion(randint(1, CASES_COTE), randint(1, CASES_COTE), 1)
|
|
|
|
def f_dPion(x1, y1, x2, y2):
|
|
test = j_dPion(x1, y1, x2, y2)
|
|
if test == True:
|
|
g_dPion(x1, y1, x2, y2)
|
|
return True
|
|
else:
|
|
g_statut('Impossible ! ('+str(test)+')') # TODO Messages corrects
|
|
return False
|
|
|
|
def f_nvPartie():
|
|
j_nvPartie()
|
|
g_cDamier()
|
|
g_cGrille()
|
|
g_remplirGrille(j_grille)
|
|
|
|
def f_dClic(x, y):
|
|
global f_origine, f_x1, f_y1, f_x2, f_y2
|
|
if f_origine:
|
|
f_x1, f_y1 = x, y
|
|
# TODO Colorer case
|
|
g_statut('Poser')
|
|
else:
|
|
f_x2, f_y2 = x, y
|
|
f_dPion(f_x1, f_y1, f_x2, f_y2)
|
|
f_statutPrendre()
|
|
f_origine = not f_origine
|
|
|
|
|
|
def f_clic(event):
|
|
x = event.x//COTE_CASE
|
|
y = event.y//COTE_CASE
|
|
f_dClic(x, y)
|
|
|
|
|
|
|
|
f_init()
|