0

目前我正在寻找 python 做一个失败的“ia”,这给了我最好的成功率(使用 lichess 数据库的大师部分)的开局,最小最大值,并且只采取至少有 100 个位置的动作已经玩过以免单场100%黑成功率。我设法用 lichess api 做到了,问题是当我请求超过 3 个深度时,lichess 会因为 api 上生成的垃圾邮件而阻止我。

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

我无法通过 chess-py 文档找到请求,而且我的谷歌搜索也没有找到任何内容。

有人有想法吗?

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

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

4

2 回答 2

0

一种方法是构建像 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 文件中的每个游戏。

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

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

于 2022-01-02T03:50:35.033 回答
0

这是一个带有@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]))

以及搜索 minmax 得分的算法(得分 = %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 更舒服,我通过以下代码选择了 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)
?>

谢谢你的帮忙 :)

于 2022-01-02T15:18:16.520 回答