-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChessPieces.py
408 lines (376 loc) · 17.6 KB
/
ChessPieces.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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
from pygame import sprite, image
colNumber = {"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7}
#gives the character, as a string, corresponding to the column num
def colStr(num):
num = int(num)
num = num%8 #deals with negative numbers
if num == 0:
return 'a'
elif num == 1:
return 'b'
elif num == 2:
return 'c'
elif num == 3:
return 'd'
elif num == 4:
return 'e'
elif num == 5:
return 'f'
elif num == 6:
return 'g'
else:
return 'h'
class Piece(sprite.Sprite):
def __init__(self, color, board, col, row):
sprite.Sprite.__init__(self)
self.color = color
self.col = col
self.row = row
self.rect = board.squareDic[self.col+self.row].get_rect()
self.rect.centerx = board.squareDic[self.col+self.row].get_rect().centerx
self.rect.centery = board.squareDic[self.col+self.row].get_rect().centery
self.onBoard = True
board.squareDic[str(col)+str(row)].piece = self
self.hasMoved = False #used for Castling
self.setPic()
# Requires Capture or not isOccupied
def moveTo(self, board, col, row):
board.squareDic[str(col)+str(row)].piece = self
self.col = col
self.row = row
self.hasMoved = True
self.rect = board.squareDic[self.col+self.row].get_rect()
class Rook(Piece): #Rook is a subclass of piece and inherits its attributes and methods
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackRook.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whiteRook.png").convert_alpha()
else:
print "Color issue with Rook"
def __str__(self):
return self.color + " rook"
#returns True or String error message
#requires that currentRow and destRow are numbers
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values below values (X Y) are numerical ints
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
if (currentX == destX and currentY == destY): #doesn't actually move
return (False, "same dest and current loc")
elif destX > 7 or destX < 0 or destY > 7 or destX < 0: #goes off grid
return (False, "off grid")
elif currentX == destX:
if abs(currentY - destY) == 1: #no spaces in between
return (True, "")
elif currentY < destY:
tempY = currentY + 1
while tempY < destY:
if board.isOccupied(destCol, str(tempY)): # col, row
return (False, "Rook cannot leap over other pieces")
tempY +=1
return (True, "")
else: #currentY > destY, need to decrement tempY
tempY = currentY - 1
while tempY > destY:
if board.isOccupied(destCol, tempY): # col, row
return (False, "Rook cannot leap over other pieces.")
tempY -=1
return (True, "")
elif currentY == destY:
numToCheck = abs(currentY - destY) #actually numtoCheck +1
if numToCheck == 1:
return (True, "") #no spaces in between
sList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
i = 0
s = sList[i]
while currentCol != s and destCol != s:
i+=1
s = sList[i]
j = 1
while j < numToCheck:
if board.isOccupied(sList[i+j], destY):
return (False, "This piece cannot leap over other pieces.")
j+=1
return (True, "")
else:
return (False, "not valid rook move")
class Knight(Piece):
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackKnight.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whiteKnight.png").convert_alpha()
else:
print "Color issue with Knight"
def __str__(self):
return self.color + " knight"
#reutrns True or a string error message
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values below values (X Y) are numerical ints
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
if (currentX == destX and currentY == destY): #doesn't actually move
return False, "That's not moving1"
elif destX > 7 or destX < 0 or destY > 7 or destX < 0: #goes off grid
return False, "You cannot move your piece off the grid"
else:
absX = abs(destX-currentX)
absY = abs(destY-currentY)
if absY == 2 and absX == 1 or absY ==1 and absX == 2:
return True, ""
else:
return False, "Knights cannot move in this way"
class Bishop(Piece):
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackBishop.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whiteBishop.png").convert_alpha()
else:
print "Color issue with Bishop"
def __str__(self):
return self.color + " bishop"
# returns True or a string error message
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values below values (X Y) are numerical ints
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
absX = abs(destX-currentX)
absY = abs(destY-currentY)
if (absX == 0 and absY == 0): #doesn't actually move
return False, "That's not moving!"
elif destX > 7 or destX < 0 or destY > 7 or destX < 0: #goes off grid
return False, "You can't move your piece off the grid"
else:
if absX != absY:
return False, "Bishops cannot move in this way"
else: #need to ensure that spaces inbetween are unoccupied
if absX == 1:
return True, "" #no spaces in between
else:
x, y = 1, 1 #y corresponds to row, x corresponds to col
if currentX > destX:
x = -1
if currentY > destY:
y = -1
mag = 1 #magnitude
while mag < absX: #absX = numSpaces inbetween +1
if board.isOccupied(colStr(currentX + mag*x), str(currentY + mag*y)):
return False, "Bishop cannot leap over other pieces."
mag += 1
return True, ""
class Queen(Piece):
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackQueen.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whiteQueen.png").convert_alpha()
else:
print "Color issue with Queen"
def __str__(self):
return self.color + " queen"
# returns True or a string error message
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values below values (X Y) are numerical ints
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
absX = abs(destX-currentX)
absY = abs(destY-currentY)
if (absX == 0 and absY == 0): #doesn't move
return False, "That's not moving!"
elif destX > 7 or destX < 0 or destY > 7 or destX < 0: #goes off grid
return False, "You cannot move your piece off the grid"
else:
if absX != absY: #not valid for bishop, check Rook Moves
if currentX == destX:
if abs(currentY - destY) == 1: #no spaces in between
return True, ""
elif currentY < destY:
tempY = currentY + 1
while tempY < destY:
if board.isOccupied(destCol, str(tempY)): # col, row
return False, "Queen cannot leap over other pieces."
tempY +=1
return True, ""
else: #currentY > destY, need to decrement tempY
tempY = currentY - 1
while tempY > destY:
if board.isOccupied(destCol, tempY): # col, row
return False, "Queen cannot leap over other pieces."
tempY -=1
return True, ""
elif currentY == destY:
numToCheck = abs(currentY - destY) #actually numtoCheck +1
if numToCheck == 1:
return True, "" #no spaces in between
sList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
i = 0
s = sList[i]
while currentCol != s and destCol != s:
i+=1
s = sList[i]
j = 1
while j < numToCheck:
if board.isOccupied(sList[i+j], destY):
return False, "Queen cannot leap over other pieces."
j+=1
return True, "" #moving in X direction with no pieces in between
else:
return False, "Queen cannot move in this way" #not valid rook or bishop move
else: # absX == absY, so moving like a bishop.
#need to ensure that spaces inbetween are unoccupied
if absX == 1:
return True, "" #no spaces in between
else:
x, y = 1, 1 #y corresponds to row, x corresponds to col
if currentX > destX:
x = -1
if currentY > destY:
y = -1
mag = 1 #magnitude
while mag < absX: #absX = numSpaces inbetween +1
if board.isOccupied(colStr(currentX + mag*x), str(currentY + mag*y)):
return False, "Queen cannot leap over other pieces."
mag += 1
return True, ""
class King(Piece):
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackKing.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whiteKing.png").convert_alpha()
else:
print "Color issue with King"
def __str__(self):
return self.color + " king"
#Returns True, or a string error message
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values, below values (X Y) are numerical ints
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
if destX < 0 or destY < 0:
return False, "Not on board"
absX = abs(destX-currentX)
absY = abs(destY-currentY)
if (absX == 0 and absY == 0):
return False, "That's not moving!"
elif destX > 7 or destX < 0 or destY > 7 or destX < 0: #goes off grid
return False, "You can't move your piece off the grid!"
elif absX <= 1 and absY <= 1:
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
return True, ""
else:
return False, "Kings cannot move in this way"
class Pawn(Piece):
def __init__(self, color, board, col):
sprite.Sprite.__init__(self)
self.color = color
self.col = col
self.setPic()
if color == 'black':
self.row = '6'
elif color == 'white':
self.row = '1'
else:
print "Pawn color error"
self.onBoard = True
startSquare = board.squareDic[self.col+self.row]
self.rect = startSquare.get_rect()
startSquare.piece = self
def setPic(self):
if (self.color == 'black'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\BlackPawn.png").convert_alpha()
# convert alpha preserves per pixel transparency
elif (self.color == 'white'):
self.image = image.load("C:\Users\Colleen\Pictures\usedInSomething\whitePawn.png").convert_alpha()
else:
print "Color issue with Pawn"
def __str__(self):
return self.color + " pawn"
#Returns True, or a string error message
def validMove(self, board, currentCol, currentRow, destCol, destRow): #row is y value
#input is string values below values (X Y) are numerical ints
if board.isOccupied(destCol, destRow) and board.squareDic[destCol + destRow].piece.color == self.color:
return False, "Can't capture your own piece"
currentX = colNumber[currentCol]
currentY = int(currentRow)
destX = colNumber[destCol]
destY = int(destRow)
absX = abs(destX - currentX)
if (currentY == destY):
if absX == 0: #doesn't actually move
return False, "That's not moving!"
else:
return False, "Pawns can't move directly sideways!"
elif destX > 7 or destX < 0 or destY > 7 or destY < 0: #goes off grid
return False, "You can't move your piece off the grid!"
#WHITE ALWAYS STARTS IN ROWS ZERO AND 1
elif self.color == 'white':
if destY - currentY <0:
return False, "Pawns can't move backwards!"
elif absX==0:
if board.isOccupied(destCol, destRow):
return False, "Pawn cannot capture directly in front of itself"
if currentY == 1 and destY == 3:
if board.isOccupied(currentCol, 2): #checks square in between
return False, "Pawn cannot jump over a piece"
return True, ""
elif destY == currentY +1:
return True, ""
else:
return False, "Pawns can't move that far"
elif absX == 1 and destY - currentY == 1:
if board.isOccupied(destCol, destRow):
return True, ""
else:
return False, "Pawn can only move that way when capturing"
else:
return False, "This piece can't move that many spaces now."
elif self.color == 'black':
if destY - currentY > 0:
return False, "Pawns can't move backwards!"
elif absX==0:
if board.isOccupied(destCol, destRow):
return False, "Pawn cannot capture directly in front of itself"
if currentY == 6 and destY == 4:
if board.isOccupied(currentCol, 5): #checks square in between
return False, "Pawn cannot jump over a piece"
return True, ""
elif destY == currentY - 1:
return True, ""
else:
return False, "Pawns can't move that far"
elif absX == 1 and destY - currentY == -1:
if board.isOccupied(destCol, destRow):
return (True, "")
else:
return False, "Pawn can only move that way when capturing"
else:
return False, "This piece can't move that many spaces now."
else:
return False, "Color Error"