Guest User

ChesswithGUI

a guest
Jan 11th, 2016
175
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import numpy as np
  2. import tkinter as tk
  3. import os.path
  4. import os
  5. # CHECK, PROMOTION AND CASTLING
  6. tile_width = 60
  7. board_width = 8 * tile_width
  8. board_height = board_width
  9. pic_dir = "/mnt/DATA/Dropbox/Courses/Python/Project/Pictures"
  10. DICT = {"black_tile":"black.gif",
  11.     "Bb":"blackbishop.gif",
  12.     "Bw":"whitebishop.gif",
  13.     "Kb":"blackking.gif",
  14.     "Kw":"whiteking.gif",
  15.     "Nb":"blackknight.gif",
  16.     "Nw":"whiteknight.gif",
  17.     "Pb":"blackpawn.gif",
  18.     "Pw":"whitepawn.gif",
  19.     "Qb":"blackqueen.gif",
  20.     "Qw":"whitequeen.gif",
  21.     "Rb":"blackrook.gif",
  22.     "Rw":"whiterook.gif",
  23.     "white_tile":"white.gif"
  24.     }
  25.  
  26. class ChessBoard:
  27.     count = 0 # This is the counter to keep track of moves
  28.     def __init__(self):
  29.         self.objectboard = self.form_board()
  30.        
  31.     def __str__(self):
  32.         string = ''
  33.         self.symbolboard = self.draw_board(self.objectboard.T) # Transpose is necessary to make the board as we are accustomed to
  34.         for i in reversed(range(8)): # It is reversed so that white is at the bottom
  35.             string += str(self.symbolboard[i])  + '\n'
  36.         return string
  37.        
  38.     def show_board(self, symbolboard):
  39.         window = tk.Tk()
  40.         canvas = tk.Canvas(width = board_width, height = board_height)
  41.         canvas.pack()
  42.         images = {}
  43.         for image_file_name in DICT:
  44.             f = os.path.join(pic_dir, DICT[image_file_name])
  45.             if not os.path.exists(f):
  46.                 print("Error: Cannot find image file: %s at %s - aborting"%(DICT[image_file_name], f))
  47.                 exit(-1)
  48.             images[image_file_name]= tk.PhotoImage(file=f)
  49.         for j in range(8):
  50.             y = j * tile_width
  51.             for i in range(8):
  52.                 x = i * tile_width
  53.                 if (i % 2 ==  ((1 + j) % 2)):  
  54.                     tile = images['black_tile']
  55.                 else:
  56.                     tile = images['white_tile']
  57.                 canvas.create_image(x, y, anchor = tk.NW,  image=tile)
  58.         for j in (range(8)):
  59.             for i in (range(8)):
  60.                 piece = symbolboard[i][j]
  61.                 if piece == '0 ':
  62.                     continue  #  There is no piece on this tile
  63.                 tile = images[piece]
  64.                 x = j * tile_width
  65.                 y = (7 - i) * tile_width
  66.                 canvas.create_image(x, y, anchor=tk.NW,  image = tile)
  67.         window.mainloop()
  68.  
  69.     def form_board(self): # Forms the board and puts the pieces on the respective positions
  70.         board = np.zeros((8,8), dtype = object)
  71.         # Now we should put the pieces on the board
  72.         WhiteRook1 = Rook(0, 0, 'w', board)
  73.         WhiteRook2 = Rook(7, 0, 'w', board)
  74.         WhiteKnight1 = Knight(1, 0, 'w', board)
  75.         WhiteKnight2 = Knight(6, 0, 'w', board)
  76.         WhiteBishop1 = Bishop(2, 0, 'w', board)
  77.         WhiteBishop2 = Bishop(5, 0, 'w', board)
  78.         WhiteQueen = Queen(3, 0, 'w', board)
  79.         WhiteKing = King(4, 0, 'w', board)
  80.         # Now we should put the pawns
  81.         for i in range(8):
  82.             exec("WPawn" + str(i+1)  + "= Pawn(i, 1, 'w', board)")  
  83.         # This syntax is for changing variable names
  84.         # Now put the black pieces
  85.         BlackRook1 = Rook(0, 7, 'b', board)
  86.         BlackRook2 = Rook(7, 7, 'b', board)
  87.         BlackKnight1 = Knight(1, 7, 'b', board)
  88.         BlackKnight2 = Knight(6, 7, 'b', board)
  89.         BlackBishop1 = Bishop(2, 7, 'b', board)
  90.         BlackBishop2 = Bishop(5, 7, 'b', board)
  91.         BlackQueen = Queen(3, 7, 'b', board)
  92.         BlackKing = King(4, 7, 'b', board)
  93.         # Now we should put the pawns
  94.         for i in range(8):
  95.             exec("BPawn" + str(i+1)  + "= Pawn(i, 6, 'b', board)")  
  96.         return board
  97.        
  98.     def draw_board(self, board):
  99.         func_sym_col = np.vectorize(self.retrieve_piece)
  100.         symbolic_board = func_sym_col(board)
  101.         return symbolic_board
  102.        
  103.     def retrieve_piece(self, piece):
  104.         if isinstance(piece, ChessPiece):
  105.             return str(piece.symbol+piece.color)
  106.         else:
  107.             return '0 '
  108.            
  109.     def rules(self, piece, i, j, m, n):
  110.         board = self.objectboard
  111.         #symboard = self.draw_board(board)
  112.         if ((self.__class__.count % 2) == 0):
  113.             if (piece.color == 'b'):
  114.                 raise Exception('It is Whites turn to play')
  115.         else:
  116.             if (piece.color == 'w'):
  117.                 raise Exception('It is Blacks turn to play')
  118.         piece_type = piece.symbol # Rules depend on the piece
  119.         # Implement check
  120.         check_new_pos = 0 # We should modify this write a loop over other pieces
  121.         opponent_king = 0
  122.         auxboard = []
  123.        
  124.         if ((m - i) >= 0):
  125.             check1 = 1
  126.         else:
  127.             check1 = 0
  128.            
  129.         if ((n - j) >= 0):
  130.             check2 = 1
  131.         else:
  132.             check2 = 0
  133.        
  134.         if piece_type == 'K':
  135.             if (abs(i - m) > 1):
  136.                 raise Exception('This is not a valid move for the King')
  137.             elif (abs(j - n) > 1) :
  138.                 raise Exception('This is not a valid move for the King')
  139.             elif check_new_pos:
  140.                 raise Exception('The King cannot move to a threatened square!!!')
  141.             elif opponent_king:
  142.                 raise Exception('You cannot go too close to the opponent king')
  143.                
  144.         elif piece_type == 'Q':
  145.             if not ((abs((i - m) / (j - n)) == 1) or ((i - m) == 0) or ((j - n) == 0)):
  146.                 raise Exception('The queen cannot move like this')
  147.             if (i - m) == 0:
  148.                 if check2:
  149.                     auxboard = board[i][j+1:n]
  150.                 else:
  151.                     auxboard = board[i][n+1:j]
  152.             elif (j - n) == 0:
  153.                 if check1:
  154.                     auxboard = board[i+1:m][j]
  155.                 else:
  156.                     auxboard = board[m+1:i][j]
  157.             else:
  158.                 if check1 and check2:
  159.                     for ct in range(m - i - 1):
  160.                         auxboard.append(board[i + 1 + ct][j + 1 + ct])
  161.                 elif check1 and (not check2):
  162.                     for ct in range(m - i  - 1):
  163.                         auxboard.append(board[i + 1 + ct][j - 1 - ct])
  164.                 elif (not check1) and check2:
  165.                     for ct in range(i - m - 1):
  166.                         auxboard.append(board[i - 1 - ct][j + 1 + ct])
  167.                 elif (not check1) and (not check2):
  168.                     for ct in range(i - m - 1):
  169.                         auxboard.append(board[i - 1 - ct][j - 1 - ct])
  170.             if not (all(p == 0 for p in auxboard)):
  171.                 raise Exception('The path is obscured')
  172.                
  173.         elif piece_type == 'R':
  174.             if not (((i - m) == 0) or ((j - n) == 0)):
  175.                 raise Exception('The rook cannot move like this')
  176.             if (i - m) == 0:
  177.                 if check2:
  178.                     auxboard = board[i][j+1:n]
  179.                 else:
  180.                     auxboard = board[i][n+1:j]
  181.             elif (j - n) == 0:
  182.                 if check1:
  183.                     auxboard = board[i+1:m][j]
  184.                 else:
  185.                     auxboard = board[m+1:i][j]
  186.             if not (all(p == 0 for p in auxboard)):
  187.                 raise Exception('The path is obscured')
  188.  
  189.         elif piece_type == 'B':
  190.             if not (abs((i - m) / (j - n)) == 1):
  191.                 raise Exception('The bishop cannot move like this')
  192.             if check1 and check2:
  193.                 for ct in range(m - i - 1):
  194.                     auxboard.append(board[i + 1 + ct][j + 1 + ct])
  195.             elif check1 and (not check2):
  196.                 for ct in range(m - i  - 1):
  197.                     auxboard.append(board[i + 1 + ct][j - 1 - ct])
  198.             elif (not check1) and check2:
  199.                 for ct in range(i - m - 1):
  200.                     auxboard.append(board[i - 1 - ct][j + 1 + ct])
  201.             elif (not check1) and (not check2):
  202.                 for ct in range(i - m - 1):
  203.                     auxboard.append(board[i - 1 - ct][j - 1 - ct])
  204.             if not (all(p == 0 for p in auxboard)):
  205.                 raise Exception('The path is obscured')
  206.         elif piece_type == 'N': # The path may be obscured this time
  207.             if not (((abs(i - m) == 2) and (abs(j - n) == 1)) or  ((abs(i - m) == 1) and (abs(j - n) == 2))):
  208.                 raise Exception('The knight cannot move like this')
  209.                
  210.         elif piece_type == 'P':
  211.             if piece.color == 'w':
  212.                 if piece.count == 0:
  213.                     if not(((n - j) == 2) or ((n - j) == 1) and ((i - m) == 0)):
  214.                         raise Exception('The pawn cannot move like this')
  215.                 elif piece.count != 0:
  216.                     if not((n - j) == 1):
  217.                         raise Exception('The pawn cannot move like this')
  218.             else:
  219.                 if piece.count == 0:
  220.                     if not(((n - j) == -2) or ((n - j) == -1) and ((i - m) == 0)):
  221.                         raise Exception('The pawn cannot move like this')
  222.                 elif piece.count != 0:
  223.                     if not((n - j) == -1):
  224.                         raise Exception('The pawn cannot move like this')
  225.          
  226.         # Implement one cannot move to a square containing same color piece
  227.         if board[m][n] != 0: # There is a piece in the final position
  228.             if board[i][j].color == board[m][n].color:# Two pieces are of the same color
  229.                 raise Exception("You cannot go to your own pieces location")
  230.             elif board[m][n].symbol == 'K':# The opponent king is in the location
  231.                 raise Exception("You cannot eat the KING")
  232.         if ((piece_type == 'P') or (piece_type == 'K')):
  233.             piece.count += 1
  234.         return 1
  235.        
  236.     def move(self, position):
  237.         # These two strings are for board coordinates
  238.         letstr = 'abcdefgh'
  239.         numstr = '12345678'
  240.         board = self.objectboard
  241.         if not (len(position) == 4):
  242.             raise ValueError('The position string should consist of 4 characters');
  243.         # Get the final and initial positions
  244.         initial_pos = position[:2]
  245.         final_pos = position[-2:]
  246.         # First perform the checks
  247.         if not (str == type(initial_pos) and (str == type(final_pos))):     # Check if the arguments are strings
  248.             raise TypeError('The supplied positions should be strings!')
  249.         elif not ((initial_pos[0] in letstr) and (initial_pos[1] in numstr)): # Check if they fulfill the condition to be on the board
  250.             raise ValueError('The initial position values should be between a1 and h8')
  251.         elif not ((final_pos[0] in letstr) and (final_pos[1] in numstr)): # Check if they fulfill the condition to be on the board
  252.             raise ValueError('The final position values should be between a1 and h8')
  253.         elif initial_pos == final_pos:
  254.             raise ValueError('Final position should be different from the initial position')
  255.         # Now determine if there is a piece on the initial square
  256.         i = letstr.index(initial_pos[0]) ; j = numstr.index(initial_pos[1]) # Numerical initial position
  257.         m = letstr.index(final_pos[0]); n = numstr.index(final_pos[1]) # Numerical final position
  258.         if not (isinstance(board[i][j], ChessPiece)):
  259.             raise Exception('There is no chess piece here')
  260.         piece = board[i][j]
  261.         if self.rules(piece, i, j, m, n) != 1:
  262.             raise('This move is not allowed')
  263.         # Move the piece on the chessboard
  264.         piece.movepiece(i, j, m, n, board)
  265.         self.__class__.count += 1 # Increment the counter after each allowed move
  266.  
  267. class ChessPiece: # This is the base class, all the other specific pieces inherit this class.
  268.     def __init__(self, x, y, color):
  269.         if not ((int == type(x)) and (int == type(y))):
  270.             raise TypeError(' x and y should be integers!!')
  271.         elif not ((x in range(8)) and (y in range(8))):
  272.             raise ValueError('x and y positions should be between 0 and 7 inclusive')
  273.         elif not ((str == type(color)) and (color in 'wb')):
  274.             raise ValueError('Color should be "w" or "b"')
  275.         self.pos_x = x
  276.         self.pos_y = y
  277.         self.color = color
  278.         # IMPLEMENT PROMOTION HERE
  279.     def movepiece(self, i, j, m, n, chessboard):
  280.         self.pos_x = i
  281.         self.pos_y = j
  282.         chessboard[i][j] = 0 # Set the previous position to be zero
  283.         chessboard[m][n] = self
  284.  
  285. class King(ChessPiece):
  286.         def __init__(self, x, y, color, chessboard):
  287.             ChessPiece.__init__(self, x, y, color)
  288.             self.symbol = 'K'
  289.             self.count = 0
  290.             chessboard[self.pos_x][self.pos_y] = self
  291.  
  292. class Queen(ChessPiece):
  293.         def __init__(self, x, y, color, chessboard):
  294.             ChessPiece.__init__(self, x, y, color)
  295.             self.symbol = 'Q'
  296.             chessboard[self.pos_x][self.pos_y] = self
  297.  
  298. class Rook(ChessPiece):
  299.         def __init__(self, x, y, color, chessboard):
  300.             ChessPiece.__init__(self, x, y, color) 
  301.             self.symbol = 'R'
  302.             chessboard[self.pos_x][self.pos_y] = self
  303.  
  304. class Bishop(ChessPiece):
  305.         def __init__(self, x, y, color, chessboard):
  306.             ChessPiece.__init__(self, x, y, color)
  307.             self.symbol = 'B'
  308.             chessboard[self.pos_x][self.pos_y] = self
  309.            
  310. class Knight(ChessPiece):
  311.         def __init__(self, x, y, color, chessboard):
  312.             ChessPiece.__init__(self, x, y, color)
  313.             self.symbol = 'N'
  314.             chessboard[self.pos_x][self.pos_y] = self
  315.            
  316. class Pawn(ChessPiece):
  317.         def __init__(self, x, y, color, chessboard):
  318.             ChessPiece.__init__(self, x, y, color)
  319.             self.symbol = 'P'
  320.             self.count = 0 # To keep track if it just started moving
  321.             chessboard[self.pos_x][self.pos_y] = self
  322.  
  323. # These are auxiliary functions
  324. ####################################################################
  325. # ACTUAL CODE STARTS HERE
  326. chessboard = ChessBoard()
  327. print(chessboard)
  328. chessboard.move('e2e4')
  329. print(chessboard)
  330. chessboard.move('e7e5')
  331. print(chessboard)
  332. chessboard.move('d1f3')
  333. print(chessboard)
  334. chessboard.move('b8c6')
  335. print(chessboard)
  336. chessboard.show_board(chessboard.symbolboard)
  337. # Already mate here
  338. chessboard.move('f3f7')
  339. print(chessboard)
  340. chessboard.move('f8c5')
  341. print(chessboard)
  342. chessboard.move('h1h4')
  343. print(chessboard)
RAW Paste Data