-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpiece.py
More file actions
164 lines (126 loc) · 5.22 KB
/
piece.py
File metadata and controls
164 lines (126 loc) · 5.22 KB
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
# class represenation of a piece
from enum import Enum
# necessary enum
class PieceColor(Enum):
White = 1
Black = 2
# helper methods
def value(self):
if self == PieceColor.White:
return 1
else: return -1
# you'd be surprised at how useful this is
def opponent(self):
if self == PieceColor.White:
return PieceColor.Black
return PieceColor.White
# another necessary enum
class PieceType(Enum):
Pawn = 1
Bishop = 2
Knight = 3
Rook = 4
Queen = 5
King = 6
# helper methods
def value(self):
if self == PieceType.Pawn:
return 1
elif self == PieceType.Bishop or self == PieceType.Knight:
return 3
elif self == PieceType.Rook:
return 5
elif self == PieceType.Queen:
return 9
elif self == PieceType.King:
return 10000 # arbitrary large number
# our piece only needs to know its type and color
class Piece:
def __init__(self, piece_type: PieceType, piece_color: PieceColor):
self.piece_type = piece_type
self.piece_color = piece_color
# black pieces have negative value
def get_value(self):
return self.piece_type.value() * self.piece_color.value()
# for easy printing
def __str__(self):
return f'{self.piece_color.name} {self.piece_type.name}'
def is_not_friendly_piece(self, other_piece) -> bool:
if not other_piece: return True
return other_piece.piece_color != self.piece_color
# returns a unicode string of the piece for board printing
def symbol(self) -> str:
symbols = {
(PieceType.Pawn, PieceColor.White): "♟︎",
(PieceType.Rook, PieceColor.White): "♜",
(PieceType.Knight, PieceColor.White): "♞",
(PieceType.Bishop, PieceColor.White): "♝",
(PieceType.Queen, PieceColor.White): "♛",
(PieceType.King, PieceColor.White): "♚",
(PieceType.Pawn, PieceColor.Black): "♙",
(PieceType.Rook, PieceColor.Black): "♖",
(PieceType.Knight, PieceColor.Black): "♘",
(PieceType.Bishop, PieceColor.Black): "♗",
(PieceType.Queen, PieceColor.Black): "♕",
(PieceType.King, PieceColor.Black): "♔"
}
return symbols.get((self.piece_type, self.piece_color), '?')
# return's a piece's zobrist index for use in hashing
def zobrist_index(self) -> int:
indices = {
(PieceType.Pawn, PieceColor.White): 0,
(PieceType.Rook, PieceColor.White): 1,
(PieceType.Knight, PieceColor.White): 2,
(PieceType.Bishop, PieceColor.White): 3,
(PieceType.Queen, PieceColor.White): 4,
(PieceType.King, PieceColor.White): 5,
(PieceType.Pawn, PieceColor.Black): 6,
(PieceType.Rook, PieceColor.Black): 7,
(PieceType.Knight, PieceColor.Black): 8,
(PieceType.Bishop, PieceColor.Black): 9,
(PieceType.Queen, PieceColor.Black): 10,
(PieceType.King, PieceColor.Black): 11
}
return indices.get((self.piece_type, self.piece_color))
# for reading FEN
@staticmethod
def from_character(char: str):
char_to_piece = {
'P': (PieceType.Pawn, PieceColor.White),
'R': (PieceType.Rook, PieceColor.White),
'N': (PieceType.Knight, PieceColor.White),
'B': (PieceType.Bishop, PieceColor.White),
'Q': (PieceType.Queen, PieceColor.White),
'K': (PieceType.King, PieceColor.White),
'p': (PieceType.Pawn, PieceColor.Black),
'r': (PieceType.Rook, PieceColor.Black),
'n': (PieceType.Knight, PieceColor.Black),
'b': (PieceType.Bishop, PieceColor.Black),
'q': (PieceType.Queen, PieceColor.Black),
'k': (PieceType.King, PieceColor.Black)
}
piece_type, piece_color = char_to_piece.get(char, (None, None))
if piece_type is None or piece_color is None:
raise ValueError(f"Invalid character for piece: {char}")
return Piece(piece_type, piece_color)
# for printing FEN
def to_character(self) -> str:
piece_to_char = {
(PieceType.Pawn, PieceColor.White): 'P',
(PieceType.Rook, PieceColor.White): 'R',
(PieceType.Knight, PieceColor.White): 'N',
(PieceType.Bishop, PieceColor.White): 'B',
(PieceType.Queen, PieceColor.White): 'Q',
(PieceType.King, PieceColor.White): 'K',
(PieceType.Pawn, PieceColor.Black): 'p',
(PieceType.Rook, PieceColor.Black): 'r',
(PieceType.Knight, PieceColor.Black): 'n',
(PieceType.Bishop, PieceColor.Black): 'b',
(PieceType.Queen, PieceColor.Black): 'q',
(PieceType.King, PieceColor.Black): 'k'
}
return piece_to_char.get((self.piece_type, self.piece_color), '?')
# returns true if matches both color and type
def matches(self, other_piece):
if not other_piece: return False
return self.piece_color == other_piece.piece_color and self.piece_type == other_piece.piece_type