Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import colorama
- import tkinter as tk
- from tkinter import ttk
- class Space(tk.Button):
- color = 0
- inst_num = 0
- def __init__(self, name, root, player=None):
- Space.inst_num += 1
- Space.color += 1
- Space.color += (1 if Space.color % 9 == 0 else 0)
- self.root = root
- self.name = name
- self.player = player
- self.select_move = False
- self.information = {'Name': name, 'Player': C_ABBREVIATIONS[self.player],
- 'Current Space': f'{"H" if Space.inst_num % 8 == 0 else chr(Space.inst_num % 8 + 64)}'
- f'{Space.inst_num // 8 + (0 if Space.inst_num % 8 == 0 else 1)}',
- 'Times Moved': 0, 'Opponents Eaten': 0}
- super().__init__(self.root, image=P_ABBREVIATIONS[self.name], bg=('grey' if Space.color % 2 == 0 else 'white'),
- fg=('black' if player == 'B' else 'grey22'), height=80, width=80, relief='flat')
- class ChessBoard:
- def __init__(self, root):
- colorama.init()
- self.root = root
- self.root.geometry('1920x1080')
- self.root.title('Chess')
- self._init_board()
- self.select_move = False
- self.turn = 'W'
- self.invalid = tk.Label(self.root)
- self.invalid.place(relx=0.5, rely=0.05)
- self.turn_lab = ttk.Button(self.root, text=f'{C_ABBREVIATIONS[self.turn]} player\'s turn.', style='Fun.TButton', width=20,
- state='disabled')
- self.turn_lab.place(relx=0.5, rely=0.02)
- def _init_board(self):
- self.board = [[Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'),
- Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'),
- Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B')],
- [Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'),
- Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B'),
- Space('Pawn', self.root, 'B'), Space('Pawn', self.root, 'B')],
- [Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root),
- Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root)],
- [Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root),
- Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root)],
- [Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root),
- Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root)],
- [Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root),
- Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root), Space('Pawn', self.root)],
- [Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'),
- Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'),
- Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W')],
- [Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'),
- Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W'),
- Space('Pawn', self.root, 'W'), Space('Pawn', self.root, 'W')]]
- for i in self.board:
- for j in i:
- j.place(relx=i.index(j) / 20 + 0.3, rely=self.board.index(i) / 10 + 0.1)
- j['command'] = lambda arg1=j: self._click_space(arg1)
- j.bind('<Enter>', lambda event_, arg=j: self._space_hover(event_, arg))
- j.bind('<Leave>', lambda event: self.info.destroy())
- def _space_hover(self, event, space):
- print(event)
- self.info = tk.Text(self.root, bd=10, relief='groove', height=7, width=25, font='Helvetica 11')
- self.info.tag_configure('bold', font="Helvetica 11 bold")
- self.info.place(relx=0.15, rely=0.2)
- self.info.insert('end', ' BUTTON INFO\n', 'bold')
- for k, v in space.information.items():
- self.info.insert('end', f'{k}: ', 'bold')
- self.info.insert('end', f'{v}\n')
- self.info.configure(state='disabled')
- def _check_valid_move(self, row_from, col_from, row_to, col_to):
- """In charge of calling all the checking"""
- print(f'({row_from}, {col_from}), ({row_to}, {col_to})')
- if self.board[row_to][col_to].player == self.board[row_from][col_from].player:
- return False
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'Castle':
- return self._check_castle(row_from, col_from, row_to, col_to)
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'Horse':
- return self._check_horse(row_from, col_from, row_to, col_to)
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'Bishop':
- return self._check_bishop(row_from, col_from, row_to, col_to)
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'Queen':
- return self._check_queen(row_from, col_from, row_to, col_to)
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'King':
- return self._check_king(row_from, col_from, row_to, col_to)
- elif P_ABBREVIATIONS[self.board[row_from][col_from].name] == 'Pawn':
- return self._check_pawn(row_from, col_from, row_to, col_to)
- def _check_castle(self, row_from, col_from, row_to, col_to): # Checks validity of move input by user in play()
- """Checks validity of move involving a castle"""
- if row_from == row_to: # Horizontal movement
- for i in range(min(col_from + 1, col_to + 1), max(col_from, col_to)):
- if self.board[row_from][i].name == ' ': # Checks that it is all empty spaces in between
- continue
- else:
- return False
- return True
- elif col_from == col_to: # Vertical movement
- print('hi')
- for i in range(min(row_from + 1, row_to + 1), max(row_from, row_to)):
- if self.board[i][col_from].name == ' ': # Checks that it is all empty spaces in between
- print('hello')
- continue
- else:
- return False
- return True
- else:
- return False
- # noinspection PyMethodMayBeStatic
- def _check_horse(self, row_from, col_from, row_to, col_to):
- """Checks validity of move involving a horse"""
- if ((abs(row_from - row_to) == 1) and (abs(col_from - col_to) == 2)) or ((abs(row_from - row_to) == 2) and (abs(col_from - col_to) == 1)):
- return True
- else:
- return False
- def _check_bishop(self, row_from, col_from, row_to, col_to):
- """Checks validity of move involving a bishop"""
- if abs(row_from - row_to) == abs(col_from - col_to):
- direction = (1 if row_from < row_to else -1, 1 if col_from < col_to else -1) # Direction vector
- for i in range(1, abs(col_from - col_to)):
- if self.board[row_from + i * direction[0]][col_from + i * direction[1]].name == ' ': # Checks for empty spaces in between
- continue
- else:
- return False
- return True
- else:
- return False
- def _check_queen(self, row_from, col_from, row_to, col_to):
- """Checks validity of move involving a queen"""
- return self._check_castle(row_from, col_from, row_to, col_to) or self. _check_bishop(row_from, col_from, row_to, col_to)
- # noinspection PyMethodMayBeStatic
- def _check_king(self, row_from, col_from, row_to, col_to):
- """Checks validity of move involving a queen"""
- if ((abs(row_from - row_to) == 1) and (col_from == col_to)) or ((abs(col_from - col_to) == 1) and (row_from == row_to)) or \
- ((abs(row_from - row_to) == 1) and (abs(col_from - col_to) == 1)):
- return True
- else:
- return False
- def _check_pawn(self, row_from, col_from, row_to, col_to):
- """Checks validity of move involving a pawn"""
- turn_check = (True if self.turn == 'W' else False)
- if (row_from - row_to == (1 if turn_check else -1)) and (col_from == col_to) and (self.board[row_to][col_to].name == ' '): # Regular move
- return True
- elif (row_from == (6 if turn_check else 1)) and (row_from - row_to == (2 if turn_check else -2)) and \
- (col_from == col_to) and (self.board[row_to][col_to].name == ' ') and \
- (self.board[row_from + (-1 if turn_check else 1)][col_from].name == ' '): # Two space jump from start
- return True
- elif row_from - row_to == (1 if turn_check else -1) and (abs(col_from - col_to) == 1) and (self.board[row_to][col_to].name != ' '):
- return True # Diagonal eating
- else:
- return False
- def _click_space(self, clicked):
- if not self.select_move:
- if clicked.name == 'Empty' or clicked.player != self.turn:
- self.invalid['text'] = 'Invalid space'
- return
- self.butt_from = clicked
- clicked['relief'] = 'ridge'
- self.from_ = (int(clicked.information['Current Space'][1]) - 1, ord(clicked.information['Current Space'][0]) - 65)
- self.select_move = True
- else:
- self.select_move = False
- self.butt_from['relief'] = 'flat'
- self.to = (int(clicked.information['Current Space'][1]) - 1, ord(clicked.information['Current Space'][0]) - 65)
- self.butt_to = clicked
- if self._check_valid_move(self.from_[0], self.from_[1], self.to[0], self.to[1]):
- self._make_move()
- self.invalid['text'] = ''
- else:
- self.invalid['text'] = 'Invalid space'
- def _make_move(self):
- self.turn = ('W' if self.turn == 'B' else 'B')
- self.turn_lab['text'] = f'{C_ABBREVIATIONS[self.turn]} player\'s turn'
- eat = (0 if self.butt_to.name == ' ' else 1)
- self.butt_to.name = self.butt_from.name
- self.butt_to.player = self.butt_from.player
- self.butt_to.configure(text=self.butt_to.name, fg=self.butt_from['fg'])
- self.butt_to.information.update({'Name': P_ABBREVIATIONS[self.butt_to.name], 'Player': C_ABBREVIATIONS[self.butt_to.player],
- 'Times Moved': self.butt_from.information['Times Moved'] + 1,
- 'Opponents Eaten': self.butt_from.information['Opponents Eaten'] + eat})
- self.butt_from.name = ' '
- self.butt_from.player = None
- self.butt_from.configure(text=self.butt_from.name, relief='flat')
- self.butt_from.information.update({'Name': P_ABBREVIATIONS[self.butt_from.name], 'Player': C_ABBREVIATIONS[self.butt_from.player],
- 'Times Moved': 0, 'Opponents Eaten': 0})
- if __name__ == '__main__':
- master = tk.Tk()
- P_ABBREVIATIONS = {'Pawn': tk.PhotoImage(r'icons\b_pawn.png').subsample(8, 8), '\u265C': 'Castle', '\u2656': 'Castle', '\u265E': 'Horse',
- '\u2658': 'Horse', '\u265D': 'Bishop', '\u2657': 'Bishop', '\u265B': 'Queen', '\u2655': 'Queen', '\u265A': 'King',
- '\u2654': 'King', '\u265F': 'Pawn', '\u2659': 'Pawn', 'Empty': None}
- C_ABBREVIATIONS = {'W': 'White', 'B': 'Black', None: 'None'}
- if __name__ == '__main__':
- Chess = ChessBoard(master)
- master.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement