Advertisement
Guest User

PythonChessOngun

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