Files
projet_dd/Main.ipynb
2025-12-06 16:29:46 +01:00

767 lines
55 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "8b22a2d1",
"metadata": {},
"source": [
"# Introduction\n",
"\n",
"Bonjour et bienvenue dans le notebook du projet sur les bases de données tablebase.\n",
"\n",
"Dans ce notebook. Nous allons montrer comme fonctionne le stockage d'une base de données tablebases en prenant comme exemple la table base \"syzygy\" avec comme taille 3 à 5 pièces pour des raisons de taille.\n",
"Nous allons expliquer comment les finales ( ou position d'échecs) sont stockés dans le format key-value puis nous verrons ensuite les performances de la base à l'aide de Redis.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "78fdf40a",
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-06T09:21:56.560113Z",
"start_time": "2025-12-06T09:21:56.104871Z"
}
},
"outputs": [],
"source": [
"#import du projet\n",
"import redis\n",
"import time\n",
"import chess\n",
"import chess.syzygy\n",
"import random\n",
"import numpy as np\n",
"import pandas as pd\n",
"import os\n",
"import hashlib\n",
"from IPython.display import display\n",
"from scipy import stats\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "d584aba1",
"metadata": {},
"source": [
"## Peuplement de Redis\n",
"\n",
"Dans un premier temps, on ajoute les positions de la tablebase à Redis afin de pouvoir les utilisers derrières pour faire les tests."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "e6058974",
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-06T09:22:49.905572Z",
"start_time": "2025-12-06T09:22:06.592819Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Configs ok: {'KRvK', 'KQvKP', 'KRvKB', 'KNvK', 'KRBvKP', 'KBvK', 'KBNvK', 'KPvK', 'KPvKP', 'KRPvKP', 'KQvK'}\n"
]
},
{
"data": {
"image/svg+xml": [
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 390 390\" width=\"390\" height=\"390\"><desc><pre>. . . . k . . .\n",
". . . . . . . .\n",
". . . n . . . .\n",
". . . . . . . .\n",
". . . . . . . p\n",
". P . . . . . .\n",
". . . . B . . .\n",
". . . . K . . .</pre></desc><defs><g id=\"white-pawn\" class=\"white pawn\"><path d=\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\" fill=\"#fff\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" /></g><g id=\"white-bishop\" class=\"white bishop\" fill=\"none\" fill-rule=\"evenodd\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><g fill=\"#fff\" stroke-linecap=\"butt\"><path d=\"M9 36c3.39-.97 10.11.43 13.5-2 3.39 2.43 10.11 1.03 13.5 2 0 0 1.65.54 3 2-.68.97-1.65.99-3 .5-3.39-.97-10.11.46-13.5-1-3.39 1.46-10.11.03-13.5 1-1.354.49-2.323.47-3-.5 1.354-1.94 3-2 3-2zM15 32c2.5 2.5 12.5 2.5 15 0 .5-1.5 0-2 0-2 0-2.5-2.5-4-2.5-4 5.5-1.5 6-11.5-5-15.5-11 4-10.5 14-5 15.5 0 0-2.5 1.5-2.5 4 0 0-.5.5 0 2zM25 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 1 1 5 0z\" /></g><path d=\"M17.5 26h10M15 30h15m-7.5-14.5v5M20 18h5\" stroke-linejoin=\"miter\" /></g><g id=\"white-king\" class=\"white king\" fill=\"none\" fill-rule=\"evenodd\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22.5 11.63V6M20 8h5\" stroke-linejoin=\"miter\" /><path d=\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\" fill=\"#fff\" stroke-linecap=\"butt\" stroke-linejoin=\"miter\" /><path d=\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\" fill=\"#fff\" /><path d=\"M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\" /></g><g id=\"black-pawn\" class=\"black pawn\"><path d=\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\" fill=\"#000\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" /></g><g id=\"black-knight\" class=\"black knight\" fill=\"none\" fill-rule=\"evenodd\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18\" style=\"fill:#000000; stroke:#000000;\" /><path d=\"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10\" style=\"fill:#000000; stroke:#000000;\" /><path d=\"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z\" style=\"fill:#ececec; stroke:#ececec;\" /><path d=\"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z\" transform=\"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)\" style=\"fill:#ececec; stroke:#ececec;\" /><path d=\"M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z \" style=\"fill:#ececec; stroke:none;\" /></g><g id=\"black-king\" class=\"black king\" fill=\"none\" fill-rule=\"evenodd\" stroke=\"#000\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M22.5 11.63V6\" stroke-linejoin=\"miter\" /><path d=\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\" fill=\"#000\" stroke-linecap=\"butt\" stroke-linejoin=\"miter\" /><path d=\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\" fill=\"#000\" /><path d=\"M20 8h5\" stroke-linejoin=\"miter\" /><path d=\"M32 29.5s8.5-4 6.03-9.65C34.15 14 25 18 22.5 24.5l.01 2.1-.01-2.1C20 18 9.906 14 6.997 19.85c-2.497 5.65 4.853 9 4.853 9M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\" stroke=\"#fff\" /></g></defs><rect x=\"7.5\" y=\"7.5\" width=\"375\" height=\"375\" fill=\"none\" stroke=\"#212121\" stroke-width=\"15\" /><g transform=\"translate(20, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M23.328 10.016q-1.742 0-2.414.398-.672.398-.672 1.36 0 .765.5 1.218.508.445 1.375.445 1.196 0 1.914-.843.727-.852.727-2.258v-.32zm2.867-.594v4.992h-1.437v-1.328q-.492.797-1.227 1.18-.734.375-1.797.375-1.343 0-2.14-.75-.79-.758-.79-2.024 0-1.476.985-2.226.992-.75 2.953-.75h2.016V8.75q0-.992-.656-1.531-.649-.547-1.829-.547-.75 0-1.46.18-.711.18-1.368.539V6.062q.79-.304 1.532-.453.742-.156 1.445-.156 1.898 0 2.836.984.937.985.937 2.985z\" /></g><g transform=\"translate(20, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M23.328 10.016q-1.742 0-2.414.398-.672.398-.672 1.36 0 .765.5 1.218.508.445 1.375.445 1.196 0 1.914-.843.727-.852.727-2.258v-.32zm2.867-.594v4.992h-1.437v-1.328q-.492.797-1.227 1.18-.734.375-1.797.375-1.343 0-2.14-.75-.79-.758-.79-2.024 0-1.476.985-2.226.992-.75 2.953-.75h2.016V8.75q0-.992-.656-1.531-.649-.547-1.829-.547-.75 0-1.46.18-.711.18-1.368.539V6.062q.79-.304 1.532-.453.742-.156 1.445-.156 1.898 0 2.836.984.937.985.937 2.985z\" /></g><g transform=\"translate(65, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.922 10.047q0-1.586-.656-2.485-.649-.906-1.79-.906-1.14 0-1.796.906-.649.899-.649 2.485 0 1.586.649 2.492.656.898 1.797.898 1.14 0 1.789-.898.656-.906.656-2.492zm-4.89-3.055q.452-.781 1.14-1.156.695-.383 1.656-.383 1.594 0 2.586 1.266 1 1.265 1 3.328 0 2.062-1 3.328-.992 1.266-2.586 1.266-.96 0-1.656-.375-.688-.383-1.14-1.164v1.312h-1.446V2.258h1.445z\" /></g><g transform=\"translate(65, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.922 10.047q0-1.586-.656-2.485-.649-.906-1.79-.906-1.14 0-1.796.906-.649.899-.649 2.485 0 1.586.649 2.492.656.898 1.797.898 1.14 0 1.789-.898.656-.906.656-2.492zm-4.89-3.055q.452-.781 1.14-1.156.695-.383 1.656-.383 1.594 0 2.586 1.266 1 1.265 1 3.328 0 2.062-1 3.328-.992 1.266-2.586 1.266-.96 0-1.656-.375-.688-.383-1.14-1.164v1.312h-1.446V2.258h1.445z\" /></g><g transform=\"translate(110, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M25.96 6v1.344q-.608-.336-1.226-.5-.609-.172-1.234-.172-1.398 0-2.172.89-.773.883-.773 2.485 0 1.601.773 2.492.774.883 2.172.883.625 0 1.234-.164.618-.172 1.227-.508v1.328q-.602.281-1.25.422-.64.14-1.367.14-1.977 0-3.14-1.242-1.165-1.242-1.165-3.351 0-2.14 1.172-3.367 1.18-1.227 3.227-1.227.664 0 1.296.14.633.134 1.227.407z\" /></g><g transform=\"translate(110, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M25.96 6v1.344q-.608-.336-1.226-.5-.609-.172-1.234-.172-1.398 0-2.172.89-.773.883-.773 2.485 0 1.601.773 2.492.774.883 2.172.883.625 0 1.234-.164.618-.172 1.227-.508v1.328q-.602.281-1.25.422-.64.14-1.367.14-1.977 0-3.14-1.242-1.165-1.242-1.165-3.351 0-2.14 1.172-3.367 1.18-1.227 3.227-1.227.664 0 1.296.14.633.134 1.227.407z\" /></g><g transform=\"translate(155, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.973 6.992V2.258h1.437v12.156h-1.437v-1.312q-.453.78-1.149 1.164-.687.375-1.656.375-1.586 0-2.586-1.266-.992-1.266-.992-3.328 0-2.063.992-3.328 1-1.266 2.586-1.266.969 0 1.656.383.696.375 1.149 1.156zm-4.899 3.055q0 1.586.649 2.492.656.898 1.797.898 1.14 0 1.796-.898.657-.906.657-2.492 0-1.586-.657-2.485-.656-.906-1.796-.906-1.141 0-1.797.906-.649.899-.649 2.485z\" /></g><g transform=\"translate(155, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.973 6.992V2.258h1.437v12.156h-1.437v-1.312q-.453.78-1.149 1.164-.687.375-1.656.375-1.586 0-2.586-1.266-.992-1.266-.992-3.328 0-2.063.992-3.328 1-1.266 2.586-1.266.969 0 1.656.383.696.375 1.149 1.156zm-4.899 3.055q0 1.586.649 2.492.656.898 1.797.898 1.14 0 1.796-.898.657-.906.657-2.492 0-1.586-.657-2.485-.656-.906-1.796-.906-1.141 0-1.797.906-.649.899-.649 2.485z\" /></g><g transform=\"translate(200, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M26.555 9.68v.703h-6.61q.094 1.484.89 2.265.806.774 2.235.774.828 0 1.602-.203.781-.203 1.547-.61v1.36q-.774.328-1.586.5-.813.172-1.649.172-2.093 0-3.32-1.22-1.219-1.218-1.219-3.296 0-2.148 1.157-3.406 1.164-1.266 3.132-1.266 1.766 0 2.79 1.14 1.03 1.134 1.03 3.087zm-1.438-.422q-.015-1.18-.664-1.883-.64-.703-1.703-.703-1.203 0-1.93.68-.718.68-.828 1.914z\" /></g><g transform=\"translate(200, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M26.555 9.68v.703h-6.61q.094 1.484.89 2.265.806.774 2.235.774.828 0 1.602-.203.781-.203 1.547-.61v1.36q-.774.328-1.586.5-.813.172-1.649.172-2.093 0-3.32-1.22-1.219-1.218-1.219-3.296 0-2.148 1.157-3.406 1.164-1.266 3.132-1.266 1.766 0 2.79 1.14 1.03 1.134 1.03 3.087zm-1.438-.422q-.015-1.18-.664-1.883-.64-.703-1.703-.703-1.203 0-1.93.68-.718.68-.828 1.914z\" /></g><g transform=\"translate(245, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M25.285 2.258v1.195H23.91q-.773 0-1.078.313-.297.312-.297 1.125v.773h2.367v1.117h-2.367v7.633H21.09V6.781h-1.375V5.664h1.375v-.61q0-1.46.68-2.124.68-.672 2.156-.672z\" /></g><g transform=\"translate(245, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M25.285 2.258v1.195H23.91q-.773 0-1.078.313-.297.312-.297 1.125v.773h2.367v1.117h-2.367v7.633H21.09V6.781h-1.375V5.664h1.375v-.61q0-1.46.68-2.124.68-.672 2.156-.672z\" /></g><g transform=\"translate(290, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.973 9.937q0-1.562-.649-2.421-.64-.86-1.804-.86-1.157 0-1.805.86-.64.859-.64 2.421 0 1.555.64 2.415.648.859 1.805.859 1.164 0 1.804-.86.649-.859.649-2.414zm1.437 3.391q0 2.234-.992 3.32-.992 1.094-3.04 1.094-.757 0-1.429-.117-.672-.11-1.304-.344v-1.398q.632.344 1.25.508.617.164 1.257.164 1.414 0 2.118-.743.703-.734.703-2.226v-.711q-.446.773-1.141 1.156-.695.383-1.664.383-1.61 0-2.594-1.227-.984-1.226-.984-3.25 0-2.03.984-3.257.985-1.227 2.594-1.227.969 0 1.664.383t1.14 1.156V5.664h1.438z\" /></g><g transform=\"translate(290, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M24.973 9.937q0-1.562-.649-2.421-.64-.86-1.804-.86-1.157 0-1.805.86-.64.859-.64 2.421 0 1.555.64 2.415.648.859 1.805.859 1.164 0 1.804-.86.649-.859.649-2.414zm1.437 3.391q0 2.234-.992 3.32-.992 1.094-3.04 1.094-.757 0-1.429-.117-.672-.11-1.304-.344v-1.398q.632.344 1.25.508.617.164 1.257.164 1.414 0 2.118-.743.703-.734.703-2.226v-.711q-.446.773-1.141 1.156-.695.383-1.664.383-1.61 0-2.594-1.227-.984-1.226-.984-3.25 0-2.03.984-3.257.985-1.227 2.594-1.227.969 0 1.664.383t1.14 1.156V5.664h1.438z\" /></g><g transform=\"translate(335, 1) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M26.164 9.133v5.281h-1.437V9.18q0-1.243-.485-1.86-.484-.617-1.453-.617-1.164 0-1.836.742-.672.742-.672 2.024v4.945h-1.445V2.258h1.445v4.765q.516-.789 1.211-1.18.703-.39 1.617-.39 1.508 0 2.282.938.773.93.773 2.742z\" /></g><g transform=\"translate(335, 375) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M26.164 9.133v5.281h-1.437V9.18q0-1.243-.485-1.86-.484-.617-1.453-.617-1.164 0-1.836.742-.672.742-.672 2.024v4.945h-1.445V2.258h1.445v4.765q.516-.789 1.211-1.18.703-.39 1.617-.39 1.508 0 2.282.938.773.93.773 2.742z\" /></g><g transform=\"translate(0, 335) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.754 26.996h2.578v-8.898l-2.805.562v-1.437l2.79-.563h1.578v10.336h2.578v1.328h-6.72z\" /></g><g transform=\"translate(375, 335) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.754 26.996h2.578v-8.898l-2.805.562v-1.437l2.79-.563h1.578v10.336h2.578v1.328h-6.72z\" /></g><g transform=\"translate(0, 290) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M8.195 26.996h5.508v1.328H6.297v-1.328q.898-.93 2.445-2.492 1.555-1.57 1.953-2.024.758-.851 1.055-1.437.305-.594.305-1.164 0-.93-.657-1.516-.648-.586-1.695-.586-.742 0-1.57.258-.82.258-1.758.781v-1.593q.953-.383 1.781-.578.828-.196 1.516-.196 1.812 0 2.89.906 1.079.907 1.079 2.422 0 .72-.274 1.368-.265.64-.976 1.515-.196.227-1.243 1.313-1.046 1.078-2.953 3.023z\" /></g><g transform=\"translate(375, 290) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M8.195 26.996h5.508v1.328H6.297v-1.328q.898-.93 2.445-2.492 1.555-1.57 1.953-2.024.758-.851 1.055-1.437.305-.594.305-1.164 0-.93-.657-1.516-.648-.586-1.695-.586-.742 0-1.57.258-.82.258-1.758.781v-1.593q.953-.383 1.781-.578.828-.196 1.516-.196 1.812 0 2.89.906 1.079.907 1.079 2.422 0 .72-.274 1.368-.265.64-.976 1.515-.196.227-1.243 1.313-1.046 1.078-2.953 3.023z\" /></g><g transform=\"translate(0, 245) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M11.434 22.035q1.132.242 1.765 1.008.64.766.64 1.89 0 1.727-1.187 2.672-1.187.946-3.375.946-.734 0-1.515-.149-.774-.14-1.602-.43V26.45q.656.383 1.438.578.78.196 1.632.196 1.485 0 2.258-.586.782-.586.782-1.703 0-1.032-.727-1.61-.719-.586-2.008-.586h-1.36v-1.297h1.423q1.164 0 1.78-.46.618-.47.618-1.344 0-.899-.64-1.375-.633-.485-1.82-.485-.65 0-1.391.141-.743.14-1.633.437V16.95q.898-.25 1.68-.375.788-.125 1.484-.125 1.797 0 2.844.82 1.046.813 1.046 2.204 0 .968-.554 1.64-.555.664-1.578.922z\" /></g><g transform=\"translate(375, 245) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M11.434 22.035q1.132.242 1.765 1.008.64.766.64 1.89 0 1.727-1.187 2.672-1.187.946-3.375.946-.734 0-1.515-.149-.774-.14-1.602-.43V26.45q.656.383 1.438.578.78.196 1.632.196 1.485 0 2.258-.586.782-.586.782-1.703 0-1.032-.727-1.61-.719-.586-2.008-.586h-1.36v-1.297h1.423q1.164 0 1.78-.46.618-.47.618-1.344 0-.899-.64-1.375-.633-.485-1.82-.485-.65 0-1.391.141-.743.14-1.633.437V16.95q.898-.25 1.68-.375.788-.125 1.484-.125 1.797 0 2.844.82 1.046.813 1.046 2.204 0 .968-.554 1.64-.555.664-1.578.922z\" /></g><g transform=\"translate(0, 200) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M11.016 18.035L7.03 24.262h3.985zm-.414-1.375h1.984v7.602h1.664v1.312h-1.664v2.75h-1.57v-2.75H5.75v-1.523z\" /></g><g transform=\"translate(375, 200) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M11.016 18.035L7.03 24.262h3.985zm-.414-1.375h1.984v7.602h1.664v1.312h-1.664v2.75h-1.57v-2.75H5.75v-1.523z\" /></g><g transform=\"translate(0, 155) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.719 16.66h6.195v1.328h-4.75v2.86q.344-.118.688-.172.343-.063.687-.063 1.953 0 3.094 1.07 1.14 1.07 1.14 2.899 0 1.883-1.171 2.93-1.172 1.039-3.305 1.039-.735 0-1.5-.125-.758-.125-1.57-.375v-1.586q.703.383 1.453.57.75.188 1.586.188 1.351 0 2.14-.711.79-.711.79-1.93 0-1.219-.79-1.93-.789-.71-2.14-.71-.633 0-1.266.14-.625.14-1.281.438z\" /></g><g transform=\"translate(375, 155) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.719 16.66h6.195v1.328h-4.75v2.86q.344-.118.688-.172.343-.063.687-.063 1.953 0 3.094 1.07 1.14 1.07 1.14 2.899 0 1.883-1.171 2.93-1.172 1.039-3.305 1.039-.735 0-1.5-.125-.758-.125-1.57-.375v-1.586q.703.383 1.453.57.75.188 1.586.188 1.351 0 2.14-.711.79-.711.79-1.93 0-1.219-.79-1.93-.789-.71-2.14-.71-.633 0-1.266.14-.625.14-1.281.438z\" /></g><g transform=\"translate(0, 110) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M10.137 21.863q-1.063 0-1.688.727-.617.726-.617 1.992 0 1.258.617 1.992.625.727 1.688.727 1.062 0 1.68-.727.624-.734.624-1.992 0-1.266-.625-1.992-.617-.727-1.68-.727zm3.133-4.945v1.437q-.594-.28-1.204-.43-.601-.148-1.195-.148-1.562 0-2.39 1.055-.82 1.055-.938 3.188.46-.68 1.156-1.04.696-.367 1.531-.367 1.758 0 2.774 1.07 1.023 1.063 1.023 2.899 0 1.797-1.062 2.883-1.063 1.086-2.828 1.086-2.024 0-3.094-1.547-1.07-1.555-1.07-4.5 0-2.766 1.312-4.406 1.313-1.649 3.524-1.649.593 0 1.195.117.61.118 1.266.352z\" /></g><g transform=\"translate(375, 110) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M10.137 21.863q-1.063 0-1.688.727-.617.726-.617 1.992 0 1.258.617 1.992.625.727 1.688.727 1.062 0 1.68-.727.624-.734.624-1.992 0-1.266-.625-1.992-.617-.727-1.68-.727zm3.133-4.945v1.437q-.594-.28-1.204-.43-.601-.148-1.195-.148-1.562 0-2.39 1.055-.82 1.055-.938 3.188.46-.68 1.156-1.04.696-.367 1.531-.367 1.758 0 2.774 1.07 1.023 1.063 1.023 2.899 0 1.797-1.062 2.883-1.063 1.086-2.828 1.086-2.024 0-3.094-1.547-1.07-1.555-1.07-4.5 0-2.766 1.312-4.406 1.313-1.649 3.524-1.649.593 0 1.195.117.61.118 1.266.352z\" /></g><g transform=\"translate(0, 65) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.25 16.66h7.5v.672L9.516 28.324H7.867l3.985-10.336H6.25z\" /></g><g transform=\"translate(375, 65) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M6.25 16.66h7.5v.672L9.516 28.324H7.867l3.985-10.336H6.25z\" /></g><g transform=\"translate(0, 20) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M10 22.785q-1.125 0-1.773.602-.641.601-.641 1.656t.64 1.656q.649.602 1.774.602t1.773-.602q.649-.61.649-1.656 0-1.055-.649-1.656-.64-.602-1.773-.602zm-1.578-.672q-1.016-.25-1.586-.945-.563-.695-.563-1.695 0-1.399.993-2.211 1-.813 2.734-.813 1.742 0 2.734.813.993.812.993 2.21 0 1-.57 1.696-.563.695-1.571.945 1.14.266 1.773 1.04.641.773.641 1.89 0 1.695-1.04 2.602-1.03.906-2.96.906t-2.969-.906Q6 26.738 6 25.043q0-1.117.64-1.89.641-.774 1.782-1.04zm-.578-2.492q0 .906.562 1.414.57.508 1.594.508 1.016 0 1.586-.508.578-.508.578-1.414 0-.906-.578-1.414-.57-.508-1.586-.508-1.023 0-1.594.508-.562.508-.562 1.414z\" /></g><g transform=\"translate(375, 20) scale(0.75, 0.75)\" fill=\"#e5e5e5\" stroke=\"#e5e5e5\"><path d=\"M10 22.785q-1.125 0-1.773.602-.641.601-.641 1.656t.64 1.656q.649.602 1.774.602t1.773-.602q.649-.61.649-1.656 0-1.055-.649-1.656-.64-.602-1.773-.602zm-1.578-.672q-1.016-.25-1.586-.945-.563-.695-.563-1.695 0-1.399.993-2.211 1-.813 2.734-.813 1.742 0 2.734.813.993.812.993 2.21 0 1-.57 1.696-.563.695-1.571.945 1.14.266 1.773 1.04.641.773.641 1.89 0 1.695-1.04 2.602-1.03.906-2.96.906t-2.969-.906Q6 26.738 6 25.043q0-1.117.64-1.89.641-.774 1.782-1.04zm-.578-2.492q0 .906.562 1.414.57.508 1.594.508 1.016 0 1.586-.508.578-.508.578-1.414 0-.906-.578-1.414-.57-.508-1.586-.508-1.023 0-1.594.508-.562.508-.562 1.414z\" /></g><rect x=\"15\" y=\"330\" width=\"45\" height=\"45\" class=\"square dark a1\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"60\" y=\"330\" width=\"45\" height=\"45\" class=\"square light b1\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"105\" y=\"330\" width=\"45\" height=\"45\" class=\"square dark c1\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"150\" y=\"330\" width=\"45\" height=\"45\" class=\"square light d1\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"195\" y=\"330\" width=\"45\" height=\"45\" class=\"square dark e1\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"240\" y=\"330\" width=\"45\" height=\"45\" class=\"square light f1\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"285\" y=\"330\" width=\"45\" height=\"45\" class=\"square dark g1\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"330\" y=\"330\" width=\"45\" height=\"45\" class=\"square light h1\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"15\" y=\"285\" width=\"45\" height=\"45\" class=\"square light a2\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"60\" y=\"285\" width=\"45\" height=\"45\" class=\"square dark b2\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"105\" y=\"285\" width=\"45\" height=\"45\" class=\"square light c2\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"150\" y=\"285\" width=\"45\" height=\"45\" class=\"square dark d2\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"195\" y=\"285\" width=\"45\" height=\"45\" class=\"square light e2\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"240\" y=\"285\" width=\"45\" height=\"45\" class=\"square dark f2\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"285\" y=\"285\" width=\"45\" height=\"45\" class=\"square light g2\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"330\" y=\"285\" width=\"45\" height=\"45\" class=\"square dark h2\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"15\" y=\"240\" width=\"45\" height=\"45\" class=\"square dark a3\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"60\" y=\"240\" width=\"45\" height=\"45\" class=\"square light b3\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"105\" y=\"240\" width=\"45\" height=\"45\" class=\"square dark c3\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"150\" y=\"240\" width=\"45\" height=\"45\" class=\"square light d3\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"195\" y=\"240\" width=\"45\" height=\"45\" class=\"square dark e3\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"240\" y=\"240\" width=\"45\" height=\"45\" class=\"square light f3\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"285\" y=\"240\" width=\"45\" height=\"45\" class=\"square dark g3\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"330\" y=\"240\" width=\"45\" height=\"45\" class=\"square light h3\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"15\" y=\"195\" width=\"45\" height=\"45\" class=\"square light a4\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"60\" y=\"195\" width=\"45\" height=\"45\" class=\"square dark b4\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"105\" y=\"195\" width=\"45\" height=\"45\" class=\"square light c4\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"150\" y=\"195\" width=\"45\" height=\"45\" class=\"square dark d4\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"195\" y=\"195\" width=\"45\" height=\"45\" class=\"square light e4\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"240\" y=\"195\" width=\"45\" height=\"45\" class=\"square dark f4\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"285\" y=\"195\" width=\"45\" height=\"45\" class=\"square light g4\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"330\" y=\"195\" width=\"45\" height=\"45\" class=\"square dark h4\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"15\" y=\"150\" width=\"45\" height=\"45\" class=\"square dark a5\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"60\" y=\"150\" width=\"45\" height=\"45\" class=\"square light b5\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"105\" y=\"150\" width=\"45\" height=\"45\" class=\"square dark c5\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"150\" y=\"150\" width=\"45\" height=\"45\" class=\"square light d5\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"195\" y=\"150\" width=\"45\" height=\"45\" class=\"square dark e5\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"240\" y=\"150\" width=\"45\" height=\"45\" class=\"square light f5\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"285\" y=\"150\" width=\"45\" height=\"45\" class=\"square dark g5\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"330\" y=\"150\" width=\"45\" height=\"45\" class=\"square light h5\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"15\" y=\"105\" width=\"45\" height=\"45\" class=\"square light a6\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"60\" y=\"105\" width=\"45\" height=\"45\" class=\"square dark b6\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"105\" y=\"105\" width=\"45\" height=\"45\" class=\"square light c6\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"150\" y=\"105\" width=\"45\" height=\"45\" class=\"square dark d6\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"195\" y=\"105\" width=\"45\" height=\"45\" class=\"square light e6\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"240\" y=\"105\" width=\"45\" height=\"45\" class=\"square dark f6\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"285\" y=\"105\" width=\"45\" height=\"45\" class=\"square light g6\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"330\" y=\"105\" width=\"45\" height=\"45\" class=\"square dark h6\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"15\" y=\"60\" width=\"45\" height=\"45\" class=\"square dark a7\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"60\" y=\"60\" width=\"45\" height=\"45\" class=\"square light b7\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"105\" y=\"60\" width=\"45\" height=\"45\" class=\"square dark c7\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"150\" y=\"60\" width=\"45\" height=\"45\" class=\"square light d7\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"195\" y=\"60\" width=\"45\" height=\"45\" class=\"square dark e7\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"240\" y=\"60\" width=\"45\" height=\"45\" class=\"square light f7\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"285\" y=\"60\" width=\"45\" height=\"45\" class=\"square dark g7\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"330\" y=\"60\" width=\"45\" height=\"45\" class=\"square light h7\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"15\" y=\"15\" width=\"45\" height=\"45\" class=\"square light a8\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"60\" y=\"15\" width=\"45\" height=\"45\" class=\"square dark b8\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"105\" y=\"15\" width=\"45\" height=\"45\" class=\"square light c8\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"150\" y=\"15\" width=\"45\" height=\"45\" class=\"square dark d8\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"195\" y=\"15\" width=\"45\" height=\"45\" class=\"square light e8\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"240\" y=\"15\" width=\"45\" height=\"45\" class=\"square dark f8\" stroke=\"none\" fill=\"#d18b47\" /><rect x=\"285\" y=\"15\" width=\"45\" height=\"45\" class=\"square light g8\" stroke=\"none\" fill=\"#ffce9e\" /><rect x=\"330\" y=\"15\" width=\"45\" height=\"45\" class=\"square dark h8\" stroke=\"none\" fill=\"#d18b47\" /><use href=\"#white-king\" xlink:href=\"#white-king\" transform=\"translate(195, 330)\" /><use href=\"#white-bishop\" xlink:href=\"#white-bishop\" transform=\"translate(195, 285)\" /><use href=\"#white-pawn\" xlink:href=\"#white-pawn\" transform=\"translate(60, 240)\" /><use href=\"#black-pawn\" xlink:href=\"#black-pawn\" transform=\"translate(330, 195)\" /><use href=\"#black-knight\" xlink:href=\"#black-knight\" transform=\"translate(150, 105)\" /><use href=\"#black-king\" xlink:href=\"#black-king\" transform=\"translate(195, 15)\" /></svg>"
],
"text/plain": [
"Board('4k3/8/3n4/8/7p/1P6/4B3/4K3 b - - 0 1')"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Récupération des positions de la tablebase KBNvK\n",
"Récupération des positions de la tablebase KPvK\n",
"Récupération des positions de la tablebase KPvKP\n",
"Récupération des positions de la tablebase KQvK\n",
"Récupération des positions de la tablebase KQvKP\n",
"Récupération des positions de la tablebase KRBvKP\n",
"Récupération des positions de la tablebase KRPvKP\n",
"Récupération des positions de la tablebase KRvK\n",
"Récupération des positions de la tablebase KRvKB\n",
"Récupération des positions de la tablebase KBvK\n",
"Récupération des positions de la tablebase KNvK\n",
"Total positions récupérées: 55000\n",
"Ajoute de toutes les positions des tablebases dans Redis terminé!\n"
]
}
],
"source": [
"def get_250_random_position(tablebases, config):\n",
" positions = []\n",
" tries = 0\n",
"\n",
" while len(positions) < 10000 and tries < 5000:\n",
" board = generate_board_from_config(config)\n",
" positions.append(board)\n",
" tries += 1\n",
"\n",
" return positions\n",
"\n",
"def generate_board_from_config(config):\n",
" \"\"\"\n",
" Génère un board contenant exactement le matériel d'une config Syzygy. Exemples de config :\n",
" - 'KQvK', 'KPvKP'\n",
" Cette fonction est important car il faut générer les positions qui dont les informations sont dans la tablebases.\n",
" \"\"\"\n",
"\n",
" piece_map = {\"K\": chess.KING,\"Q\": chess.QUEEN,\"R\": chess.ROOK,\"B\": chess.BISHOP,\"N\": chess.KNIGHT,\"P\": chess.PAWN}\n",
"\n",
" white_str, black_str = config.split(\"v\") #Sépare la config entre les 2 couleurs\n",
"\n",
" board = chess.Board(None) # donne un plateau vide\n",
"\n",
" # boucles pour placer les pièces sur le plateau\n",
" for p in white_str:\n",
" piece = piece_map[p]\n",
" sq = random.choice([s for s in chess.SQUARES if board.piece_at(s) is None]) #choisi une pièce et vérifie que il n'y a pas déjà une pièce dessus\n",
" board.set_piece_at(sq, chess.Piece(piece, chess.WHITE))\n",
"\n",
" for p in black_str:\n",
" piece = piece_map[p]\n",
" sq = random.choice([s for s in chess.SQUARES if board.piece_at(s) is None])#choisi une pièce et vérifie que il n'y a pas déjà une pièce dessus\n",
" board.set_piece_at(sq, chess.Piece(piece, chess.BLACK))\n",
"\n",
" # désactive les règles des échecs.\n",
" board.castling_rights = 0\n",
" board.ep_square = None\n",
"\n",
" # Donne une couleur aléatoire pour savoir quelle couleur doit jouer le prochain coup.\n",
" board.turn = random.choice([chess.WHITE, chess.BLACK])\n",
"\n",
" if not board.is_valid():\n",
" return generate_board_from_config(config)\n",
"\n",
" return board\n",
"\n",
"def add_tablebase_to_redis():\n",
" #Connect to Redis server\n",
" redis_server = redis.Redis(host='localhost', port=6379, db=0)\n",
" \n",
" tablebases_path = \"tablebases/\" #Chemin vers les tables bases Syzygy\n",
"\n",
" tablebases = chess.syzygy.open_tablebase(tablebases_path)\n",
"\n",
" available_tables = set()\n",
" for f in os.listdir(tablebases_path):\n",
" if f.endswith(\".rtbw\") or f.endswith(\".rtbz\"):\n",
" available_tables.add(f.split(\".\")[0])\n",
"\n",
" print(\"Configs ok:\", available_tables)\n",
"\n",
" position = chess.Board(\"4k3/8/3n4/8/7p/1P6/4B3/4K3 b - - 0 1\") #Position d'exemple\n",
" display(position) \n",
" \n",
" configs = [\"KBNvK\",\"KPvK\",\"KPvKP\",\"KQvK\",\"KQvKP\",\"KRBvKP\",\"KRPvKP\",\"KRvK\",\"KRvKB\",\"KBvK\",\"KNvK\"]\n",
" config_valide = [c for c in configs if c in available_tables]\n",
" #Configurations de toute les tablebases que l'on utilisera dans le projet.\n",
" all_positions = []\n",
" for config in config_valide:\n",
" print(f\"Récupération des positions de la tablebase {config}\")\n",
" position = get_250_random_position(tablebases,config)\n",
" all_positions.extend(position) #Ajout des positions générées à la liste globale\n",
" \n",
" print(f\"Total positions récupérées: {len(all_positions)}\")\n",
" print(\"Ajoute de toutes les positions des tablebases dans Redis terminé!\")\n",
"\n",
"if __name__ == \"__main__\":\n",
" add_tablebase_to_redis() "
]
},
{
"cell_type": "markdown",
"id": "1b443c8c",
"metadata": {},
"source": [
"## Accès à Redis\n",
"\n",
"Nous avons rajouter 250 positions apparentant à chacune des tablesbases présent dans le dossier. Il y a des configurations ayant 3,4 ainsi que 5 pièces pour voir si cela a une incidence sur le temps d'accès à Redis.\n",
"\n",
"Pour la suite, nous allons donc pouvoir passer sur Redis pour vérifier cette hypothèse et faire d'autres tests sur notre base.\n",
"\n",
"## Benchmark redis"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "8d49b928-7522-4727-b6d8-224e2bd3a1b7",
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-06T09:27:00.752325Z",
"start_time": "2025-12-06T09:27:00.748915Z"
}
},
"outputs": [],
"source": [
"def benchmark_redis(redis_serveur, pos):\n",
" latency = []\n",
" start_time_all = time.time()\n",
"\n",
" for board in pos:\n",
" fen = board.fen()\n",
" start_individual = time.time()\n",
" redis_serveur.hset(fen, mapping={\"board\": board.fen()})\n",
" latency.append(time.time() - start_individual)\n",
"\n",
" total_time_all=time.time()-start_time_all\n",
" latency= np.array(latency)\n",
"\n",
" return{\n",
" \"count\": len(pos),\n",
" \"average_latency\": np.mean(latency),\n",
" \"p50\": np.percentile(latency,50),\n",
" \"p90\": np.percentile(latency,90),\n",
" \"p95\": np.percentile(latency,95),\n",
" \"p99\": np.percentile(latency,99),\n",
" \"std\": np.std(latency),\n",
" \"min\": np.min(latency),\n",
" \"max\": np.max(latency),\n",
" \"total_time\": total_time_all,\n",
" \"latency\": latency,\n",
" \"rps\": len(latency)/total_time_all,\n",
" }\n",
"\n",
"def benchmark_syzygy(tablebases, pos):\n",
" latency = []\n",
" start_time_all = time.time()\n",
"\n",
" for board in pos:\n",
" try:\n",
" start = time.time()\n",
" tablebases.probe_wdl(board)\n",
" tablebases.probe_dtz(board)\n",
" latency.append(time.time() - start)\n",
" except chess.syzygy.MissingTableError:\n",
" continue\n",
"\n",
" total_time_all=time.time()-start_time_all\n",
"\n",
" return{\n",
" \"count\": len(pos),\n",
" \"average_latency\": np.mean(latency),\n",
" \"p50\": np.percentile(latency,50),\n",
" \"p90\": np.percentile(latency,90),\n",
" \"p95\": np.percentile(latency,95),\n",
" \"p99\": np.percentile(latency,99),\n",
" \"std\": np.std(latency),\n",
" \"min\": np.min(latency),\n",
" \"max\": np.max(latency),\n",
" \"total_time\": total_time_all,\n",
" \"latency\": latency,\n",
" \"rps\": len(latency)/total_time_all\n",
" }\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0d955b0d-dc80-4518-954b-7c2df295adca",
"metadata": {
"ExecuteTime": {
"end_time": "2025-12-06T10:18:18.501308Z",
"start_time": "2025-12-06T10:18:18.393765Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BENCHMARK SYZYGY\n",
"BENCHMARK REDIS\n",
"Redis latency array length: 55000\n",
"Syzygy latency array length: 50215\n",
" test statistic p-value \\\n",
"0 paired t-test 93.454797 0.0 \n",
"1 KS-test 0.690232 0.0 \n",
"\n",
" interpretation \n",
"0 H0: mean latency equal (Redis vs Syzygy) \n",
"1 H0: same latency distribution (Redis vs Syzygy) \n"
]
}
],
"source": [
"def statistical_tests(bench_redis, bench_syzygy):\n",
" redis_lat = np.array(bench_redis[\"latency\"], dtype=np.float64)\n",
" syz_lat = np.array(bench_syzygy[\"latency\"], dtype=np.float64)\n",
" \n",
" min_len = min(len(redis_lat), len(syz_lat))\n",
" redis_lat = redis_lat[:min_len]\n",
" syz_lat = syz_lat[:min_len]\n",
"\n",
" # PAIRED T-Test (Comparaison median)\n",
" t_stat, t_p = stats.ttest_rel(syz_lat, redis_lat)\n",
"\n",
" # KS Test (Comparaison distribution)\n",
" ks_stat, ks_p = stats.ks_2samp(syz_lat, redis_lat)\n",
"\n",
" df_stats = pd.DataFrame({\n",
" \"test\": [\"paired t-test\", \"KS-test\"],\n",
" \"statistic\": [t_stat, ks_stat],\n",
" \"p-value\": [t_p, ks_p],\n",
" \"interpretation\": [\n",
" \"H0: mean latency equal (Redis vs Syzygy)\",\n",
" \"H0: same latency distribution (Redis vs Syzygy)\"\n",
" ]\n",
" })\n",
"\n",
" print(df_stats)\n",
" return df_stats\n",
"\n",
"\n",
"def run_experiment_test_latency():\n",
" redis_server = redis.Redis(host=\"localhost\", port=6379, db=0)\n",
" tablebases = chess.syzygy.open_tablebase(\"tablebases/\")\n",
"\n",
" configs = [\"KBNvK\",\"KPvK\",\"KPvKP\",\"KQvK\",\"KQvKP\",\"KRBvKP\",\"KRPvKP\",\"KRvK\",\"KRvKB\",\"KBvK\",\"KNvK\"]\n",
"\n",
" all_positions = []\n",
" for config in configs:\n",
" all_positions += get_250_random_position(tablebases, config)\n",
"\n",
" # Benchmark Syzygy\n",
" bench_syzygy = benchmark_syzygy(tablebases, all_positions)\n",
" print(\"BENCHMARK SYZYGY\")\n",
" #print(bench_syzygy)\n",
"\n",
" # Benchmark Redis\n",
" bench_redis = benchmark_redis(redis_server, all_positions)\n",
" print(\"BENCHMARK REDIS\")\n",
" #print(bench_redis)\n",
"\n",
" # Length info\n",
" print(f\"Redis latency array length: {len(bench_redis['latency'])}\")\n",
" print(f\"Syzygy latency array length: {len(bench_syzygy['latency'])}\")\n",
"\n",
" return {\n",
" \"bench_syzygy\": bench_syzygy,\n",
" \"bench_redis\": bench_redis\n",
" }\n",
"\n",
"if __name__ == \"__main__\":\n",
" results = run_experiment_test_latency()\n",
" statistical_tests(results[\"bench_redis\"], results[\"bench_syzygy\"])"
]
},
{
"cell_type": "markdown",
"id": "37b01080",
"metadata": {},
"source": [
"Cette partie teste les accès Redis, afin de savoir si le nombre de pièces de la configuration importe sur le temps d'accès : "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "a68060e1-0052-4446-a0d3-40bc1756f210",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"=== Benchmark Redis GET : 3pieces ===\n",
"\n",
"=== Benchmark Redis GET : 4pieces ===\n",
"\n",
"=== Benchmark Redis GET : 5pieces ===\n"
]
},
{
"data": {
"text/plain": [
"{'3pieces': {'mean_ms': np.float64(0.4743400499864947),\n",
" 'median_ms': np.float64(0.4443719999471796),\n",
" 'min_ms': np.float64(0.30335500014189165),\n",
" 'max_ms': np.float64(3.0856469993523206),\n",
" 'std_ms': np.float64(0.2824736354026385)},\n",
" '4pieces': {'mean_ms': np.float64(0.45132315999580896),\n",
" 'median_ms': np.float64(0.4520549996414047),\n",
" 'min_ms': np.float64(0.2539389997764374),\n",
" 'max_ms': np.float64(0.838474999909522),\n",
" 'std_ms': np.float64(0.13465422472708688)},\n",
" '5pieces': {'mean_ms': np.float64(0.5181703400103288),\n",
" 'median_ms': np.float64(0.4918450003970065),\n",
" 'min_ms': np.float64(0.3080989999943995),\n",
" 'max_ms': np.float64(1.0084479999932228),\n",
" 'std_ms': np.float64(0.11421552341082152)}}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"\"\"\"\n",
"redis_client : instance redis.Redis déjà créée\n",
"test_positions : dict {\"3men\": [...], \"4men\": [...], \"5men\": [...]}\n",
"\"\"\"\n",
"def benchmark_redis_get_comparison(redis_client, test_positions: dict, iterations=100):\n",
"\n",
" results = {}\n",
"\n",
" for label, fens in test_positions.items():\n",
" print(f\"\\n=== Benchmark Redis GET : {label} ===\")\n",
"\n",
" times = np.zeros(iterations)\n",
"\n",
" for i in range(iterations):\n",
" fen = random.choice(fens)\n",
" key = f\"tb:{fen}\"\n",
"\n",
" start = time.perf_counter()\n",
" _ = redis_client.get(key)\n",
" times[i] = time.perf_counter() - start\n",
"\n",
" results[label] = {\n",
" \"mean_ms\": np.mean(times) * 1000,\n",
" \"median_ms\": np.median(times) * 1000,\n",
" \"min_ms\": np.min(times) * 1000,\n",
" \"max_ms\": np.max(times) * 1000,\n",
" \"std_ms\": np.std(times) * 1000,\n",
" }\n",
" return results\n",
"\n",
"\n",
"#IMPORTANT : Es-ce qu'on garde ca comme ca ? \n",
"TEST_POSITIONS = {\n",
" \"3pieces\": [\n",
" \"K7/8/8/8/8/8/8/k7 w - - 0 1\",\n",
" \"KB6/8/8/8/8/8/8/k7 w - - 0 1\",\n",
" \"KN6/8/8/8/8/8/8/k7 w - - 0 1\",\n",
" ],\n",
" \"4pieces\": [\n",
" \"KQ6/8/8/8/8/8/8/k7 w - - 0 1\",\n",
" \"KP6/8/8/8/8/8/8/k7 w - - 0 1\",\n",
" \"KQ6/kr6/8/8/8/8/8/8 w - - 0 1\",\n",
" ],\n",
" \"5pieces\": [\n",
" \"KQ6/8/8/Kp6/8/8/8/k7 w - - 0 1\",\n",
" \"KR6/1p6/8/8/8/8/8/k7 w - - 0 1\",\n",
" \"KRP5/1p6/8/8/8/8/8/k7 w - - 0 1\",\n",
" ],\n",
"}\n",
"\n",
"redis_server = redis.Redis(host=\"localhost\", port=6379, db=0)\n",
"benchmark_redis_get_comparison(redis_server, TEST_POSITIONS, 100)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "a68060e1-0052-4446-a0d3-40bc1756f210",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"MEMORY USAGE REDIS\n",
"Memory Redis: 9.43M\n"
]
},
{
"data": {
"text/plain": [
"'\\n#Test Mémoire Syzygy\\nimport psutil\\n\\ntablebases = chess.syzygy.open_tablebase(\"tablebases/\")\\n\\n#Récuperer les données de proccesus de Syzygy\\nprocess = psutil.Process(os.getpid())\\nmem_bytes = process.memory_info().rss\\nmem_mb = mem_bytes / (1024**2)\\nprint(\"MEMORY USAGE SYZYGY\")\\nprint(f\"Memory Syzygy: {mem_mb}\")\\n'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#Test Mémoire Redis ( Stockage du Redis )\n",
"redis_server = redis.Redis(host=\"localhost\", port=6379, db=0)\n",
"info= redis_server.info(\"memory\")\n",
"mem_human = info[\"used_memory_human\"]\n",
"print(\"MEMORY USAGE REDIS\")\n",
"print(f\"Memory Redis: {mem_human}\")\n",
"\n",
"\"\"\"\n",
"#Test Mémoire Syzygy\n",
"import psutil\n",
"\n",
"tablebases = chess.syzygy.open_tablebase(\"tablebases/\")\n",
"\n",
"#Récuperer les données de proccesus de Syzygy\n",
"process = psutil.Process(os.getpid())\n",
"mem_bytes = process.memory_info().rss\n",
"mem_mb = mem_bytes / (1024**2)\n",
"print(\"MEMORY USAGE SYZYGY\")\n",
"print(f\"Memory Syzygy: {mem_mb}\")\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "d6d03e08",
"metadata": {},
"outputs": [],
"source": [
"def benchmark_hash(redis_serveur, pos):\n",
" latency = []\n",
" start_time_all = time.perf_counter()\n",
" \n",
" for board in pos:\n",
" fen = board.fen()\n",
" key = hashlib.md5(fen.encode()).hexdigest()[:16]\n",
" \n",
" start_individual = time.perf_counter()\n",
" results = redis_serveur.hgetall(key)\n",
" latency.append(time.perf_counter() - start_individual)\n",
" \n",
" total_time_all = time.perf_counter() - start_time_all\n",
" latency = np.array(latency)\n",
" \n",
" return {\n",
" \"count\": len(pos),\n",
" \"average_latency\": latency.mean(),\n",
" \"p50\": np.percentile(latency, 50),\n",
" \"p90\": np.percentile(latency, 90),\n",
" \"p95\": np.percentile(latency, 95),\n",
" \"p99\": np.percentile(latency, 99),\n",
" \"std\": latency.std(),\n",
" \"min\": latency.min(),\n",
" \"max\": latency.max(),\n",
" \"total_time\": total_time_all,\n",
" \"latency\": latency,\n",
" \"rps\": len(latency) / total_time_all,\n",
" }"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "46157e5c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Configs ok: {'KRvK', 'KQvKP', 'KRvKB', 'KNvK', 'KRBvKP', 'KBvK', 'KBNvK', 'KPvK', 'KPvKP', 'KRPvKP', 'KQvK'}\n",
"Récupération des positions de la tablebase KBNvK\n",
"Récupération des positions de la tablebase KPvK\n",
"Récupération des positions de la tablebase KPvKP\n",
"Récupération des positions de la tablebase KQvK\n",
"Récupération des positions de la tablebase KQvKP\n",
"Récupération des positions de la tablebase KRBvKP\n",
"Récupération des positions de la tablebase KRPvKP\n",
"Récupération des positions de la tablebase KRvK\n",
"Récupération des positions de la tablebase KRvKB\n",
"Total positions récupérées: 2250\n",
"Ajoute de toutes les positions hashés des tablebases dans Redis terminé!\n"
]
}
],
"source": [
"def get_250_random_position(tablebases, config):\n",
" positions = []\n",
" tries = 0\n",
"\n",
" while len(positions) < 250 and tries < 500:\n",
" board = generate_board_from_config(config)\n",
" try:\n",
" tablebases.probe_wdl(board) # thử probe WDL\n",
" positions.append(board)\n",
" except chess.syzygy.MissingTableError:\n",
" pass # bỏ qua nếu table không tồn tại\n",
" tries += 1\n",
" return positions\n",
"\n",
"def add_tablebase_to_redis():\n",
" h = hashlib.new('sha512_256')\n",
" #Connect to Redis server\n",
" redis_server = redis.Redis(host='localhost', port=6379, db=1) #db1 pour H4\n",
" \n",
" tablebases_path = \"tablebases/\" #Chemin vers les tables bases Syzygy\n",
"\n",
" tablebases = chess.syzygy.open_tablebase(tablebases_path)\n",
"\n",
" available_tables = set()\n",
" for f in os.listdir(tablebases_path):\n",
" if f.endswith(\".rtbw\") or f.endswith(\".rtbz\"):\n",
" available_tables.add(f.split(\".\")[0])\n",
"\n",
" print(\"Configs ok:\", available_tables)\n",
" \n",
" configs = [\"KBNvK\",\"KPvK\",\"KPvKP\",\"KQvK\",\"KQvKP\",\"KRBvKP\",\"KRPvKP\",\"KRvK\",\"KRvKB\"]\n",
" config_valide = [c for c in configs if c in available_tables]\n",
" #Configurations de toute les tablebases que l'on utilisera dans le projet.\n",
" all_positions = []\n",
" for config in config_valide:\n",
" print(f\"Récupération des positions de la tablebase {config}\")\n",
" position = get_250_random_position(tablebases,config)\n",
" all_positions.extend(position) #Ajout des positions générées à la liste globale\n",
" \n",
" print(f\"Total positions récupérées: {len(all_positions)}\")\n",
" for position in all_positions:\n",
" try:\n",
" fen = position.fen()\n",
" key = hashlib.md5(fen.encode()).hexdigest()[:16] #Limite à 16 caractères\n",
" wdl = tablebases.probe_wdl(position)\n",
" dtz = tablebases.probe_dtz(position)\n",
" redis_server.hset(key, mapping={\"wdl\": wdl, \"dtz\": dtz}) \n",
" except (KeyError,chess.syzygy.MissingTableError): #vérifie que les positions générés appartiennent bien au table du projet seulement\n",
" continue \n",
" \n",
" print(\"Ajoute de toutes les positions hashés des tablebases dans Redis terminé!\")\n",
"\n",
"if __name__ == \"__main__\":\n",
" add_tablebase_to_redis()\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "099ce824",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"BENCHMARK REDIS (FEN)\n",
"{'count': 2250, 'average_latency': np.float64(0.0007091928058200412), 'p50': np.float64(0.0006681680679321289), 'p90': np.float64(0.0009292125701904298), 'p95': np.float64(0.00102473497390747), 'p99': np.float64(0.0013124537467956525), 'std': np.float64(0.00022609616592649846), 'min': np.float64(0.0004031658172607422), 'max': np.float64(0.004224300384521484), 'total_time': 2.1053922176361084, 'latency': array([0.00342536, 0.00068593, 0.00071573, ..., 0.00083399, 0.00082922,\n",
" 0.00101638], shape=(2250,)), 'rps': 1068.6844860318968}\n",
"BENCHMARK REDIS (HASH)\n",
"{'count': 2250, 'average_latency': np.float64(0.0004489188648941409), 'p50': np.float64(0.0004307850003897329), 'p90': np.float64(0.0005560255000091274), 'p95': np.float64(0.0006055185504919784), 'p99': np.float64(0.000822205319836939), 'std': np.float64(0.00018291225647658574), 'min': np.float64(0.00024306299928866792), 'max': np.float64(0.003079133999563055), 'total_time': 1.5033779259993025, 'latency': array([0.00307913, 0.00059742, 0.00061489, ..., 0.00038755, 0.00035628,\n",
" 0.00050254], shape=(2250,)), 'rps': 1496.6296638314775}\n",
"Redis FEN latency array length: 2250\n",
"Redis Hash latency array length: 2250\n",
"\n",
"============================================================\n",
"MEMORY USAGE BY KEY (ESTIMATION)\n",
"============================================================\n",
"Taille moyenne clé FEN: 136.46 bytes\n",
"Taille moyenne clé Hash: 97.84 bytes\n",
"\n",
"Estimation pour 66009 clés:\n",
" FEN: 8.59 MB\n",
" Hash: 6.16 MB\n",
" Gain: 28.3%\n",
"============================================================\n",
" test statistic p-value \\\n",
"0 paired t-test -44.041712 4.787276e-306 \n",
"1 KS-test 0.691556 0.000000e+00 \n",
"\n",
" interpretation \n",
"0 H0: mean latency equal (Redis vs Syzygy) \n",
"1 H0: same latency distribution (Redis vs Syzygy) \n"
]
}
],
"source": [
"def run_experiment():\n",
" redis_server = redis.Redis(host=\"localhost\", port=6379, db=0)\n",
" redis_hash = redis.Redis(host=\"localhost\", port=6379, db=1)\n",
" tablebases = chess.syzygy.open_tablebase(\"tablebases/\")\n",
" configs = [\"KBNvK\",\"KPvK\",\"KPvKP\",\"KQvK\",\"KQvKP\",\"KRBvKP\",\"KRPvKP\",\"KRvK\",\"KRvKB\"]\n",
" all_positions = []\n",
" for config in configs:\n",
" all_positions += get_250_random_position(tablebases, config)\n",
" valid_positions = []\n",
" for board in all_positions:\n",
" try:\n",
" tablebases.probe_wdl(board)\n",
" valid_positions.append(board)\n",
" except chess.syzygy.MissingTableError:\n",
" continue\n",
" print(\"BENCHMARK REDIS (FEN)\")\n",
" bench_redis = benchmark_redis(redis_server, valid_positions)\n",
" print(bench_redis)\n",
" print(\"BENCHMARK REDIS (HASH)\")\n",
" bench_hash = benchmark_hash(redis_hash, valid_positions)\n",
" print(bench_hash)\n",
" print(f\"Redis FEN latency array length: {len(bench_redis['latency'])}\")\n",
" print(f\"Redis Hash latency array length: {len(bench_hash['latency'])}\")\n",
" print(\"\\n\" + \"=\" * 60)\n",
" print(\"MEMORY USAGE BY KEY (ESTIMATION)\")\n",
" print(\"=\" * 60)\n",
"\n",
" # Échantillonner 50 clés de chaque base\n",
" sample_fen = [redis_server.randomkey() for _ in range(50)]\n",
" mem_per_key_fen = [redis_server.memory_usage(k) for k in sample_fen if k]\n",
" avg_fen = np.mean(mem_per_key_fen)\n",
"\n",
" sample_hash = [redis_hash.randomkey() for _ in range(50)]\n",
" mem_per_key_hash = [redis_hash.memory_usage(k) for k in sample_hash if k]\n",
" avg_hash = np.mean(mem_per_key_hash)\n",
"\n",
" nb_keys = redis_server.dbsize()\n",
" estimated_fen = avg_fen * nb_keys\n",
" estimated_hash = avg_hash * nb_keys\n",
"\n",
" print(f\"Taille moyenne clé FEN: {avg_fen:.2f} bytes\")\n",
" print(f\"Taille moyenne clé Hash: {avg_hash:.2f} bytes\")\n",
" print(f\"\\nEstimation pour {nb_keys} clés:\")\n",
" print(f\" FEN: {estimated_fen / (1024*1024):.2f} MB\")\n",
" print(f\" Hash: {estimated_hash / (1024*1024):.2f} MB\")\n",
" print(f\" Gain: {(1 - avg_hash/avg_fen) * 100:.1f}%\")\n",
" print(\"=\" * 60)\n",
" \n",
" return {\n",
" \"bench_redis\": bench_redis,\n",
" \"bench_hash\": bench_hash\n",
" }\n",
"\n",
"if __name__ == \"__main__\":\n",
" results = run_experiment()\n",
" statistical_tests(results[\"bench_redis\"], results[\"bench_hash\"])\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}