Facebook
From عرشیا, 1 Month ago, written in Python.
Embed
Download Paste or View Raw
Hits: 170
  1. import tkinter as tk
  2. from tkinter import messagebox
  3. from tkinter import Button
  4. from functools import partial
  5. from PIL import ImageTk, Image
  6. class Position:
  7.     def __init__(self, row, col):
  8.         self.row = row
  9.         self.col = col
  10.     def match(self,list_pos):
  11.         for pos in list_pos:
  12.             if pos.row == self.row and pos.col == self.col:
  13.                 return True
  14.         return False
  15. class Piece:
  16.     def __init__(self, color, board, position=None):
  17.         self.color = color
  18.         self.board = board
  19.         self.has_moved = False
  20.         self.position = position
  21.     def __str__(self):
  22.         pass
  23. class King(Piece):
  24.     def __init__(self,color,board,position=None):
  25.         super().__init__(color,board,position)
  26.         self.piece_type = "king"
  27.        
  28.     def possible_moves(self):
  29.         moves = []
  30.         offsets = [(1, 0), (0, 1), (-1, 0), (0, -1),
  31.                    (1, 1), (-1, 1), (1, -1), (-1, -1)]
  32.         for dr, dc in offsets:
  33.             new_pos = Position(self.position.row + dr, self.position.col + dc)
  34.             if self.board.is_inside_board(new_pos) and (self.board.is_square_empty(new_pos) or self.board.is_enemy_piece(new_pos, self.color)):
  35.                 moves.append(new_pos)
  36.         # Castling
  37.         if not self.board.board[self.position.row][self.position.col].has_moved:
  38.             print("roozbeh")
  39.             # Check kingside castling
  40.             if self.board.board[self.position.row][7] and not self.board.board[self.position.row][7].has_moved:
  41.                 if all(self.board.is_square_empty(Position(self.position.row, c)) for c in range(self.position.col + 1, 7)):
  42.                     print("poo")
  43.                     moves.append(Position(self.position.row, self.position.col + 2))
  44.             # Check queenside castling
  45.             if not self.board.board[self.position.row][0]:
  46.                 print("ali")
  47.             if self.board.board[self.position.row][0].has_moved:
  48.                 print(self.position.row)
  49.                 print("sook")
  50.             if  self.board.board[self.position.row][0] and not self.board.board[self.position.row][0].has_moved:
  51.                 print("younes")
  52.                 if all(self.board.is_square_empty(Position(self.position.row, c)) for c in range(1, self.position.col)):
  53.                     print("abdolali")
  54.                     moves.append(Position(self.position.row, self.position.col - 2))
  55.         return moves
  56.     def move(self,end_pos):
  57.         a = self.possible_moves()
  58.         for pos in a:
  59.             if pos.row == end_pos.row and pos.col == end_pos.col:
  60.                 return True
  61.         return False
  62.     def __str__(self):
  63.         if self.color == "White":
  64.             return "K"
  65.         return "k"
  66. class Bishop(Piece):
  67.     def __init__(self,color,board,position=None):
  68.         super().__init__(color,board,position)
  69.         self.piece_type = "bishop"
  70.     def possible_moves(self):
  71.         moves = []
  72.         directions = [(-1, -1), (-1, 1), (1, 1), (1, -1)]
  73.         for dr, dc in directions:
  74.             temp = self.position
  75.             while True:
  76.                 new_pos = Position(temp.row + dr, temp.col + dc)
  77.                 temp = new_pos
  78.                 if self.board.is_inside_board(new_pos) == False:
  79.                     break
  80.                 if self.board.is_inside_board(new_pos) and (self.board.is_square_empty(new_pos) or self.board.is_enemy_piece(new_pos, self.color)):
  81.                     moves.append(new_pos)
  82.                 if self.board.is_enemy_piece(new_pos, self.color):
  83.                     break
  84.                 if not self.board.is_square_empty(new_pos):
  85.                     break
  86.         return moves
  87.     def move(self,end_pos):
  88.         a = self.possible_moves()
  89.         for pos in a:
  90.             if pos.row == end_pos.row and pos.col == end_pos.col:
  91.                 return True
  92.         return False
  93.     def __str__(self):
  94.         if self.color == "White":
  95.             return "B"
  96.         return "b"
  97. class Pawn(Piece):
  98.     def __init__(self,color,board,position=None):
  99.         super().__init__(color,board,position)
  100.         self.piece_type = "pawn"
  101.     def possible_moves(self):
  102.         moves = []
  103.         direction = 1 if self.color == "White" else -1
  104.         start_row = 1 if self.color == "White" else 6
  105.         # Moves for regular pawn advance
  106.         temp = self.position
  107.         count = 0
  108.         if start_row == temp.row:
  109.             help = 2
  110.         else:
  111.             help = 1
  112.         while count < help:
  113.             new_pos = Position(temp.row + direction, temp.col)
  114.             temp = new_pos
  115.             if self.board.is_inside_board(new_pos) and self.board.is_square_empty(new_pos):
  116.                 moves.append(new_pos)
  117.             else:
  118.                 break
  119.             count += 1
  120.         # Moves for capturing diagonally
  121.         temp = self.position
  122.         new_pos = Position(temp.row + direction, temp.col - 1)
  123.         if self.board.is_inside_board(new_pos):
  124.             if self.board.is_enemy_piece(new_pos, self.color):
  125.                 moves.append(new_pos)
  126.         new_pos = Position(temp.row + direction, temp.col + 1)
  127.         if self.board.is_inside_board(new_pos):
  128.             if self.board.is_enemy_piece(new_pos, self.color):
  129.                 moves.append(new_pos)
  130.         return moves
  131.     def move(self,end_pos):
  132.         a = self.possible_moves()
  133.         for pos in a:
  134.             if pos.row == end_pos.row and pos.col == end_pos.col:
  135.                 return True
  136.         return False
  137.     def __str__(self):
  138.         if self.color == "White":
  139.             return "P"
  140.         return "p"
  141. class Rook(Piece):
  142.      def __init__(self,color,board,positi
  143.         super().__init__(color,board,position)
  144.         self.piece_type = "rook"
  145.     def possible_moves(self):
  146.         moves = []
  147.          directi 0), (-1, 0), (0, 1), (0, -1)]
  148.         for dr, dc in directions:
  149.             temp = self.position
  150.             while True:
  151.                 new_pos = Position(temp.row + dr, temp.col + dc)
  152.                 temp = new_pos
  153.                 if self.board.is_inside_board(new_pos) == False:
  154.                     break
  155.                 if self.board.is_inside_board(new_pos) and (self.board.is_square_empty(new_pos) or self.board.is_enemy_piece(new_pos, self.color)):
  156.                     moves.append(new_pos)
  157.                 if not self.board.is_square_empty(new_pos):
  158.                     break
  159.         return moves
  160.     def move(self,end_pos):
  161.         a = self.possible_moves()
  162.         for pos in a:
  163.             if pos.row == end_pos.row and pos.col == end_pos.col:
  164.                 return True
  165.         return False
  166.     def __str__(self):
  167.         if self.color == "White":
  168.             return "R"
  169.         return "r"
  170.  
  171. class Knight(Piece):
  172.      def __init__(self,color,board,positi
  173.         super().__init__(color,board,position)
  174.         self.piece_type = "knight"
  175.     def possible_moves(self):
  176.         moves = []
  177.         ends = [(-2, 1), (-2, -1), (2, -1), (2, 1), (1, 2), (-1, 2), (1, -2), (-1, -2)]
  178.         temp = self.position
  179.         for er, ec in ends:
  180.             new_pos = Position(temp.row + er, temp.col + ec)
  181.             # print(new_pos.row, new_pos.col)
  182.             if self.board.is_inside_board(new_pos) and (self.board.is_square_empty(new_pos) or self.board.is_enemy_piece(new_pos, self.color)):
  183.                 moves.append(new_pos)
  184.  
  185.         return moves
  186.     def move(self,end_pos):
  187.         a = self.possible_moves()
  188.         for pos in a:
  189.             if pos.row == end_pos.row and pos.col == end_pos.col:
  190.                 return True
  191.         return False
  192.     def __str__(self):
  193.         if self.color == "White":
  194.             return "N"
  195.         return "n"
  196.            
  197. class Queen(Piece):
  198.      def __init__(self,color,board,positi
  199.         super().__init__(color,board,position)
  200.         self.piece_type = "queen"
  201.     def possible_moves(self):
  202.         moves = []
  203.          directi -1), (-1, 1), (1, 1), (1, -1), (1, 0), (-1, 0), (0, 1), (0, -1)]
  204.         for dr, dc in directions:
  205.             temp = self.position
  206.             while True:
  207.                 new_pos = Position(temp.row + dr, temp.col + dc)
  208.                 temp = new_pos
  209.                 if self.board.is_inside_board(new_pos):
  210.                     if self.board.is_square_empty(new_pos) or self.board.is_enemy_piece(new_pos, self.color):
  211.                         moves.append(new_pos)
  212.                 if not self.board.is_inside_board(new_pos):
  213.                     break
  214.                 if not self.board.is_square_empty(new_pos):
  215.                     break
  216.         return moves
  217.     def move(self,end_pos):
  218.         a = self.possible_moves()
  219.         for pos in a:
  220.             if pos.row == end_pos.row and pos.col == end_pos.col:
  221.                 return True
  222.         return False
  223.     def __str__(self):
  224.         if self.color == "White":
  225.             return "Q"
  226.         return "q"
  227. class Board:
  228.     def __init__(self):    
  229.         self.board = [[None for _ in range(8)] for _ in range(8)] #initialize the board
  230.          self.butt for _ in range(8)] for _ in range(8)]
  231.         self.left_click = [[0 for _ in range(8)] for _ in range(8)]
  232.         self.right_click = [[0 for _ in range(8)] for _ in range(8)]
  233.         self.current_player = "White"
  234.         self.cc = 0
  235.         for i in range(8):
  236.             for j in range(8):
  237.                 bt = Button(master, text = '', height = 5, width = 10, image = ImageTk.PhotoImage(Image.open("/Users/arshiash/Documents/1403-01-06 22.33.08.jpg")))
  238.                 bt.bind("<Button-1>", self.inner1(i, j))
  239.                 bt.bind("<Button-2>", self.inner2(i, j))
  240.                 self.buttons[i][j] = bt
  241.                 bt.grid(row = i, column = j)
  242.     def inner1(self, i, j):
  243.         def lft(l):
  244.             print(type(self))
  245.             print("lili")
  246.             for x in self.board[i][j].possible_moves():
  247.                 print(x.row, x.col)
  248.             for ii in range(8):
  249.                 for jj in range(8):
  250.                     self.left_click[ii][jj] = 0
  251.             if self.board[i][j]:
  252.                 if self.board[i][j].color == self.current_player:
  253.                     self.left_click[i][j] = 1
  254.         return lft
  255.     def inner2(self, i, j):
  256.         def rgt(l):
  257.             flag = False
  258.             for ii in range(8):
  259.                 for jj in range(8):
  260.                     if self.left_click[ii][jj] == 1:
  261.                         print("salam")
  262.                         flag = True
  263.                         co_ii = ii
  264.                         co_jj = jj
  265.             if flag == True:
  266.                 for ii in range(8):
  267.                     for jj in range(8):
  268.                         self.right_click[ii][jj] = 0
  269.                 self.right_click[i][j] = 1
  270.                 if self.board[co_ii][co_jj].move(Position(i, j)):
  271.                     co_1 = self.board[co_ii][co_jj]
  272.                     co_2 = self.board[i][j]
  273.                     self.move_piece(Position(co_ii, co_jj), Position(i, j))
  274.                     if (not self.is_check(self.current_player)) and co_1.piece_type == "king" and (co_ii == i) and (abs(co_jj - j) > 1):
  275.                         if co_1.color == "White":
  276.                             if co_ii == 0:
  277.                                 if j > co_jj:
  278.                                     print("mohammadreza")
  279.                                     self.cc = 1
  280.                                     self.move_piece(Position(0, 7), Position(0, 5))
  281.                                 if j < co_jj:
  282.                                     self.cc = 1
  283.                                     self.move_piece(Position(0, 0), Position(0, 3))
  284.                         if co_1.color == "Black":
  285.                             if co_ii == 7:
  286.                                 if j > co_jj:
  287.                                     self.cc = 1
  288.                                     self.move_piece(Position(7, 7), Position(7, 5))
  289.                                 if j < co_jj:
  290.                                     self.cc = 1
  291.                                     self.move_piece(Position(7, 0), Position(7, 3))
  292.  
  293.                     temp = False
  294.                     if self.is_check(self.current_player):
  295.                         print("arshia")
  296.                         messagebox.showinfo("NOP", "Your still check")
  297.                         self.remove_piece(self.board[i][j])
  298.                         self.place_piece(co_1, Position(co_ii, co_jj))
  299.                         if co_2:
  300.                             print(co_2.piece_type)
  301.                         self.place_piece(co_2, Position(i, j))
  302.                         temp = True
  303.                     self.current_player = "Black" if self.current_player == "White" else "White"
  304.                     if temp == True:
  305.                         self.current_player = "Black" if self.current_player == "White" else "White"
  306.                     if self.is_checkmate(self.current_player):
  307.                         messagebox.showinfo("The end", f'{self.current_player} lost')
  308.                         master.destroy()
  309.         return rgt
  310.            
  311.     def is_check(self, current_player):
  312.         #TODO - find current_player's king on the board, check if the king is in check
  313.         enemy = "Black" if current_player == "White" else "White"
  314.         for i in range(8):
  315.             for j in range(8):
  316.                 piece = self.board[i][j]
  317.                 if piece:
  318.                     if piece.color == enemy:
  319.                         if piece.possible_moves():
  320.                             for pos in piece.possible_moves():
  321.                                 if self.board[pos.row][pos.col]:
  322.                                     if self.board[pos.row][pos.col].piece_type == "king":
  323.                                         return True
  324.         return False
  325.     def is_checkmate(self, current_player):
  326.         # For simplicity, we consider losing the king as checkmate
  327.         enemy = "Black" if current_player == "White" else "White"
  328.         for i in range(8):
  329.             for j in range(8):
  330.                 if not self.board[i][j]:
  331.                     continue
  332.                 if self.board[i][j].color == enemy:
  333.                     continue
  334.                 co_1 = self.board[i][j]
  335.                 for mv in self.board[i][j].possible_moves():
  336.                     co_2 = self.board[mv.row][mv.col]
  337.                     if co_1:
  338.                         help1 = self.board[i][j].has_moved
  339.                     if co_2:
  340.                         help2 = self.board[i][j].has_moved
  341.                     self.move_piece(Position(i, j), mv)
  342.                     if not self.is_check(current_player):
  343.                         self.remove_piece(self.board[mv.row][mv.col])
  344.                         self.place_piece(co_1, Position(i, j))
  345.                         self.place_piece(co_2, Position(mv.row, mv.col))
  346.                         if self.board[i][j]:
  347.                             self.board[i][j].has_moved = help1
  348.                         if self.board[mv.row][mv.col]:
  349.                             self.board[mv.row][mv.col].has_moved = help2
  350.                         print(i, j, " ", mv.row, mv.col)
  351.                         return False
  352.                     self.remove_piece(self.board[mv.row][mv.col])
  353.                     self.place_piece(co_1, Position(i, j))
  354.                     self.place_piece(co_2, Position(mv.row, mv.col))
  355.         return True
  356.     def place_piece(self, piece, position):
  357.         if piece:
  358.             self.board[position.row][position.col] = piece
  359.         if piece:
  360.             tmp = 'green' if piece.color == "White" else 'black'
  361.         else:
  362.             tmp = 'white'
  363.         if piece:
  364.             self.buttons[position.row][position.col].config(text = f'{piece.piece_type}', foreground = tmp)
  365.              piece.positi
  366.         else:
  367.             self.buttons[position.row][position.col].config(text = '')
  368.  
  369.     def remove_piece(self, piece):
  370.         self.board[piece.position.row][piece.position.col] = None
  371.         self.buttons[piece.position.row][piece.position.col].config(text = '')
  372.  
  373.     def move_piece(self, start_pos, end_pos):
  374.         piece = self.board[start_pos.row][start_pos.col]
  375.        
  376.         if piece:
  377.             if piece.move(end_pos) or (piece.piece_type == 'rook' and self.cc == 1):
  378.                 if piece.piece_type == 'rook' and self.cc == 1:
  379.                     self.cc = 0
  380.                 #TODO (remove piece, place the piece at the end_pos and set has_moved to True)
  381.                 self.remove_piece(piece)
  382.                 self.place_piece(piece, end_pos)
  383.                 piece.has_moved = True
  384.                  piece.positi
  385.                 return True
  386.         else:
  387.             print("No piece at the starting position.")
  388.             return False
  389.  
  390.     def is_square_empty(self, position):
  391.         return self.board[position.row][position.col] is None
  392.  
  393.     def is_enemy_piece(self, position, color):
  394.         if not self.is_square_empty(position):
  395.             if self.board[position.row][position.col].color == color:
  396.                 return False
  397.             return True
  398.         return False
  399.            
  400.  
  401.  
  402.     def is_inside_board(self, position):
  403.         if position.row > 7 or position.col > 7 or position.row < 0 or position.col < 0:
  404.             return False
  405.         return True
  406. class ChessSet:
  407.     def __init__(self):
  408.         self.board = Board()
  409.         self.setup_board()
  410.  
  411.     def setup_board(self):
  412.         # Place white pieces
  413.         self.board.place_piece(Rook("White",self.board), Position(0, 0))
  414.         self.board.place_piece(Knight("White",self.board), Position(0, 1))
  415.         self.board.place_piece(Bishop("White",self.board), Position(0, 2))
  416.         self.board.place_piece(Queen("White",self.board), Position(0, 3))
  417.         self.board.place_piece(King("White",self.board), Position(0, 4))
  418.         self.board.place_piece(Bishop("White",self.board), Position(0, 5))
  419.         self.board.place_piece(Knight("White",self.board), Position(0, 6))
  420.         self.board.place_piece(Rook("White",self.board), Position(0, 7))
  421.         for col in range(8):
  422.             self.board.place_piece(Pawn("White", self.board), Position(1, col))
  423.  
  424.  
  425.         # Place black pieces
  426.         self.board.place_piece(Rook("Black",self.board), Position(7, 0))
  427.         self.board.place_piece(Knight("Black",self.board), Position(7, 1))
  428.         self.board.place_piece(Bishop("Black",self.board), Position(7, 2))
  429.         self.board.place_piece(Queen("Black",self.board), Position(7, 3))
  430.         self.board.place_piece(King("Black",self.board), Position(7, 4))
  431.         self.board.place_piece(Bishop("Black",self.board), Position(7, 5))
  432.         self.board.place_piece(Knight("Black",self.board), Position(7, 6))
  433.         self.board.place_piece(Rook("Black",self.board), Position(7, 7))
  434.         for col in range(8):
  435.             self.board.place_piece(Pawn("Black", self.board), Position(6, col))
  436.  
  437.     def print_board(self):
  438.         self.board.print_board()
  439. class Chess:
  440.     def __init__(self):
  441.         self.chess_set = ChessSet()
  442.  
  443. if __name__ == "__main__":
  444.     master = tk.Tk()
  445.     master.geometry("850x680")
  446.     chess_game = Chess()
  447.     master.mainloop()
  448.