0

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?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Hantalyte
  • 72
  • 6
  • It seems there is no need to have different rules for white and black pieces in your above code snippet - just handle them the same way when you draw them. The only piece that has different rules whether it is white or black is the pawn, so just have a condition on the pawn movement rules that dictates the moving direction – oskros Feb 08 '23 at 13:41
  • @oskros I am using the Python chess library for handling piece movement. The only real challenge is drawing them. Python chess stores the pieces in an array of 64 (8*8) for each square. I am attempting to get the piece, and then inverting its x and y, making it the equivalent for Black. – Hantalyte Feb 08 '23 at 13:48
  • you are looping through all positions on the chess board, and getting the piece at that position - you don't need to handle black and white pieces differently. also I don't understand your `y_value` calculation. shouldn't it just be `y_value=i//8` (potentially multiplying by `100` to scale if you want.. – oskros Feb 08 '23 at 14:05
  • ```y_value = i//8`` puts the pieces on the top. 700 - i//8 puts the pieces on the right side. – Hantalyte Feb 08 '23 at 14:10
  • @oskros The reason why I am handling them differently is so that when the player is Black, they are in Black's perspective. It is confusing to be in White's perspective while playing as Black. – Hantalyte Feb 08 '23 at 15:10
  • @Rabbid76 I added more code to make it reproducible. – Hantalyte Feb 17 '23 at 16:45

1 Answers1

1

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))

    
Rabbid76
  • 202,892
  • 27
  • 131
  • 174