un jeu d’echec /!\ pas complet, mais jouable
from kandinsky import * from ion import * from time import * keys = {} def keyinput(key,value=None): if value != None: keyPressed = value else: keyPressed = keydown(key) if not key in keys: keys[key] = False if keyPressed and not keys[key]: keys[key] = True return True if keys[key]: if not keyPressed: keys[key] = False return False return False delay = 0.1 keyDelayed = {} def keydowntimed(key,value=None,delay=delay): if value != None: keyPressed = value else: keyPressed = keydown(key) if not key in keyDelayed: keyDelayed[key] = 0 if keyPressed and monotonic()-keyDelayed[key] > delay: keyDelayed[key] = monotonic() return True return False def check_pawn(x,y,c,grid): moves = [] if grid[y-2*c+1][x] == None: moves.append((x,y-2*c+1)) if x!=7 and ((grid[y-2*c+1][x+1] != None and int(grid[y-2*c+1][x+1][1]) != c) or (grid[y][x+1] != None and len(grid[y][x+1]) == 3)): moves.append((x+1,y-2*c+1)) if x!=0 and ((grid[y-2*c+1][x-1] != None and int(grid[y-2*c+1][x-1][1]) != c) or (grid[y][x-1] != None and len(grid[y][x-1]) == 3)): moves.append((x-1,y-2*c+1)) if (x,y-2*c+1) in moves and y == 5*c+1 and grid[y-4*c+2][x] == None: moves.append((x,y-4*c+2)) return moves def check_rook(x,y,c,grid): moves = [] for i in range(y): if grid[y-i-1][x] == None: moves.append((x,y-i-1)) else: if int(grid[y-i-1][x][1]) != c: moves.append((x,y-i-1)) break for i in range(7-y): if grid[y+i+1][x] == None: moves.append((x,y+i+1)) else: if int(grid[y+i+1][x][1]) != c: moves.append((x,y+i+1)) break for i in range(x): if grid[y][x-i-1] == None: moves.append((x-i-1,y)) else: if int(grid[y][x-i-1][1]) != c: moves.append((x-i-1,y)) break for i in range(7-x): if grid[y][x+i+1] == None: moves.append((x+i+1,y)) else: if int(grid[y][x+i+1][1]) != c: moves.append((x+i+1,y)) break return moves def check_knight(x,y,c,grid): pos = ((1,2),(-1,2),(-2,1),(-2,-1),(-1,-2),(1,-2),(2,-1),(2,1)) moves = [] for i in pos: if 0<=x+i[0]<8 and 0<=y+i[1]<8 and (grid[y+i[1]][x+i[0]] == None or int(grid[y+i[1]][x+i[0]][1]) != c): moves.append((x+i[0],y+i[1])) return moves def check_bishop(x,y,c,grid): moves = [] for i in range(min(x,y)): if grid[y-i-1][x-i-1] == None: moves.append((x-i-1,y-i-1)) else: if int(grid[y-i-1][x-i-1][1]) != c: moves.append((x-i-1,y-i-1)) break for i in range(min(7-x,y)): if grid[y-i-1][x+i+1] == None: moves.append((x+i+1,y-i-1)) else: if int(grid[y-i-1][x+i+1][1]) != c: moves.append((x+i+1,y-i-1)) break for i in range(min(x,7-y)): if grid[y+i+1][x-i-1] == None: moves.append((x-i-1,y+i+1)) else: if int(grid[y+i+1][x-i-1][1]) != c: moves.append((x-i-1,y+i+1)) break for i in range(min(7-x,7-y)): if grid[y+i+1][x+i+1] == None: moves.append((x+i+1,y+i+1)) else: if int(grid[y+i+1][x+i+1][1]) != c: moves.append((x+i+1,y+i+1)) break return moves def check_king(x,y,c,grid,check_roque): pos = ((-1,-1),(0,-1),(1,-1),(1,0),(1,1),(0,1),(-1,1),(-1,0)) moves = [] for i in pos: if 0<=x+i[0]<8 and 0<=y+i[1]<8 and (grid[y+i[1]][x+i[0]] == None or int(grid[y+i[1]][x+i[0]][1]) != c): moves.append((x+i[0],y+i[1])) if len(grid[y][x]) > 2 and check_roque: if grid[y][x+1] == None and grid[y][x+2] == None and grid[y][x+3] != None and len(grid[y][x+3]) > 2: if not check_check(grid,not c,(x,y),(x+1,y),(x+2,y),(x+3,y)): moves.append((x+2,y)) if grid[y][x-1] == None and grid[y][x-2] == None and grid[y][x-3] == None and grid[y][x-4] != None and len(grid[y][x-4]) > 2: if not check_check(grid,not c,(x,y),(x-1,y),(x-2,y),(x-3,y),(x-4,y)): moves.append((x-2,y)) return moves def check_check(grid,c,*coord): for i in range(8): for j in range(8): if grid[j][i] != None and int(grid[j][i][1]) == c: for k in coord: if k in pieces_func[grid[j][i][0]](i,j,c,grid): return True return False def do_check(x,y,grid): c = int(grid[y][x][1]) moves = pieces_func[grid[y][x][0]](x,y,c,grid) for i in moves: if grid[i[1]][i[0]] != None and 'K'+str(int(not c)) in grid[i[1]][i[0]]: return True return False pieces_func = {'p': lambda x,y,c,grid: check_pawn(x,y,c,grid), 'r': lambda x,y,c,grid: check_rook(x,y,c,grid), 'k': lambda x,y,c,grid: check_knight(x,y,c,grid), 'b': lambda x,y,c,grid: check_bishop(x,y,c,grid), 'Q': lambda x,y,c,grid: pieces_func['r'](x,y,c,grid)+pieces_func['b'](x,y,c,grid), 'K': lambda x,y,c,grid,check_roque=False: check_king(x,y,c,grid,check_roque)} class Chess: def __init__(self): self.grid = [['r00','k0','b0','Q0','K00','b0','k0','r00'], ['p0','p0','p0','p0','p0','p0','p0','p0'], [None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None], [None,None,None,None,None,None,None,None], ['p1','p1','p1','p1','p1','p1','p1','p1'], ['r10','k1','b1','Q1','K10','b1','k1','r10']] self.grid_colors = ((155,85,0),(235,170,100)) self.cursor = [0,0] self.selected_square = () self.pieces_func = {'p': lambda: pieces_func['p'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid), 'r': lambda: pieces_func['r'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid), 'k': lambda: pieces_func['k'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid), 'b': lambda: pieces_func['b'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid), 'Q': lambda: pieces_func['Q'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid), 'K': lambda: pieces_func['K'](self.cursor[0],self.cursor[1],int(self.selected_square[0][1]),self.grid,True)} self.possible_moves = [] self.current_player = 0 self.checked = [False,False] def drw_square(self,x,y): if (x,y) in self.possible_moves: c = ((self.grid_colors[(x+y)%2][0]+150*(int(self.selected_square[0][1])!=self.current_player))/2,(150*(int(self.selected_square[0][1])==self.current_player)+self.grid_colors[(x+y)%2][1])/2,self.grid_colors[(x+y)%2][2]/2) else: c = self.grid_colors[(x+y)%2] fill_rect(56+x*26,7+y*26,26,26,c) s=' 0' if self.grid[y][x] == None else self.grid[y][x] draw_string(s[0],64+x*26,11+y*26,(255*int(s[1]),)*3,c) def drw_cursor(self): fill_rect(56+self.cursor[0]*26,7+self.cursor[1]*26,26,2,'k') fill_rect(56+self.cursor[0]*26,7+self.cursor[1]*26,2,26,'k') fill_rect(56+self.cursor[0]*26,31+self.cursor[1]*26,26,2,'k') fill_rect(80+self.cursor[0]*26,7+self.cursor[1]*26,2,26,'k') def drw_grid(self): for i in range(8): for j in range(8): self.drw_square(i,j) def drw_all(self): self.drw_grid() self.drw_cursor() def drw_replace_pawn_cursor(self,c,color): fill_rect(110+c*26,103,22,1,color) fill_rect(110+c*26,103,1,22,color) fill_rect(131+c*26,103,1,22,color) fill_rect(110+c*26,125,22,1,color) def replace_pawn(self): fill_rect(98,98,124,34,'k') fill_rect(100,100,120,30,'w') cursor = 0 for i in range(4): draw_string('rbkQ'[i],116+i*26,105) self.drw_replace_pawn_cursor(cursor,'k') while keydown(4): pass while 1: arrowHori = keyinput(3)-keyinput(0) if arrowHori: self.drw_replace_pawn_cursor(cursor,'w') cursor = max(0,min(3,cursor+arrowHori)) self.drw_replace_pawn_cursor(cursor,'k') if keydown(4): return 'rbkQ'[cursor] def move_cursor(self): arrowVerti = keydowntimed(2,self.downPressed)-keydowntimed(1,self.upPressed) arrowHori = keydowntimed(3,self.rightPressed)-keydowntimed(0,self.leftPressed) if arrowHori or arrowVerti: self.drw_square(*self.cursor) self.cursor[0] = max(0,min(self.cursor[0]+arrowHori,7)) self.cursor[1] = max(0,min(self.cursor[1]+arrowVerti,7)) self.drw_cursor() def move_selected_piece(self): if self.selected_square[0][0] == 'p': if (self.cursor[1] == 7 or self.cursor[1] == 0): newPiece = self.replace_pawn()+self.selected_square[0][1] elif abs(self.selected_square[1]-self.cursor[1]) == 2: newPiece = self.selected_square[0]+'1' else: newPiece = self.selected_square[0] if self.selected_square[2] != self.cursor[0] and self.grid[self.cursor[1]][self.cursor[0]] == None: self.grid[self.selected_square[1]][self.cursor[0]] = None elif self.selected_square[0][0] == 'K': if abs(self.selected_square[2]-self.cursor[0]) > 1: self.grid[self.cursor[1]][round(0.5*self.cursor[0]+2)] = 'r'+self.selected_square[0][1] self.grid[self.cursor[1]][round(1.75*self.cursor[0]-3.5)] = None newPiece = self.selected_square[0][0:2] elif self.selected_square[0][0] == 'r': newPiece = self.selected_square[0][0:2] else: newPiece = self.selected_square[0] self.grid[self.selected_square[1]][self.selected_square[2]] = None self.grid[self.cursor[1]][self.cursor[0]] = newPiece if self.selected_square[0][0] == 'p' and (self.cursor[1] == 7 or self.cursor[1] == 0): self.replace_pawn() self.possible_moves.clear() self.checked[self.current_player] = do_check(self.cursor[0],self.cursor[1],self.grid) self.selected_square = () self.drw_all() def clear_selection(self): self.selected_square = () self.possible_moves.clear() self.drw_all() def select_current_piece(self): self.selected_square = (self.grid[self.cursor[1]][self.cursor[0]],self.cursor[1],self.cursor[0]) self.possible_moves = self.pieces_func[self.selected_square[0][0]]() self.drw_all() def check_en_passant(self): for i in range(8): for j in range(8): if self.grid[j][i] != None and int(self.grid[j][i][1]) == self.current_player and self.grid[j][i][0] == 'p': self.grid[j][i] = self.grid[j][i][0:2] def play(self): while 1: self.okPressed = keydown(4) self.leftPressed = keydown(0) self.rightPressed = keydown(3) self.upPressed = keydown(1) self.downPressed = keydown(2) self.move_cursor() if keyinput(4,self.okPressed): if len(self.selected_square) != 0 and (self.cursor[0],self.cursor[1]) in self.possible_moves and int(self.selected_square[0][1]) == self.current_player: self.move_selected_piece() self.current_player = not self.current_player self.check_en_passant() else: if self.grid[self.cursor[1]][self.cursor[0]] == None: self.clear_selection() else: self.select_current_piece() c=Chess() c.drw_grid() c.drw_cursor() c.play()