SHARE
TWEET

ChesswithGUI

a guest Jan 11th, 2016 102 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top