-
Notifications
You must be signed in to change notification settings - Fork 0
/
pieces.py
198 lines (175 loc) · 7.93 KB
/
pieces.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import pygame
from typing import ForwardRef
Board = ForwardRef("Board")
class Piece():
'''A chess piece.'''
piece_id = 0
def __init__(self, piece: pygame.Surface=None, piece_name: str=None, Nonetype=False) -> None:
self.isNone = Nonetype
if Nonetype:
self.color = None
self.type = None
self.piece = None
self.piece_name = None
self.piece_id = None
return
self.color = piece_name[0]
self.type = piece_name[1]
self.piece = piece
self.piece_name = piece_name
self.piece_id = Piece.piece_id
Piece.piece_id += 1
def location(self, board: Board) -> tuple:
'''Get the location of a piece.'''
for i in range(8):
for j in range(8):
if board[j][i].piece_id == self.piece_id:
return (i, j)
# def move(self, board: Board, x: int, y: int) -> None:
# '''Move a piece to a location.'''
# board[y][x] = self
def get_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a piece.'''
# x, y = self.location(board)
moves = set()
if self.type == "K":
moves = self.get_king_moves(board, x, y)
elif self.type == "Q":
moves = self.get_queen_moves(board, x, y)
elif self.type == "R":
moves = self.get_rook_moves(board, x, y)
elif self.type == "B":
moves = self.get_bishop_moves(board, x, y)
elif self.type == "N":
moves = self.get_knight_moves(board, x, y)
elif self.type == "P":
moves = self.get_pawn_moves(board, x, y)
return moves
def get_pawn_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a pawn.'''
moves = set()
if self.color == "w":
if board[y - 1][x] is None: # move forward
moves.add((x, y - 1))
if y == 6 and board[y - 2][x] is None: # move forward 2
moves.add((x, y - 2))
if x > 0 and board[y - 1][x - 1] is not None and board[y - 1][x - 1].color != self.color: # capture left
moves.add((x - 1, y - 1))
if x < 7 and board[y - 1][x + 1] is not None and board[y - 1][x + 1].color != self.color: # capture right
moves.add((x + 1, y - 1))
else:
if board[y + 1][x] is None: # move forward
moves.add((x, y + 1))
if y == 1 and board[y + 2][x] is None: # move forward 2
moves.add((x, y + 2))
if x > 0 and board[y + 1][x - 1] is not None and board[y + 1][x - 1].color != self.color: # capture left
moves.add((x - 1, y + 1))
if x < 7 and board[y + 1][x + 1] is not None and board[y + 1][x + 1].color != self.color: # capture right
moves.add((x + 1, y + 1))
return moves
def get_knight_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a knight.'''
moves = set()
for i, j in ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)): # check all possible moves
if 0 <= x + i < 8 and 0 <= y + j < 8: # if on the board
if board[y + j][x + i] is None or board[y + j][x + i].color != self.color: # if empty or enemy
moves.add((x + i, y + j))
return moves
def get_bishop_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a bishop.'''
moves = set()
for i in range(1, 8): # lower right diagonal
if 0 <= x + i < 8 and 0 <= y + i < 8: # if on the board
if board[y + i][x + i] is None: # if empty
moves.add((x + i, y + i))
elif board[y + i][x + i].color != self.color: # if enemy
moves.add((x + i, y + i))
break
else: # if friendly
break
for i in range(1, 8): # upper right diagonal
if 0 <= x + i < 8 and 0 <= y - i < 8: # if on the board
if board[y - i][x + i] is None: # if empty
moves.add((x + i, y - i))
elif board[y - i][x + i].color != self.color: # if enemy
moves.add((x + i, y - i))
break
else: # if friendly
break
for i in range(1, 8): # lower left diagonal
if 0 <= x - i < 8 and 0 <= y + i < 8: # if on the board
if board[y + i][x - i] is None: # if empty
moves.add((x - i, y + i))
elif board[y + i][x - i].color != self.color: # if enemy
moves.add((x - i, y + i))
break
else: # if friendly
break
for i in range(1, 8): # upper left diagonal
if 0 <= x - i < 8 and 0 <= y - i < 8: # if on the board
if board[y - i][x - i] is None: # if empty
moves.add((x - i, y - i))
elif board[y - i][x - i].color != self.color: # if enemy
moves.add((x - i, y - i))
break
else: # if friendly
break
return moves
def get_rook_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a rook.'''
moves = set()
for i in range(1, 8): # check right
if 0 <= x + i < 8: # if on the board
if board[y][x + i] is None: # if empty
moves.add((x + i, y))
elif board[y][x + i].color != self.color: # if enemy
moves.add((x + i, y))
break
else: # if friendly
break
for i in range(1, 8): # check left
if 0 <= x - i < 8: # if on the board
if board[y][x - i] is None: # if empty
moves.add((x - i, y))
elif board[y][x - i].color != self.color: # if enemy
moves.add((x - i, y))
break
else: # if friendly
break
for i in range(1, 8): # check down
if 0 <= y + i < 8: # if on the board
if board[y + i][x] is None: # if empty
moves.add((x, y + i))
elif board[y + i][x].color != self.color: # if enemy
moves.add((x, y + i))
break
else: # if friendly
break
for i in range(1, 8): # check up
if 0 <= y - i < 8: # if on the board
if board[y - i][x] is None: # if empty
moves.add((x, y - i))
elif board[y - i][x].color != self.color: # if enemy
moves.add((x, y - i))
break
else: # if friendly
break
return moves
def get_queen_moves(self, board: list, x: int, y: int) -> list[tuple]:
'''Get the possible moves for a queen.'''
moves = set()
# queen moves are just the combination of rook and bishop moves
moves.extend(self.get_rook_moves(board, x, y))
moves.extend(self.get_bishop_moves(board, x, y))
return moves
def get_king_moves(self, board: list, x: int, y: int):
'''Get the possible moves for a king.'''
moves = set()
for i, j in ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)): # check all possible moves
if 0 <= x + i < 8 and 0 <= y + j < 8: # if on the board
if board[y + j][x + i] is None or board[y + j][x + i].color != self.color: # if empty or enemy
moves.add((x + i, y + j))
# remove moves that would put the king in check
return moves
p = Piece(Nonetype=True)
print(p.isNone)