chess.py

Created by loic-azavant

Created on September 20, 2023

11 KB

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()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.