{ "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": 2, "id": "78fdf40a", "metadata": {}, "outputs": [], "source": [ "#import du projet\n", "\n", "import redis\n", "import time\n", "import chess\n", "import chess.syzygy\n", "import random\n", "from IPython.display import display\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": 16, "id": "338f123d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Value set. Retrieved from Redis: example_value\n", "Time == 1 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 2 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 3 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 4 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 5 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 6 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 7 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 8 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 9 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n", "Time == 10 seconds\n", "Retrieved from Redis: b'example_value'\n", "Retrieved from Redis: None\n" ] } ], "source": [ "#Connect to Redis server\n", "\n", "def do_this():\n", "\n", " redis_server = redis.Redis(host='localhost', port=6379, db=0)\n", "\n", " #Set and get a simple key-value pair \n", "\n", " redis_server.set('example_key', 'example_value')\n", " value = redis_server.get('example_key')\n", "\n", " print(\"Value set. Retrieved from Redis:\", value.decode('utf-8'))\n", "\n", " count = 1\n", " while count <= 10:\n", " print(f\"Time == {count} seconds\")\n", " value = redis_server.get('example_key')\n", " print(f\"Retrieved from Redis: {value}\")\n", " print(f\"Retrieved from Redis: {redis_server.get(name = 'exemple2')}\")\n", "\n", " count +=1\n", " time.sleep(1)\n", " \n", "if __name__ == \"__main__\":\n", " do_this()" ] }, { "cell_type": "code", "execution_count": null, "id": "e6058974", "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "
. . . . k . . .\n",
       ". . . . . . . .\n",
       ". . . n . . . .\n",
       ". . . . . . . .\n",
       ". . . . . . . p\n",
       ". P . . . . . .\n",
       ". . . . B . . .\n",
       ". . . . K . . .
" ], "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", "Total positions récupérées: 2250\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) < 250 and tries < 5000:\n", " board = generate_board_from_config(config)\n", "\n", " try:\n", " if tablebases.probe_wdl(board) is not None:\n", " positions.append(board)\n", " except KeyError:\n", " pass\n", "\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\")\n", "\n", " board = chess.Board(None) # plateau vide\n", "\n", " # Placer les pièces blanches\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])\n", " board.set_piece_at(sq, chess.Piece(piece, chess.WHITE))\n", "\n", " # Placer les pièces noires\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])\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", " # Couleur aléatoire\n", " board.turn = random.choice([chess.WHITE, chess.BLACK])\n", "\n", " # Vérifier que la position est légale\n", " if not board.is_valid():\n", " return generate_board_from_config(config) # retry\n", "\n", " return board\n", "\n", "def add_tabblebase_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", " 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\"]\n", " #Configurations de toute les tablebases que l'on utilisera dans le projet.\n", " all_positions = []\n", " for config in configs:\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", " wdl = tablebases.probe_wdl(position)\n", " dtz = tablebases.probe_dtz(position)\n", " redis_server.hset(fen, mapping={\"wdl\": wdl, \"dtz\": dtz}) \n", " except (KeyError,chess.syzygy.MissingTableError):\n", " continue \n", " \n", " print(\"Ajoute de toutes les positions des tablebases dans Redis terminé!\")\n", "\n", "if __name__ == \"__main__\":\n", " add_tabblebase_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." ] } ], "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 }