I am attempting to create a chess GUI. I was able to make it so that when the player is White, everything loads perfectly. However, when I try to load when the player is Black, it does not load anything on White's side. Here is the relevant code (Note: the screen is 800x800 and the piece pictures are 100x100):
for i in range(64):
piece = board.piece_at(i)
if piece is not None:
x_value = (i%8)*100
y_value = 700 - ((i // 8) * 100)
if color == "W":
scrn.blit(pieces[str(piece)], (x_value, y_value))
else:
scrn.blit(pieces[str(piece)], (700-x_value, 700-y_value))
Full function:
scrn = pygame.display.set_mode((800, 900))
board = chess.Board()
gui_update(scrn, board, color="W") # Last parameter can be "B"
def gui_update(scrn, board, index_moves=None, resign_button=False, confirmation=False, color="W"):
LIGHT = (240, 217, 181)
DARK = (181, 136, 99)
BLUE = (50, 255, 255)
pieces = {'p': pygame.image.load('Pieces/b_pawn.png').convert_alpha(),
'n': pygame.image.load('Pieces/b_knight.png').convert_alpha(),
'b': pygame.image.load('Pieces/b_bishop.png').convert_alpha(),
'r': pygame.image.load('Pieces/b_rook.png').convert_alpha(),
'q': pygame.image.load('Pieces/b_queen.png').convert_alpha(),
'k': pygame.image.load('Pieces/b_king.png').convert_alpha(),
'P': pygame.image.load('Pieces/w_pawn.png').convert_alpha(),
'N': pygame.image.load('Pieces/w_knight.png').convert_alpha(),
'B': pygame.image.load('Pieces/w_bishop.png').convert_alpha(),
'R': pygame.image.load('Pieces/w_rook.png').convert_alpha(),
'Q': pygame.image.load('Pieces/w_queen.png').convert_alpha(),
'K': pygame.image.load('Pieces/w_king.png').convert_alpha(),
}
row_changer = 0
for i in range(64):
square = pygame.Rect((i % 8) * 100, 700 - (i // 8) * 100, 100, 100)
if (i + row_changer) % 2 == 0:
square_color = DARK
else:
square_color = LIGHT
if (i + 1) % 8 == 0:
if row_changer == 0:
row_changer = 1
else:
row_changer = 0
pygame.draw.rect(surface=scrn, color=square_color, rect=square)
if index_moves is not None:
if i in index_moves:
x1 = (i % 8) * 100
y1 = 700 - (i // 8) * 100
if color == "B":
x1 = 700 - x1
y1 = 700 - y1
x2 = x1 + 100
y2 = y1
x3 = x2
y3 = y2 + 100
x4 = x1
y4 = y3
pygame.draw.lines(scrn, BLUE, True, [(x1, y1), (x2, y2), (x3, y3), (x4, y4)], 5)
piece = board.piece_at(i)
if piece is None:
pass
else:
x_value = (i % 8) * 100
y_value = 700 - ((i // 8) * 100)
if color == "W":
scrn.blit(pieces[str(piece)], (x_value, y_value))
else:
print("X: {0} | Y: {1}".format(700 - x_value, 700 - y_value))
scrn.blit(pieces[str(piece)], (700 - x_value, 700 - y_value))
if resign_button:
font = pygame.font.Font('freesansbold.ttf', 50)
if not confirmation:
text = font.render("Resign", True, (255, 255, 255))
else:
text = font.render("Are you sure? (Y/N)", True, (255, 255, 255))
# pygame.draw.rect(scrn, (150, 150, 150), [0, 0, 100, 50])
textRect = text.get_rect()
textRect.center = (400, 850)
scrn.blit(text, textRect)
pygame.display.flip()
Functionally, the program runs fine. However, anything above the first rows (on White's side) is not loaded. If one of White's pieces makes it to Black's side, then it is loaded. Similarly, if a Black piece makes it to White's side, then it is unloaded visually. How can I prevent this from happening?
The problem is the order of drawing when color
is not "W":
. You draw the rectangles (pygame.draw.rect
) on top of the pieces because the pieces are drawn from bottom to top and the rectangles from top to bottom in the same loop. So the bottom pieces are drawn first and later covered by the rectangles. Draw the pieces in a separate loop:
def gui_update(scrn, board, index_moves=None, resign_button=False, confirmation=False, color="W"):
# [...]
# draw board
for i in range(64):
# draw rectangles and lines
# [...]
# draw pieces and the completely drawn board
for i in range(64):
piece = board.piece_at(i)
if piece:
x_value = (i % 8) * 100
y_value = 700 - ((i // 8) * 100)
if color == "W":
scrn.blit(pieces[str(piece)], (x_value, y_value))
else:
scrn.blit(pieces[str(piece)], (700 - x_value, 700 - y_value))