Advertisement
onexiv

Check is 50% done

Mar 9th, 2024
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 20.38 KB | None | 0 0
  1. class ChessGame:
  2. def __init__(self):
  3. self.board = self.initialize_board()
  4. self.current_player = 'White'
  5. self.kings = [ ['e1', 'White'], ['e8', 'Black'] ]
  6.  
  7. def initialize_board(self):
  8. # Initialize an empty 8x8 chessboard with pieces in their starting positions
  9. board = [[None for _ in range(8)] for _ in range(8)]
  10.  
  11. # Place white pieces
  12. board[0] = [['♖', 'R', 'Black'], ['♘', 'N', 'Black'], ['♗', 'B', 'Black'], ['♕', 'Q', 'Black'], ['♔', 'K', 'Black'], ['♗', 'B', 'Black'], ['♘', 'N', 'Black'], ['♖', 'R', 'Black']]
  13. board[1] = [['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black'], ['♙', 'P', 'Black']]
  14.  
  15. # Place black pieces
  16. board[7] = [['♜', 'r', 'White'], ['♞', 'n', 'White'], ['♝', 'b', 'White'], ['♛', 'q', 'White'], ['♚', 'k', 'White'], ['♝', 'b', 'White'], ['♞', 'n', 'White'], ['♜', 'r', 'White']]
  17. board[6] = [['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White'], ['♟', 'p', 'White']]
  18.  
  19. return board
  20.  
  21. def print_board(self):
  22. # Print the current state of the chessboard with positions revealed
  23. print(" +------------------------ A +")
  24. for row in range(8):
  25. row_display = f"{8 - row} | "
  26. for col in range(8):
  27. if self.board[row][col] is not None:
  28. piece_symbol = self.board[row][col][0]
  29. else:
  30. piece_symbol = '.'
  31. row_display += f" {piece_symbol} "
  32. row_display += " |"
  33. print(row_display)
  34. print(" +------------------------ a +")
  35.  
  36. def capture_piece(self, row, col, moving_piece):
  37. # Remove the piece at the specified position from the board if it belongs to the opposing player
  38. if self.board[row][col] is not None:
  39. self.board[row][col] = None
  40.  
  41. def move_piece(self, piece, start_row, start_col, end_row, end_col):
  42. # Move the piece from start position to end position
  43. if self.board[start_row][start_col][1] == piece:
  44. self.board[end_row][end_col] = self.board[start_row][start_col]
  45. self.board[start_row][start_col] = ['.', '.', '.']
  46.  
  47. def convert_position(self, position):
  48. # Convert algebraic notation to array indices
  49. row = 8 - int(position[1])
  50. col = ord(position[0]) - ord('a')
  51. return row, col
  52.  
  53. def is_valid_move(self, piece, start_row, start_col, end_row, end_col):
  54. # Check if the move is within the bounds of the board
  55. if not (0 <= start_row < 8 and 0 <= start_col < 8 and 0 <= end_row < 8 and 0 <= end_col < 8):
  56. return False
  57.  
  58. # Check if there is a piece at the starting position
  59. if self.board[start_row][start_col] is None:
  60. return False
  61.  
  62. # opponent_color = 'Black' if self.board[start_row][start_col][2] == 'White' else 'White'
  63. # if self.is_check(opponent_color):
  64. # return False # Move leads to opponent's king being in check
  65. # Check for obstruction in the path
  66. if piece in ['R', 'r', 'Q', 'q']: # Rook or Queen
  67. if start_row == end_row: # Horizontal move
  68. delta_col = 1 if end_col > start_col else -1
  69. for col in range(start_col + delta_col, end_col, delta_col):
  70. if self.board[start_row][col] is None:
  71. self.board[start_row][col] = ['.', '.', '.']
  72. elif self.board[start_row][col][2] == self.board[start_row][start_col][2]:
  73. return False # Obstruction found
  74. elif end_col != col and self.board[end_row][col][2] != self.board[start_row][start_col][2]:
  75. return False # Obstruction found
  76. elif end_col == col and self.board[end_row][col][2] != self.board[start_row][start_col][2]:
  77. return True # Obstruction found
  78. return True
  79. elif start_col == end_col: # Vertical move
  80. delta_row = 1 if end_row > start_row else -1
  81. for row in range(start_row + delta_row, end_row, delta_row):
  82. if self.board[row][start_col] is None:
  83. self.board[row][start_col] = ['.', '.', '.']
  84. elif self.board[row][start_col][2] == self.board[start_row][start_col][2]:
  85. return False # Obstruction found
  86. elif end_row != row and self.board[row][start_col][2] != self.board[start_row][start_col][2]:
  87. return False # Obstruction found
  88. elif end_row == row and self.board[row][start_col][2] != self.board[start_row][start_col][2]:
  89. return True # Obstruction found
  90. return True
  91.  
  92. if piece in ['B', 'b', 'Q', 'q']: # Bishop or Queen
  93. delta_row = end_row - start_row
  94. delta_col = end_col - start_col
  95. if abs(delta_row) == abs(delta_col): # Diagonal move
  96. row_step = 1 if start_row < end_row else -1
  97. col_step = 1 if start_col < end_col else -1
  98. row = (start_row + row_step) % 8
  99. col = (start_col + col_step) % 8
  100. check_row = row
  101. check_col = col
  102. while row != 7 and col != 7:
  103. if self.board[row][col] is None:
  104. self.board[row][col] = ['.', '.', '.']
  105. elif self.board[row][col][1].lower() == 'k':
  106. print("Check!")
  107. return True
  108. elif self.board[row][col][2] == self.board[start_row][start_col][2]:
  109. row_step = 1 if start_row > end_row else -1
  110. col_step = 1 if start_col > end_col else -1
  111. row = abs(row + row_step) % 8
  112. col = abs(col + col_step) % 8
  113.  
  114. row_step = 1 if start_row < end_row else -1
  115. col_step = 1 if start_col < end_col else -1
  116. row = (start_row + row_step) % 8
  117. col = (start_col + col_step) % 8
  118. check_row = row
  119. check_col = col
  120. while row != end_row and col != end_col:
  121. if self.board[row][col] is None:
  122. self.board[row][col] = ['.', '.', '.']
  123. elif self.board[row][col][2] == self.board[start_row][start_col][2]:
  124. row_step = 1 if start_row > end_row else -1
  125. col_step = 1 if start_col > end_col else -1
  126. elif self.board[row][col][2] == self.board[start_row][start_col][2]:
  127. return False # Obstruction found
  128. elif row == end_row and self.board[row][col][2] == self.board[start_row][start_col][2]:
  129. return False # Obstruction found
  130. elif row != end_row and self.board[row][col][2] == self.board[start_row][start_col][2]:
  131. return False # Obstruction found
  132. row = abs(row + row_step) % 8
  133. col = abs(col + col_step) % 8
  134. # Check if there's a piece of the same color at the ending position
  135. if self.board[end_row][end_col] is not None and self.board[end_row][end_col][2] == self.board[start_row][start_col][2]:
  136. return False # Obstruction found
  137.  
  138. if piece == 'N' or piece == 'n': # Knight
  139. # Check if the move is a valid knight move
  140. delta_row = abs(end_row - start_row)
  141. delta_col = abs(end_col - start_col)
  142. if (delta_row == 1 and delta_col == 2) or (delta_row == 2 and delta_col == 1):
  143. if self.board[end_row][end_col] is None:
  144. self.board[end_row][end_col] = ['.','.','.']
  145. if self.board[end_row][end_col][2] == self.board[start_row][start_col][2]:
  146. return False
  147. # Check if the move is a valid knight's move or teleportation
  148. if delta_row == 2 and delta_col == 1:
  149. return True
  150. elif delta_row == 1 and delta_col == 2:
  151. return True
  152. elif delta_row == 1 and delta_col >= 6:
  153. return True
  154. elif delta_row >= 6 and delta_col == 1:
  155. return True
  156. else:
  157. return False
  158.  
  159. # Check for piece-specific move validation
  160. if piece == 'P': # Pawn
  161. # Pawn can move forward two squares from starting position
  162. if start_row == 1 and start_col == end_col and end_row - start_row == 2:
  163. return True
  164. if start_col == end_col and end_row - start_row == 1:
  165. return True
  166. # Pawn can capture diagonally
  167. if self.board[end_row][end_col] is not None and self.board[start_row][start_col][2] != self.board[end_row][end_col][2] and abs(start_col - end_col) == 1 and end_row - start_row == 1:
  168. return True
  169. return False
  170. elif piece == 'p': # Pawn (for black)
  171. # Pawn can move forward two squares from starting position
  172. if start_row == 6 and start_col == end_col and start_row - end_row == 2:
  173. return True
  174. # Similar logic for black pawn
  175. if start_col == end_col and start_row - end_row == 1:
  176. return True
  177. if self.board[end_row][end_col] is not None and abs(start_col - end_col) == 1 and start_row - end_row == 1:
  178. return True
  179. return False
  180. elif piece == 'R' or piece == 'r': # Rook
  181. # Rook moves horizontally or vertically
  182. return start_row == end_row or start_col == end_col
  183. elif piece == 'B' or piece == 'b': # Bishop
  184. # Bishop moves diagonally
  185. return abs(end_row - start_row) == abs(end_col - start_col)
  186. elif piece == 'Q' or piece == 'q': # Queen
  187. # Queen combines rook and bishop moves
  188. return (start_row == end_row or start_col == end_col) or (abs(end_row - start_row) == abs(end_col - start_col))
  189. elif piece == 'K' or piece == 'k': # King
  190. # King moves one square in any direction
  191. return abs(end_row - start_row) <= 1 and abs(end_col - start_col) <= 1
  192. else:
  193. return False # Default: invalid move
  194. # Check if there's a piece of the same color at the ending position
  195. if self.board[end_row][end_col] is not None and self.board[end_row][end_col][2] == self.board[start_row][start_col][2]:
  196. return False
  197.  
  198. return True # Move is valid
  199.  
  200. def is_check(self, piece, start_row, start_col, end_row, end_col):
  201. # Check if the move is within the bounds of the board
  202. if not (0 <= start_row < 8 and 0 <= start_col < 8 and 0 <= end_row < 8 and 0 <= end_col < 8):
  203. return False
  204.  
  205. # Check if there is a piece at the starting position
  206. if self.board[start_row][start_col] is None:
  207. return False
  208.  
  209. # opponent_color = 'Black' if self.board[start_row][start_col][2] == 'White' else 'White'
  210. # if self.is_check(opponent_color):
  211. # return False # Move leads to opponent's king being in check
  212. # Check for obstruction in the path
  213. if piece in ['R', 'r', 'Q', 'q']: # Rook or Queen
  214. if start_row == end_row: # Horizontal move
  215. delta_col = 1 if end_col > start_col else -1
  216. for col in range(start_col + delta_col, end_col, delta_col):
  217. if self.board[start_row][col] is None:
  218. self.board[start_row][col] = ['.', '.', '.']
  219. elif self.board[start_row][col][2] == self.board[start_row][start_col][2]:
  220. return False # Obstruction found
  221. elif end_col != col and self.board[end_row][col][2] != self.board[start_row][start_col][2]:
  222. return False # Obstruction found
  223. elif end_col == col and self.board[end_row][col][2] != self.board[start_row][start_col][2]:
  224. return True # Obstruction found
  225. return True
  226. elif start_col == end_col: # Vertical move
  227. delta_row = 1 if end_row > start_row else -1
  228. for row in range(start_row + delta_row, end_row, delta_row):
  229. if self.board[row][start_col] is None:
  230. self.board[row][start_col] = ['.', '.', '.']
  231. elif self.board[row][start_col][2] == self.board[start_row][start_col][2]:
  232. return False # Obstruction found
  233. elif end_row != row and self.board[row][start_col][2] != self.board[start_row][start_col][2]:
  234. return False # Obstruction found
  235. elif end_row == row and self.board[row][start_col][2] != self.board[start_row][start_col][2]:
  236. return True # Obstruction found
  237. return True
  238.  
  239. if piece in ['B', 'b', 'Q', 'q']: # Bishop or Queen
  240. delta_row = end_row - start_row
  241. delta_col = end_col - start_col
  242. if abs(delta_row) == abs(delta_col): # Diagonal move
  243. row_step = 1 if start_row < end_row else -1
  244. col_step = 1 if start_col < end_col else -1
  245. row = (start_row + row_step) % 8
  246. col = (start_col + col_step) % 8
  247. check_row = row
  248. check_col = col
  249. both_sides = 0
  250. while abs(row) != 7 and abs(col) != 7:
  251. if self.board[row][col] is None:
  252. self.board[row][col] = ['.', '.', '.']
  253. elif self.board[row][col][1].lower() == 'k':
  254. print("Check! * ")
  255. return True
  256. elif self.board[row][col][2] != self.board[start_row][start_col][2]:
  257. both_sides += 1
  258. row_step = 1 if start_row > end_row else -1
  259. col_step = 1 if start_col > end_col else -1
  260. elif self.board[row][col][2] == self.board[start_row][start_col][2]:
  261. both_sides += 1
  262. row_step = 1 if start_row > end_row else -1
  263. col_step = 1 if start_col > end_col else -1
  264. elif (both_sides >= 2):
  265. break
  266. row = (row + row_step) % 8
  267. col = (col + col_step) % 8
  268.  
  269.  
  270. def is_checkmate(self, color):
  271. """
  272. Check if the specified color is in checkmate.
  273. """
  274. # Iterate through all pieces of the specified color
  275. for row in range(8):
  276. for col in range(8):
  277. if self.board[row][col] is not None and self.board[row][col][2] == color:
  278. piece = self.board[row][col][1]
  279. # Generate all possible moves for the piece
  280. for move_row in range(8):
  281. for move_col in range(8):
  282. if self.is_valid_move(piece, row, col, move_row, move_col):
  283. # Apply the move to a copy of the board
  284. temp_board = [row[:] for row in self.board]
  285. temp_board[move_row][move_col] = temp_board[row][col]
  286. temp_board[row][col] = ['.','.','.']
  287.  
  288. # Check if the move leads to a position where the king is still in check
  289. if not self.is_check(color):
  290. return False # Not checkmate
  291. return True # Checkmate
  292.  
  293. def is_stalemate(self, color):
  294. """
  295. Check if the specified color is in stalemate.
  296. """
  297. # Similar to is_checkmate but without the check condition
  298. for row in range(8):
  299. for col in range(8):
  300. if self.board[row][col] is not None and self.board[row][col][2] == color:
  301. piece = self.board[row][col][1]
  302.  
  303. for move_row in range(8):
  304. for move_col in range(8):
  305. if self.is_valid_move(piece, row, col, move_row, move_col):
  306. temp_board = [row[:] for row in self.board]
  307. temp_board[move_row][move_col] = temp_board[row][col]
  308. temp_board[row][col] = ['.','.','.']
  309.  
  310. if not self.is_check(color):
  311. return False # Not stalemate
  312. return True # Stalemate
  313.  
  314. def check_endgame_modes(self, color):
  315. """
  316. Check each move in the endgame against each of the opposition's pieces.
  317. """
  318. endgame_modes = {'Check': 0, 'Checkmate': 0, 'Stalemate': 0}
  319.  
  320. # Iterate through all pieces of the specified color
  321. for row in range(8):
  322. for col in range(8):
  323. if self.board[row][col] is not None and self.board[row][col][2] == color:
  324. piece = self.board[row][col][1]
  325.  
  326. # Generate all possible moves for the piece
  327. for move_row in range(8):
  328. for move_col in range(8):
  329. if self.is_valid_move(piece, row, col, move_row, move_col):
  330. # Apply the move to a copy of the board
  331. temp_board = [row[:] for row in self.board]
  332. temp_board[move_row][move_col] = temp_board[row][col]
  333. temp_board[row][col] = ['.','.','.']
  334.  
  335. # Check if the move results in check, checkmate, or stalemate for the opposing player
  336. if self.is_check(color):
  337. if self.is_checkmate(color):
  338. endgame_modes['Checkmate'] += 1
  339. else:
  340. endgame_modes['Check'] += 1
  341. elif self.is_stalemate(color):
  342. endgame_modes['Stalemate'] += 1
  343. return endgame_modes
  344.  
  345. if __name__ == "__main__":
  346. game = ChessGame()
  347. current_player = 'White' # Start with white player
  348. while True:
  349. game.print_board()
  350. print(f"It's {'White' if current_player == 'White' else 'Black'}'s turn.")
  351.  
  352. move = input("Enter your move (e.g., 'N c2 to d4'): ")
  353. if move.lower() == 'exit':
  354. break
  355.  
  356. move_parts = move.split()
  357. piece = move_parts[0]
  358. start_position = move_parts[1]
  359. end_position = move_parts[3]
  360. start_row, start_col = game.convert_position(start_position)
  361. end_row, end_col = game.convert_position(end_position)
  362.  
  363. # Check if it's the player's piece
  364. if game.board[start_row][start_col] is None or game.board[start_row][start_col][2] != current_player:
  365. print("Invalid Move! It's not your piece.")
  366. continue
  367.  
  368. # if game.check_endgame_modes(current_player):
  369. if game.is_valid_move(piece, start_row, start_col, end_row, end_col):
  370. # game.check_endgame_modes(current_player)
  371. if game.is_check(piece, start_row, start_col, end_row, end_col):
  372. print("Check!")
  373. game.move_piece(piece, start_row, start_col, end_row, end_col)
  374.  
  375. offset = 0
  376. if current_player != 'White':
  377. offset = 1
  378. king_row, king_col = game.convert_position(game.kings[offset][0])
  379. if game.is_valid_move(piece, start_row, start_col, king_row, king_col):
  380. # if game.is_check(piece, end_row, end_col, king_row, king_col):
  381. print("Check!")
  382.  
  383. # Switch player
  384. current_player = 'Black' if current_player == 'White' else 'White'
  385. else:
  386. print("Invalid Move!")
  387.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement