Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 12aa210

Browse files
Merge pull request victorpreston#4 from atugharajohn/A.John
new chess game project added and remaining projects have been added to project list
2 parents d578d7e + 280c322 commit 12aa210

File tree

17 files changed

+404
-0
lines changed

17 files changed

+404
-0
lines changed

β€Ž0x24-Chess_Game/ChessEngine.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
2+
class GameState:
3+
4+
def __init__(self):
5+
self.board = [
6+
["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
7+
["bp", "bp", "bp", "bp", "bp", "bp", "bp", "bp"],
8+
["--", "--", "--", "--", "--", "--", "--", "--"],
9+
["--", "--", "--", "--", "--", "--", "--", "--"],
10+
["--", "--", "--", "--", "--", "--", "--", "--"],
11+
["--", "--", "--", "--", "--", "--", "--", "--"],
12+
["wp", "wp", "wp", "wp", "wp", "wp", "wp", "wp"],
13+
["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]]
14+
self.moveFunctions = {'p': self.getPawnMoves, 'R': self.getRookMoves, 'N': self.getKnightMoves,
15+
'B': self.getBishopMoves, 'Q': self.getQueenMoves, 'K': self.getKingMoves}
16+
self.whiteToMove = True,
17+
self.moveLog = []
18+
self.whiteKingLocation = (7, 4)
19+
self.blackKingLocation = (0, 4)
20+
self.checkMate = False
21+
self.staleMate = False
22+
23+
def makeMove(self, move):
24+
self.board[move.startRow][move.startCol] = "--"
25+
self.board[move.endRow][move.endCol] = move.pieceMoved
26+
self.moveLog.append(move)
27+
self.whiteToMove = not self.whiteToMove
28+
if move.pieceMoved == "wK":
29+
self.whiteKingLocation = (move.endRow, move.endCol)
30+
elif move.pieceMoved == "bK":
31+
self.blackKingLocation = (move.endRow, move.endCol)
32+
33+
if move.isPawnPromotion:
34+
self.board[move.endRow][move.endCol] = move.pieceMoved[0] + "Q"
35+
36+
37+
def undoMove(self):
38+
if len(self.moveLog) != 0:
39+
move = self.moveLog.pop()
40+
self.board[move.startRow][move.startCol] = move.pieceMoved
41+
self.board[move.endRow][move.endCol] = move.pieceCaptured
42+
self.whiteToMove = not self.whiteToMove
43+
if move.pieceMoved == "wK":
44+
self.whiteKingLocation = (move.startRow, move.startCol)
45+
if move.pieceMoved == "bK":
46+
self.blackKingLocation = (move.startRow, move.startCol)
47+
"""
48+
All move considering checks
49+
"""
50+
def getValidMoves(self):
51+
moves = self.getAllPossibleMoves()
52+
for i in range(len(moves)-1, -1, -1):
53+
self.makeMove(moves[i])
54+
self.whiteToMove = not self.whiteToMove
55+
if self.inCheck():
56+
moves.remove(moves[i])
57+
self.whiteToMove = not self.whiteToMove
58+
self.undoMove()
59+
if len(moves) == 0:
60+
if self.inCheck():
61+
self.checkMate = True
62+
else:
63+
self.staleMate = True
64+
else:
65+
self.checkMate = False
66+
self.staleMate = False
67+
68+
return moves
69+
70+
def inCheck(self):
71+
if self.whiteToMove:
72+
return self.squareUnderAttack(self.whiteKingLocation[0], self.whiteKingLocation[1])
73+
else:
74+
return self.squareUnderAttack(self.blackKingLocation[0], self.blackKingLocation[1])
75+
76+
def squareUnderAttack(self, r, c):
77+
self.whiteToMove = not self.whiteToMove
78+
oppMoves = self.getAllPossibleMoves()
79+
self.whiteToMove = not self.whiteToMove
80+
for move in oppMoves:
81+
if move.endRow == r and move.endCol == c:
82+
return True
83+
return False
84+
85+
86+
87+
88+
"""
89+
All move without considering checks
90+
"""
91+
def getAllPossibleMoves(self):
92+
moves = []
93+
for r in range(len(self.board)):
94+
for c in range(len(self.board[r])):
95+
turn = self.board[r][c][0] # b or w based on turn
96+
if(turn == 'w' and self.whiteToMove) or (turn == 'b' and not self.whiteToMove):
97+
piece = self.board[r][c][1]
98+
self.moveFunctions[piece](r,c, moves)
99+
return moves
100+
101+
102+
def getPawnMoves(self, r, c, moves):
103+
if self.whiteToMove:
104+
if self.board[r-1][c] == "--":
105+
moves.append(Move((r, c),(r-1, c), self.board))
106+
if r == 6 and self.board[r-2][c] == "--":
107+
moves.append(Move((r, c),(r-2, c), self.board))
108+
if c-1 >= 0:
109+
if self.board[r-1][c-1][0] == 'b':
110+
moves.append(Move((r, c),(r-1, c-1), self.board))
111+
if c+1 <= 7:
112+
if self.board[r-1][c+1][0] == 'b':
113+
moves.append(Move((r, c),(r-1, c+1), self.board))
114+
115+
else:
116+
if self.board[r+1][c] == "--":
117+
moves.append(Move((r, c),(r+1, c), self.board))
118+
if r == 1 and self.board[r+2][c] == "--":
119+
moves.append(Move((r, c),(r+2, c), self.board))
120+
if c-1 >= 0:
121+
if self.board[r+1][c-1][0] == 'w':
122+
moves.append(Move((r, c),(r+1, c-1), self.board))
123+
if c+1 <= 7:
124+
if self.board[r+1][c+1][0] == 'w':
125+
moves.append(Move((r, c),(r+1, c+1), self.board))
126+
127+
def getRookMoves(self, r, c, moves):
128+
directions = ((-1, 0), (0, -1), (1, 0), (0, 1))
129+
enemyColor = "b" if self.whiteToMove else "w"
130+
for d in directions:
131+
for i in range(1, 8):
132+
endRow = r + d[0] * i
133+
endCol = c + d[1] * i
134+
if 0 <= endRow < 8 and 0 <= endCol < 8:
135+
endPiece = self.board[endRow][endCol]
136+
if endPiece == "--":
137+
moves.append(Move((r,c), (endRow, endCol), self.board))
138+
elif endPiece[0] == enemyColor:
139+
moves.append(Move((r,c), (endRow, endCol), self.board))
140+
break
141+
else:
142+
break
143+
else:
144+
break
145+
146+
def getKnightMoves(self, r,c,moves):
147+
knightMoves = ((-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2,1))
148+
allyColor = "w" if self.whiteToMove else "b"
149+
for m in knightMoves:
150+
endRow = r + m[0]
151+
endCol = c + m[1]
152+
if 0 <= endRow < 8 and 0 <= endCol < 8:
153+
endPiece = self.board[endRow][endCol]
154+
if endPiece[0] != allyColor:
155+
moves.append(Move((r,c), (endRow, endCol), self.board))
156+
157+
def getBishopMoves(self, r,c,moves):
158+
directions = ((-1, -1), (-1, 1), (1, -1), (1, 1))
159+
enemyColor = "b" if self.whiteToMove else "w"
160+
for d in directions:
161+
for i in range(1, 8):
162+
endRow = r + d[0] * i
163+
endCol = c + d[1] * i
164+
if 0 <= endRow < 8 and 0 <= endCol < 8:
165+
endPiece = self.board[endRow][endCol]
166+
if endPiece == "--":
167+
moves.append(Move((r,c), (endRow, endCol), self.board))
168+
elif endPiece[0] == enemyColor:
169+
moves.append(Move((r,c), (endRow, endCol), self.board))
170+
break
171+
else:
172+
break
173+
else:
174+
break
175+
176+
def getQueenMoves(self, r,c,moves):
177+
self.getRookMoves(r, c, moves)
178+
self.getBishopMoves(r, c, moves)
179+
180+
def getKingMoves(self, r,c,moves):
181+
kingMoves = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1,1) )
182+
allyColor = "w" if self.whiteToMove else "b"
183+
for i in range(8):
184+
endRow = r + kingMoves[i][0]
185+
endCol = c + kingMoves[i][1]
186+
if 0 <= endRow < 8 and 0 <= endCol < 8:
187+
endPiece = self.board[endRow][endCol]
188+
if endPiece[0] != allyColor:
189+
moves.append(Move((r,c), (endRow, endCol), self.board))
190+
class Move():
191+
192+
ranksToRow = {"1": 7, "2": 6, "3": 5, "4": 4,
193+
"5": 3, "6": 2, "7": 1, "8": 0}
194+
rowsToRanks = {v: k for k, v in ranksToRow.items()}
195+
filesToCols = {"a": 0, "b": 1, "c": 2, "d": 3,
196+
"e": 4, "f": 5, "g": 6, "h": 7}
197+
colsToFiles = {v: k for k, v in filesToCols.items()}
198+
199+
def __init__(self, startSq, endSq, board):
200+
self.startRow = startSq[0]
201+
self.startCol = startSq[1]
202+
self.endRow = endSq[0]
203+
self.endCol = endSq[1]
204+
self.pieceMoved = board[self.startRow][self.startCol]
205+
self.pieceCaptured = board[self.endRow][self.endCol]
206+
self.isPawnPromotion = False
207+
if (self.pieceMoved == 'wp' and self.endRow == 0) or (self.pieceMoved == 'bp' and self.endRow == 7):
208+
self.isPawnPromotion = True
209+
self.moveID = self.startRow * 1000 + self.startCol * 100 + self.endRow * 10 + self.endCol
210+
211+
def __eq__(self, other):
212+
if isinstance(other, Move):
213+
return self.moveID == other.moveID
214+
return False
215+
216+
217+
def getChessNotation(self):
218+
return self.getRankFile(self.startRow, self.startCol) + self.getRankFile(self.endRow, self.endCol)
219+
220+
def getRankFile(self, r, c):
221+
return self.colsToFiles[c] + self.rowsToRanks[r]
222+

β€Ž0x24-Chess_Game/ChessGame.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import pygame as p
2+
import ChessEngine
3+
4+
WIDTH = HEIGHT = 512
5+
DIMENSIONS = 8
6+
SQ_SIZE = HEIGHT// DIMENSIONS
7+
MAX_FPS = 15
8+
IMAGES = {}
9+
10+
def loadImages():
11+
pieces = ['wp', 'wR', 'wN', 'wB', 'wQ', 'wK', 'bp', 'bR', 'bN', 'bB', 'bQ', 'bK' ]
12+
for piece in pieces:
13+
IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQ_SIZE, SQ_SIZE))
14+
15+
def main():
16+
p.init()
17+
screen = p.display.set_mode((WIDTH, HEIGHT))
18+
clock = p.time.Clock()
19+
screen.fill(p.Color("white"))
20+
gs = ChessEngine.GameState()
21+
validMoves = gs.getValidMoves()
22+
moveMade = False
23+
animate = False
24+
loadImages()
25+
running = True
26+
sqSelected = ()
27+
playerClicks = []
28+
gameOver = False
29+
while running:
30+
for e in p.event.get():
31+
if e.type == p.QUIT:
32+
running = False
33+
elif e.type == p.MOUSEBUTTONDOWN:
34+
if not gameOver:
35+
location = p.mouse.get_pos()
36+
col = location[0]//SQ_SIZE
37+
row = location[1]//SQ_SIZE
38+
if sqSelected == (row, col):
39+
sqSelected = ()
40+
playerClicks = []
41+
else:
42+
sqSelected = (row, col)
43+
playerClicks.append(sqSelected)
44+
if len(playerClicks) == 1 and (gs.board[row][col] == "--"):
45+
sqSelected = ()
46+
playerClicks = []
47+
if len(playerClicks) == 2:
48+
move = ChessEngine.Move(playerClicks[0], playerClicks[1], gs.board)
49+
for i in range(len(validMoves)):
50+
if move == validMoves[i]:
51+
gs.makeMove(move)
52+
moveMade = True
53+
animate = True
54+
sqSelected = ()
55+
playerClicks = []
56+
if not moveMade:
57+
playerClicks = [sqSelected]
58+
elif e.type == p.KEYDOWN:
59+
if e.key == p.K_z:
60+
gs.undoMove()
61+
moveMade = True
62+
animate = False
63+
if e.key == p.K_r:
64+
gs = ChessEngine.GameState()
65+
validMoves = gs.getValidMoves()
66+
sqSelected = ()
67+
playerClicks = []
68+
moveMade = False
69+
animate = False
70+
if moveMade:
71+
if animate:
72+
animatedMoves(gs.moveLog[-1], screen, gs.board,clock)
73+
validMoves = gs.getValidMoves()
74+
moveMade = False
75+
animate = False
76+
drawGameState(screen, gs, validMoves, sqSelected)
77+
if gs.checkMate:
78+
gameOver = True
79+
if gs.whiteToMove:
80+
drawText(screen, 'Black wins by checkmate')
81+
else:
82+
drawText(screen, 'White wins by checkmate')
83+
elif gs.staleMate:
84+
gameOver =True
85+
drawText(screen, 'Stalemate');
86+
clock.tick(MAX_FPS)
87+
p.display.flip()
88+
89+
def highlightSquares(screen, gs, validMoves, sqSelected):
90+
if sqSelected != ():
91+
r, c = sqSelected
92+
if gs.board[r][c][0] == ('w' if gs.whiteToMove else 'b'):
93+
s = p.Surface((SQ_SIZE, SQ_SIZE))
94+
s.set_alpha(100)
95+
s.fill(p.Color('blue'))
96+
screen.blit(s, (c*SQ_SIZE, r*SQ_SIZE))
97+
s.fill(p.Color("yellow"))
98+
for moves in validMoves:
99+
if moves.startRow == r and moves.startCol == c:
100+
screen.blit(s, (SQ_SIZE*moves.endCol, SQ_SIZE*moves.endRow))
101+
102+
def drawGameState(screen, gs, validMoves, sqSelected):
103+
drawBoard(screen)
104+
highlightSquares(screen, gs, validMoves, sqSelected)
105+
drawPieces(screen, gs.board)
106+
107+
def drawBoard(screen):
108+
global colors
109+
colors = [p.Color("white"), p.Color("grey")]
110+
for r in range(DIMENSIONS):
111+
for c in range(DIMENSIONS):
112+
color = colors[(r+c) % 2]
113+
p.draw.rect(screen, color, p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
114+
115+
def drawPieces(screen, board):
116+
for r in range(DIMENSIONS):
117+
for c in range(DIMENSIONS):
118+
piece = board[r][c]
119+
if piece != "--":
120+
screen.blit(IMAGES[piece], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
121+
122+
def animatedMoves(move, screen,board, clock):
123+
global colors
124+
dR = move.endRow - move.startRow
125+
dC = move.endCol - move.startCol
126+
framesPerSquare = 5
127+
frameCount = (abs(dR) + abs(dC)) * framesPerSquare
128+
for frame in range(frameCount + 1):
129+
r,c =((move.startRow + dR*frame/frameCount, move.startCol + dC*frame/frameCount))
130+
drawBoard(screen)
131+
drawPieces(screen, board)
132+
color = colors[(move.endRow + move.endCol)%2]
133+
endSquare = p.Rect(move.endCol*SQ_SIZE, move.endRow*SQ_SIZE, SQ_SIZE, SQ_SIZE)
134+
p.draw.rect(screen, color, endSquare)
135+
if move.pieceCaptured != "--":
136+
screen.blit(IMAGES[move.pieceCaptured], endSquare)
137+
138+
screen.blit(IMAGES[move.pieceMoved], p.Rect(c*SQ_SIZE, r*SQ_SIZE, SQ_SIZE, SQ_SIZE))
139+
p.display.flip()
140+
clock.tick(60)
141+
142+
def drawText(screen, text):
143+
font = p.font.SysFont("Helvitca", 32, True, False)
144+
textObject = font.render(text, True, p.Color('Gray'))
145+
textLocation = p.Rect(0, 0, WIDTH, HEIGHT).move(WIDTH/2 - textObject.get_width()/2, HEIGHT/2 - textObject.get_height()/2)
146+
screen.blit(textObject, textLocation)
147+
textObject = font.render(text, True, p.Color("Black"))
148+
screen.blit(textObject, textLocation.move(2,2))
149+
150+
151+
if __name__ == "__main__":
152+
main()

0 commit comments

Comments
(0)

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /