-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpMain.py
179 lines (151 loc) · 7.37 KB
/
pMain.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
import pygame as p
import playerGame
import playerMoves
import sys
from multiprocessing import Process, Queue
BOARD_WIDTH = BOARD_HEIGHT = 600
#MOVE_LOG_PANEL_HEIGHT = BOARD_HEIGHT
DIMENSION = 8
SQUARE_SIZE = BOARD_HEIGHT // DIMENSION
MAX_FPS = 20
IMAGES = {}
def loadImages():
pieces = ['wp', 'wR', 'wN', 'wB', 'wK', 'wQ', 'bp', 'bR', 'bN', 'bB', 'bK', 'bQ']
for piece in pieces:
IMAGES[piece] = p.transform.scale(p.image.load("images/" + piece + ".png"), (SQUARE_SIZE, SQUARE_SIZE))
def playerMain():
p.init()
screen = p.display.set_mode((BOARD_WIDTH, BOARD_HEIGHT))
clock = p.time.Clock()
screen.fill(p.Color("white"))
game_state = playerGame.GameState()
valid_moves = game_state.getValidMoves()
move_made = False
animate = False
loadImages()
running = True
square_selected = ()
player_clicks = []
game_over = False
move_undone = False
move_log_font = p.font.SysFont("Chunkfive", 20, False, False)
player_one = True
player_two = True
while running:
human_turn = (game_state.white_to_move and player_one) or (not game_state.white_to_move and player_two)
for e in p.event.get():
if e.type == p.QUIT:
p.quit()
sys.exit()
# mouse handler
elif e.type == p.MOUSEBUTTONDOWN:
if not game_over:
location = p.mouse.get_pos() # (x, y) location of the mouse
col = location[0] // SQUARE_SIZE
row = location[1] // SQUARE_SIZE
if square_selected == (row, col) or col >= 8: # user clicked the same square twice
square_selected = () # deselect
player_clicks = [] # clear clicks
else:
square_selected = (row, col)
player_clicks.append(square_selected) # append for both 1st and 2nd click
if len(player_clicks) == 2 and human_turn: # after 2nd click
move = playerMoves.Move(player_clicks[0], player_clicks[1], game_state.board)
for i in range(len(valid_moves)):
if move == valid_moves[i]:
game_state.makeMove(valid_moves[i])
move_made = True
animate = True
square_selected = () # reset user clicks
player_clicks = []
if not move_made:
player_clicks = [square_selected]
if move_made:
if animate:
animateMove(game_state.move_log[-1], screen, game_state.board, clock)
valid_moves = game_state.getValidMoves()
move_made = False
animate = False
move_undone = False
drawGameState(screen, game_state, valid_moves, square_selected)
if game_state.checkmate:
game_over = True
if game_state.white_to_move:
drawEndGameText(screen, "Black wins by checkmate")
else:
drawEndGameText(screen, "White wins by checkmate")
elif game_state.stalemate:
game_over = True
drawEndGameText(screen, "Stalemate")
clock.tick(MAX_FPS)
p.display.flip()
def drawGameState(screen, game_state, valid_moves, square_selected):
drawBoard(screen) # draw squares on the board
highlightSquares(screen, game_state, valid_moves, square_selected)
drawPieces(screen, game_state.board) # draw pieces on top of those squares
def drawBoard(screen):
global colors
colors = [p.Color("white"), p.Color("brown")]
for row in range(DIMENSION):
for column in range(DIMENSION):
color = colors[((row + column) % 2)]
p.draw.rect(screen, color, p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
def highlightSquares(screen, game_state, valid_moves, square_selected):
if (len(game_state.move_log)) > 0:
last_move = game_state.move_log[-1]
s = p.Surface((SQUARE_SIZE, SQUARE_SIZE))
s.set_alpha(100)
s.fill(p.Color('green'))
screen.blit(s, (last_move.end_col * SQUARE_SIZE, last_move.end_row * SQUARE_SIZE))
if square_selected != ():
row, col = square_selected
if game_state.board[row][col][0] == (
'w' if game_state.white_to_move else 'b'): # square_selected is a piece that can be moved
# highlight selected square
s = p.Surface((SQUARE_SIZE, SQUARE_SIZE))
s.set_alpha(100) # transparency value 0 -> transparent, 255 -> opaque
s.fill(p.Color('blue'))
screen.blit(s, (col * SQUARE_SIZE, row * SQUARE_SIZE))
# highlight moves from that square
s.fill(p.Color('yellow'))
for move in valid_moves:
if move.start_row == row and move.start_col == col:
screen.blit(s, (move.end_col * SQUARE_SIZE, move.end_row * SQUARE_SIZE))
def drawPieces(screen, board):
for row in range(DIMENSION):
for column in range(DIMENSION):
piece = board[row][column]
if piece != "--":
screen.blit(IMAGES[piece], p.Rect(column * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
def drawEndGameText(screen, text):
font = p.font.SysFont("Helvetica", 32, True, False)
text_object = font.render(text, False, p.Color("gray"))
text_location = p.Rect(0, 0, BOARD_WIDTH, BOARD_HEIGHT).move(BOARD_WIDTH / 2 - text_object.get_width() / 2,
BOARD_HEIGHT / 2 - text_object.get_height() / 2)
screen.blit(text_object, text_location)
text_object = font.render(text, False, p.Color('black'))
screen.blit(text_object, text_location.move(2, 2))
def animateMove(move, screen, board, clock):
global colors
d_row = move.end_row - move.start_row
d_col = move.end_col - move.start_col
frames_per_square = 8 # frames to move one square
frame_count = (abs(d_row) + abs(d_col)) * frames_per_square
for frame in range(frame_count + 1):
row, col = (move.start_row + d_row * frame / frame_count, move.start_col + d_col * frame / frame_count)
drawBoard(screen)
drawPieces(screen, board)
# erase the piece moved from its ending square
color = colors[(move.end_row + move.end_col) % 2]
end_square = p.Rect(move.end_col * SQUARE_SIZE, move.end_row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)
p.draw.rect(screen, color, end_square)
# draw captured piece onto rectangle
if move.piece_captured != '--':
if move.is_enpassant_move:
enpassant_row = move.end_row + 1 if move.piece_captured[0] == 'b' else move.end_row - 1
end_square = p.Rect(move.end_col * SQUARE_SIZE, enpassant_row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)
screen.blit(IMAGES[move.piece_captured], end_square)
# draw moving piece
screen.blit(IMAGES[move.piece_moved], p.Rect(col * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))
p.display.flip()
clock.tick(60)