使用 pgn 创建游戏资源管理器(如 lichess 资源管理器)

Create game explorer with pgn (like lichess explorer)

目前我正在寻找 python 做一个失败的“ia”,这让我以最好的成功率(使用 lichess 数据库的大师部分)和 minmax 和只接受已经下过至少100个位置的着法,以免单局落在100%的黑棋成功率上。我设法用 lichess api 做到了,问题是当我请求超过 3 个深度时,lichess 阻止了我,因为 api.

上生成了垃圾邮件

我告诉自己我会做同样的事情,但我不会使用 lichess api,而是会使用大师部分的 .pgn 和库“国际象棋”我可以做类似的事情,但目前我无法通过示例“e2-e4”过滤此文件并获得每次移动的成功率并具有递归函数来探索此文件。

我无法通过 chess-py 文档找到邀请,我的 google 搜索也没有找到任何结果。

有人有想法吗?

api 巫妖:https://lichess.org/api#tag/Opening-Explorer

png 文件:https://odysee.com/@Toadofsky:b/Lichess-Elite-Database:b

一种方法是建立像 mongodb 这样的数据库。

1. Read each game in the pgn file.
2. Record the epd after every move in the game.
3. Get the result of this game.
4. Record white_win, white_loss, white_draw, black_win, black_loss, black_draw, num_game.
5. Save/update to database the following info.
{
  "epd": <epd> 
  "white_win": ...,
  "white_loss": ..., 
  "...": ...
}

您现在可以通过 epd 查询数据库并获取其中的内容。

您可以使用例如 python-chess 库解析 pgn 文件中的每个游戏。

先保存到数据库的好处是以后查询的时候出结果快

如果您不想将其保存在数据库中,您可以这样做,但如果文件很大,可能会很昂贵。你仍然可以使用上面的算法。

这是一个带有@fougueux 指示的示例(我没有想过用这个文件创建数据库,我错过了正是我需要的“erd”代码)

填入数据库(dbname="game",row id,row fen,row result)

import json
import requests
import chess
import chess.pgn
import chess.polyglot

import pymysql


pgn = open('C:/Users/pierr/OneDrive/Bureau/lichess_elite_2020-05.pgn')
result = []

while True:
    game = chess.pgn.read_game(pgn)
    if game is not None:
        board = game.board()
        for move in game.mainline_moves():
            board.push(move)
            result.append([board.epd(), game.headers["Result"]])
    else: 
        break

connection = pymysql.connect(host='localhost',
                             user='root',
                             password='',
                             database='chess-master',
                             cursorclass=pymysql.cursors.DictCursor)

with connection:
    with connection.cursor() as cursor:
        # Create a new record
        for i in result:
            sql = "INSERT INTO `game` (`fen`, `result`) VALUES (%s, %s)"
            cursor.execute(sql, (i[0], i[1]))

和搜索最小最大分数的算法(分数 = %winrate white * 1,+ %winrate black * 0,+ %winrate draw * 0.5),他采取了更多 100 步走法

import json
import requests
import chess
import chess.pgn
import chess.polyglot

board = chess.Board()

def parcourir(board, depth, traitblanc):
    
    scorelist = []
    
    for move in board.legal_moves:
        board.push(move)
                   
        url = 'http://localhost/chess-master/?fen='
        url += board.epd() # fen
        
        r = requests.get(url)
        data  = json.loads(r.text)
        
        somme = int(data[0]['COUNT(result)']) + int(data[1]['COUNT(result)']) + int(data[2]['COUNT(result)'])
       
        if(somme > 100):  
            score = (int(data[0]['COUNT(result)']) * 1) + (int(data[1]['COUNT(result)']) * 0) + (int(data[2]['COUNT(result)']) * 0.5)
            scorelist.append(score)

        board.pop()
        
    if(depth != 0):
        score = []
        for move in board.legal_moves:

            board.push(move)
            score.append(parcourir(board, depth-1, not traitblanc))
            board.pop()
            
    if(traitblanc):
        if(not scorelist):
            return -100
        return max(scorelist)
    else:
        if(not scorelist):
            return 100
        return min(scorelist)
    
print (parcourir(board, 1, True))

使用 php 比使用 python 更舒服 我通过以下代码制作了 select 的 fen:

<?php
    $servername = "localhost";
    $username = "root";
    $password = "";
    $dbname = "chess-master";
    
    $doCount = array("1-0","0-1","1/2-1/2");
    
    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);

    $results = array();
    
    foreach($doCount as $c) {
        
        $sql = "SELECT COUNT(result) FROM `game` WHERE fen = '".$_GET['fen']."' and result = '".$c."'";
        $result = $conn->query($sql);
        while($row = $result->fetch_assoc()) {
            $results[] = $row;
            #print_r($row);
        }
    
    }   
    echo json_encode($results)
?>

感谢您的帮助:)