2

I'm not asking for specific code, but the general structure and how to link the python-chess library with the pygame library with the code that allows the player and AI to move.

Any tips on where to start?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Moiz _
  • 23
  • 1
  • 4

2 Answers2

2

You can have a look at this tutorial. The explanation is quite thorough and I believe that it will give you enough hints on how to start. Happy coding :) Here is the link How to make chess game with python

  • But as I said, I don't want to code it from scratch like the website shows, I want to use the python-chess library – Moiz _ Jun 21 '21 at 16:15
  • I understand that, but the chess module is a pure Python chess library with move generation, move validation and support for common formats. However, it does not create a pleasant User Interface. Therefore, I suggested the tutorial above. But, if your goal is to create a chess game only with the chess library you can have a look [here](https://www.google.co.uk/amp/s/www.geeksforgeeks.org/chess-library-in-python/amp/). If the answer has satisfied your needs please accept it as correct. – Asparuh Gavrailov Jun 21 '21 at 16:26
2

I'm interested in python chess engines. I'm programming my own in this moment, using the python-chess library.
For the moment, its level is very bad, but I hope I'll make a better AI. I'm changing the evaluation function.
I created an GUI using pygame and Wikipedia images ([enter link description here][1]. The bard can be found easily on Wikipedia.
I've made 3 differents codes : one for the engine, one for play with the computer, and one to watch two computers. I'll just show you my engine (in construction), and you should imagine how to use it.
engine.py :

import pygame
import chess
import random

screen = pygame.display.set_mode((480, 480))
pygame.display.set_caption("Chess Engine")
screen.fill("WHITE")

WHITE = (255, 255, 255)
RED = (255, 0, 0)

chessboard = pygame.image.load('graph/chessboard.png').convert_ alpha()
King = pygame.image.load('graph/WKing.png').convert_alpha()
king = pygame.image.load('graph/BKing.png').convert_alpha()
Knight = pygame.image.load('graph/WKnight.png').convert_alpha()
knight = pygame.image.load('graph/BKnight.png').convert_alpha()
Rook = pygame.image.load('graph/WRook.png').convert_alpha()
rook = pygame.image.load('graph/BRook.png').convert_alpha()
Queen = pygame.image.load('graph/WQueen.png').convert_alpha()
queen = pygame.image.load('graph/BQueen.png').convert_alpha()
Bishop = pygame.image.load('graph/WBishop.png').convert_alpha()
bishop = pygame.image.load('graph/BBishop.png').convert_alpha()
Pawn = pygame.image.load('graph/WPawn.png').convert_alpha()
pawn = pygame.image.load('graph/BPawn.png').convert_alpha()


def draw(fen, col, rank, board) :
    if fen == 'K' :
        if board.turn == chess.WHITE :
            if board.is_check() :
                pygame.draw.circle(screen, RED, (rank + 30, col + 30), 30)
        screen.blit(King, (rank, col))
    elif fen == 'k' :
        if board.turn == chess.BLACK :
            if board.is_check() :
                pygame.draw.circle(screen, RED, (rank + 30, col + 30), 30)
        screen.blit(king, (rank, col))
    elif fen == 'Q' :
        screen.blit(Queen, (rank, col))
    elif fen == 'q' :
        screen.blit(queen, (rank, col))
    elif fen == 'R' :
        screen.blit(Rook, (rank, col))
    elif fen == 'r' :
        screen.blit(rook, (rank, col))
    elif fen == 'N' :
        screen.blit(Knight, (rank, col))
    elif fen == 'n' :
        screen.blit(knight, (rank, col))
    elif fen == 'B' :
        screen.blit(Bishop, (rank, col))
    elif fen == 'b' :
        screen.blit(bishop, (rank, col))
    elif fen == 'P' :
        screen.blit(Pawn, (rank, col))
    elif fen == 'p' :
        screen.blit(pawn, (rank, col))

def show(FEN, board) :
        screen.blit(chessboard, (0, 0))
        col = 0
        rank = 0
        for fen in FEN :
            if fen == '/' :
                col = col + 1
                rank = 0
            elif fen in ('1', '2', '3', '4', '5', '6', '7', '8') :
                rank = rank + int(fen)
            elif fen in ('K', 'k', 'Q', 'q', 'R', 'r', 'N', 'n', 'B', 'b', 'P', 'p') :
                draw(fen, col*60, rank*60, board)
                rank = rank + 1
        pygame.display.update() 

infinity = 1000000000

def piece_list(pos) :
    '''Renvoie la liste des pièces présentes sur l'échiquier.'''
    piece_liste = []
    for place in chess.SQUARES :
        if pos.piece_at(place) != None :
            piece_liste.append(pos.piece_at(place).symbol())
    return piece_liste

def game_is_finished(pos) :
    '''Détermine si la partie est finie.'''
    if pos.is_checkmate() or pos.is_stalemate() or pos.is_insufficient_material() or pos.can_claim_threefold_repetition():
        return True
    else :
        return False

def evaluate(pos) :
    '''Évaluation d'une position en fonction d'une position et de la mobillité des pièces.'''
     if pos.is_checkmate() :
        return -infinity
    elif game_is_finished(pos) :
        return 0
    piece_liste = piece_list(pos)
    evaluation = 0
    opponent_legal_moves = []
    current_player_legal_moves = [move for move in pos.legal_moves]
    for i in piece_liste :
        if i == 'Q' :
            evaluation = evaluation + 9
        elif i == 'q' :
            evaluation = evaluation - 9
        elif i == 'R' :
            evaluation = evaluation + 5
        elif i == 'r' :
            evaluation = evaluation - 5
        elif i == 'N' :
            evaluation = evaluation + 3
        elif i == 'n' :
            evaluation = evaluation - 3
        elif i == 'B' :
            evaluation = evaluation + 3
        elif i == 'b' :
            evaluation = evaluation - 3
        elif i == 'P' :
            evaluation = evaluation + 1
        elif i == 'p' :
            evaluation = evaluation - 1

    for i in range(len(current_player_legal_moves)-1) :
        pos.push_san(str(current_player_legal_moves[i]))
        opponent_legal_moves.append(pos.legal_moves.count())
        if pos.is_checkmate() :
            pos.pop()
            return infinity
        elif game_is_finished(pos) :
            pos.pop()
            return 0
        pos.pop()
    moyenne = 0
    for i in opponent_legal_moves :
        moyenne = moyenne + i
    if len(opponent_legal_moves) != 0 :
        moyenne = moyenne / len(opponent_legal_moves)
    #else :   a servi pour le déboggage
        #print(moyenne)
    if pos.turn == chess.WHITE :
        evaluation = evaluation + 0.1*(pos.legal_moves.count() - moyenne)
    else :
        evaluation = evaluation - 0.1*(pos.legal_moves.count() - moyenne)

    return evaluation

def evaluation_turn(pos) :
    '''Évaluation d'une position selon le côté qui doit jouer.'''
    if pos.turn == chess.WHITE :
        return evaluate(pos)
    else :
        return - evaluate(pos)

def one_legal(pos) :
    current_player_legal_moves = [str(move) for move in pos.legal_moves]
    #print(current_player_legal_moves)
    return random.choice(current_player_legal_moves)

def can_t_move(pos) :
    if pos.legal_moves.count() == 0 :
        return True
    else :
        return False

def child_of_position(pos) :
    '''Détermine toutes les possitions filles d'une position (avec leur coup associé pour aller plus vite).'''
    current_player_legal_moves = [move for move in pos.legal_moves]
    result = []
    for i in range(len(current_player_legal_moves)-1) :
        new_pos = chess.Board(pos.fen())
        new_pos.push_san(str(current_player_legal_moves[i]))
        result.append((new_pos, str(current_player_legal_moves[i])))
    return result  # (board, move)

def minimax(pos, depth, alpha, beta, maximizingPlayer) :
    '''Algorithme MiniMax avec Alpha-Bêta.'''
    # maximizingPlayer = Trus si White2Play et False si Black2Play

    if depth == 0 or game_is_finished(pos[0]) or can_t_move(pos[0]) :
        return (evaluate(pos[0]), None)

    one_legal_move = one_legal(pos[0])
    if maximizingPlayer :
        maxEval = (-infinity, one_legal_move) # None = move
        for child in child_of_position(pos[0]) :
            evalu = minimax(child, depth - 1, alpha, beta, False)
            maxEval = (max(maxEval[0], evalu[0]), maxEval[1])
            if max(maxEval[0], evalu[0]) == evalu[0] :
                maxEval = (max(maxEval[0], evalu[0]), child[1])
            alpha = max(alpha, evalu[0])
            if beta <= alpha :
                break
        return maxEval

    else :
        maxEval = (infinity, one_legal_move)
        for child in child_of_position(pos[0]) :
            evalu = minimax(child, depth - 1, alpha, beta, True)
            maxEval = (min(maxEval[0], evalu[0]), maxEval[1])
            if max(maxEval[0], evalu[0]) == evalu[0] :
                maxEval = (min(maxEval[0], evalu[0]), child[1])
            alpha = min(alpha, evalu[0])
            if beta <= alpha :
                break
        return maxEval

Sorry for my bad English, I'm French. I hope my answer can helps you. [1]: https://commons.wikimedia.org/wiki/Category:PNG_chess_pieces/Standard_transparent

LittleCoder
  • 391
  • 1
  • 13