简体   繁体   English

Python国际象棋程序

[英]Python chess program

I'm attempting to make a fairly simple chess game for my a coding project, hoping to implement a computer opponent at some point too, a bit stuck on how to add move limits and functions to detect the game ending at this point.我正在尝试为我的编码项目制作一个相当简单的国际象棋游戏,希望在某个时候也能实现一个计算机对手,有点卡在如何添加移动限制和功能以检测此时游戏的结束。 The body was designed by @sloth and I've added to it.身体是由@sloth 设计的,我已经添加了。

I've done the fairly simple stuff, load all the pieces and change the board colour but I'm not too sure on what to do at this point.我已经完成了相当简单的工作,加载了所有部件并更改了电路板颜色,但我不太确定此时该做什么。 Any help would be appreciated!任何帮助,将不胜感激!

import pygame

TILESIZE = 75
BOARD_POS = (10, 10)

def create_board_surf():
    board_surf = pygame.Surface((TILESIZE*8, TILESIZE*8))
    dark = False
    for y in range(8):
        for x in range(8):
            rect = pygame.Rect(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE)
            pygame.draw.rect(board_surf, pygame.Color('darkgreen' if dark else 'beige'), rect)
            dark = not dark
        dark = not dark
    return board_surf

def get_square_under_mouse(board):
    mouse_pos = pygame.Vector2(pygame.mouse.get_pos()) - BOARD_POS
    x, y = [int(v // TILESIZE) for v in mouse_pos]
    try:
        if x >= 0 and y >= 0: return (board[y][x], x, y)
    except IndexError: pass
    return None, None, None

def create_board():
    board = []
    for y in range(8):
        board.append([])
        for x in range(8):
            board[y].append(None)

    ## BLACK PIECES ##

    for x in range(0, 8):
        board[1][x] = ('black', 'pawn')
    for x in range(0, 1):
        board[0][x] = ('black', 'rook')
    for x in range(0, 8):
        board[0][x] = ('black', 'rook')
    for x in range(1, 2):
        board[0][x] = ('black', 'horse')
    for x in range(6, 7):
        board[0][x] = ('black', 'horse')
    for x in range(2, 3):
        board[0][x] = ('black', 'bishop')
    for x in range(5, 6):
        board[0][x] = ('black', 'bishop')
    for x in range(3, 4):
        board[0][x] = ('black', 'queen')
    for x in range(4, 5):
        board[0][x] = ('black', 'king')

    ## WHITE PIECES ##

    for x in range(0, 8):
        board[6][x] = ('white', 'pawn')
    for x in range(0, 1):
        board[7][x] = ('white', 'rook')
    for x in range(7, 8):
        board[7][x] = ('white', 'rook')
    for x in range(1, 2):
        board[7][x] = ('white', 'horse')
    for x in range(6, 7):
        board[7][x] = ('white', 'horse')
    for x in range(2, 3):
        board[7][x] = ('white', 'bishop')
    for x in range(5, 6):
        board[7][x] = ('white', 'bishop')
    for x in range(3, 4):
        board[7][x] = ('white', 'queen')
    for x in range(4, 5):
        board[7][x] = ('white', 'king')



    return board

def draw_pieces(screen, board, font, selected_piece):
    sx, sy = None, None
    if selected_piece:
        piece, sx, sy = selected_piece

    for y in range(8):
        for x in range(8):
            piece = board[y][x]
            if piece:
                selected = x == sx and y == sy
                color, type = piece
                s1 = font.render(type[0], True, pygame.Color('red' if selected else color))
                s2 = font.render(type[0], True, pygame.Color('darkgrey'))
                pos = pygame.Rect(BOARD_POS[0] + x * TILESIZE+1, BOARD_POS[1] + y * TILESIZE + 1, TILESIZE, TILESIZE)
                screen.blit(s2, s2.get_rect(center=pos.center).move(1, 1))
                screen.blit(s1, s1.get_rect(center=pos.center))

def draw_selector(screen, piece, x, y):
    if piece != None:
        rect = (BOARD_POS[0] + x * TILESIZE, BOARD_POS[1] + y * TILESIZE, TILESIZE, TILESIZE)
        pygame.draw.rect(screen, (255, 0, 0, 50), rect, 2)

def draw_drag(screen, board, selected_piece, font):
    if selected_piece:
        piece, x, y = get_square_under_mouse(board)
        if x != None:
            rect = (BOARD_POS[0] + x * TILESIZE, BOARD_POS[1] + y * TILESIZE, TILESIZE, TILESIZE)
            pygame.draw.rect(screen, (0, 255, 0, 50), rect, 2)

        color, type = selected_piece[0]
        s1 = font.render(type[0], True, pygame.Color(color))
        s2 = font.render(type[0], True, pygame.Color('darkgrey'))
        pos = pygame.Vector2(pygame.mouse.get_pos())
        screen.blit(s2, s2.get_rect(center=pos + (1, 1)))
        screen.blit(s1, s1.get_rect(center=pos))
        selected_rect = pygame.Rect(BOARD_POS[0] + selected_piece[1] * TILESIZE, BOARD_POS[1] + selected_piece[2] * TILESIZE, TILESIZE, TILESIZE)
        pygame.draw.line(screen, pygame.Color('red'), selected_rect.center, pos)
        return (x, y)

def main():
    pygame.init()
    font = pygame.font.SysFont('', 64)
    screen = pygame.display.set_mode((620, 620))
    board = create_board()
    board_surf = create_board_surf()
    clock = pygame.time.Clock()
    selected_piece = None
    drop_pos = None
    while True:
        piece, x, y = get_square_under_mouse(board)
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
            if e.type == pygame.MOUSEBUTTONDOWN:
                if piece != None:
                    selected_piece = piece, x, y
            if e.type == pygame.MOUSEBUTTONUP:
                if drop_pos:
                    piece, old_x, old_y = selected_piece
                    board[old_y][old_x] = 0
                    new_x, new_y = drop_pos
                    board[new_y][new_x] = piece
                selected_piece = None
                drop_pos = None

        screen.fill(pygame.Color('grey'))
        screen.blit(board_surf, BOARD_POS)
        draw_pieces(screen, board, font, selected_piece)
        draw_selector(screen, piece, x, y)
        drop_pos = draw_drag(screen, board, selected_piece, font)

        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()

First of all you would be better of using python-chess library if you just want to get things done.首先,如果您只想完成任务,最好使用 python-chess 库。 Otherwise to check for the end of a game in chess you need to see if few of possible conditions are true:否则,要检查国际象棋游戏的结束,您需要查看是否有几个可能的条件为真:

  • is it checkmate (ie king is in check and cannot move to any adjacent square or otherwise get out of check)是将死吗(即国王处于受控状态,不能移动到任何相邻的方格或以其他方式不受控)
  • is it stalemate (ie no legal move)是否陷入僵局(即没有合法举动)
  • is it threefold repetition (ie the position repeated three times in a game)是否重复三次(即position在游戏中重复三次)
  • 50 move rule (ie if no captures or pawn moves were made in 50 moves) 50 步规则(即如果在 50 步中没有进行捕获或典当移动)
  • is it draw because of insufficient material to mate是不是因为材料不足而无法交配

So it is quite complicated just because of the rules of the game.因此,仅仅因为游戏规则,它就相当复杂。

Now if you want to pick legal moves read about 0x88 method of representing the board.现在,如果您想选择合法的移动,请阅读有关 0x88 代表棋盘的方法。 It represents the position as two boards, with one containing pieces and the other illegal territory.它将 position 表示为两块板,一个包含碎片,另一个包含非法区域。 This provides easy check on legal moves since you just AND the board with generated moves to check legality.这提供了对合法动作的简单检查,因为您只需将棋盘与生成的动作结合来检查合法性。 Take caution when implementing sliding pieces, king and en passant.在实施滑动件、国王和通行证时要小心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM