Maison >développement back-end >Tutoriel Python >Construire un jeu d'échecs avec Python et OpenAI

Construire un jeu d'échecs avec Python et OpenAI

Patricia Arquette
Patricia Arquetteoriginal
2024-11-26 06:30:12727parcourir

Building a Chess Game with Python and OpenAI

J'aime coder de petites choses idiotes chaque fois que j'ai du temps libre pendant le week-end. Une de ces idées s'est transformée en un jeu d'échecs en ligne de commande dans lequel vous pouvez jouer contre OpenAI. Je l'ai appelé "SkakiBot", inspiré de "Skaki", le mot grec pour échecs.

L'excellente bibliothèque python-chess s'occupe de toutes les mécaniques d'échecs. L’objectif n’est pas de construire un moteur d’échecs à partir de zéro mais de démontrer avec quelle facilité OpenAI peut être intégré dans un projet comme celui-ci.

Plongeons dans le code et voyons comment tout cela s'articule !

Le point d'entrée

Nous commencerons par mettre en place une boucle de jeu de base qui prend en compte les entrées de l'utilisateur et prépare les bases de la logique des échecs.

def main():
    while True:
        user_input = input("Enter your next move: ").strip()

        if user_input.lower() == 'exit':
            print("Thanks for playing SkakiBot. Goodbye!")
            break

        if not user_input:
            print("Move cannot be empty. Please try again.")
            continue

        print(f"You entered: {user_input}")

À ce stade, le code ne fait pas grand-chose. Il demande simplement à l'utilisateur une saisie, la valide et l'imprime :

Enter your next move: e2e4
You entered: e2e4
Enter your next move: exit
Thanks for playing SkakiBot. Goodbye!

Ajout de la bibliothèque d'échecs

Ensuite, nous introduisons python-chess, qui gérera la gestion du plateau, la validation des mouvements et les scénarios de fin de partie.

pip install chess

Une fois la bibliothèque installée, nous pouvons initialiser un échiquier et l'imprimer avant de demander une saisie à l'utilisateur :

import chess

def main():
    board = chess.Board()

    while not board.is_game_over():
        print(board)

        user_input = input("Enter your next move (e.g., e2e4): ").strip()

        if user_input.lower() == 'exit':
            print("Thanks for playing SkakiBot. Goodbye!")
            break

Ajout d'une validation de déplacement

Pour rendre le jeu fonctionnel, nous devons valider les entrées de l'utilisateur et appliquer les mouvements légaux au plateau. Le format UCI (Universal Chess Interface) est utilisé pour les mouvements, où vous spécifiez la case de début et de fin (par exemple, e2e4).

def main():
    board = chess.Board()

    while not board.is_game_over():
        # ...

        try:
            move = chess.Move.from_uci(user_input)
            if move in board.legal_moves:
                board.push(move)
                print(f"Move '{user_input}' played.")
            else:
                print("Invalid move. Please enter a valid move.")
        except ValueError:
            print("Invalid move format. Use UCI format like 'e2e4'.")

Gérer les fins de partie

Nous pouvons désormais gérer des scénarios de fin de jeu comme l'échec et mat ou l'impasse :

def main():
    board = chess.Board()

    while not board.is_game_over():
        # ...

    if board.is_checkmate():
        print("Checkmate! The game is over.")
    elif board.is_stalemate():
        print("Stalemate! The game is a draw.")
    elif board.is_insufficient_material():
        print("Draw due to insufficient material.")
    elif board.is_seventyfive_moves():
        print("Draw due to the seventy-five-move rule.")
    else:
        print("Game ended.")

A ce stade, vous jouez pour les deux côtés. Vous pouvez le tester en tentant Fool's Mate avec les mouvements suivants au format UCI :

  • f2f3
  • e7e5
  • g2g4
  • d8h4

Cela se traduit par un échec et mat rapide.

Intégration d'OpenAI

Il est maintenant temps de laisser l’IA prendre le dessus. OpenAI évaluera l'état du tableau et suggérera la meilleure décision.

Récupérer la clé OpenAI

Nous commençons par récupérer la clé API OpenAI depuis l'environnement :

# config.py

import os

def get_openai_key() -> str:
    key = os.getenv("OPENAI_API_KEY")
    if not key:
        raise EnvironmentError("OpenAI API key is not set. Please set 'OPENAI_API_KEY' in the environment.")
    return key

Génération de mouvements IA

Ensuite, nous écrivons une fonction pour envoyer l'état de la carte - au format Forsyth-Edwards Notation (FEN) - à OpenAI et récupérons un mouvement suggéré :

def get_openai_move(board):
    import openai
    openai.api_key = get_openai_key()
    board_fen = board.fen()

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": (
                "You are an expert chess player and assistant. Your task is to "
                "analyse chess positions and suggest the best move in UCI format."
            )},
            {"role": "user", "content": (
                "The current chess board is given in FEN notation:\n"
                f"{board_fen}\n\n"
                "Analyse the position and suggest the best possible move. Respond "
                "with a single UCI move, such as 'e2e4'. Do not provide any explanations."
            )}
        ])

    suggested_move = response.choices[0].message.content.strip()
    return suggested_move

L'invite est simple, mais elle fonctionne bien pour générer des mouvements valides. Il fournit suffisamment de contexte pour qu'OpenAI comprenne l'état du conseil d'administration et réponde par une décision légale au format UCI.

L'état du plateau est envoyé au format FEN, ce qui donne un aperçu complet du jeu, y compris la position des pièces, à qui appartient le tour, les droits de roque et d'autres détails. C'est idéal car l'API d'OpenAI est sans état et ne conserve pas d'informations entre les requêtes, chaque requête doit donc inclure tout le contexte nécessaire.

Pour l'instant, le modèle est codé en dur sous gpt-3.5-turbo pour plus de simplicité, mais il serait préférable de le récupérer depuis l'environnement, comme nous l'avons fait pour la clé API. Cela faciliterait la mise à jour ou les tests ultérieurs avec différents modèles.

La boucle finale du jeu

Enfin, nous pouvons intégrer l'IA dans la boucle principale du jeu. L'IA évalue le tableau après chaque mouvement de l'utilisateur et joue sa réponse.

def main():
    while True:
        user_input = input("Enter your next move: ").strip()

        if user_input.lower() == 'exit':
            print("Thanks for playing SkakiBot. Goodbye!")
            break

        if not user_input:
            print("Move cannot be empty. Please try again.")
            continue

        print(f"You entered: {user_input}")

C'est ça ! Vous disposez désormais d'un jeu d'échecs fonctionnel où vous pouvez jouer contre OpenAI. Il y a encore beaucoup à faire dans le code, mais il est déjà jouable. Une prochaine étape amusante serait d’opposer deux IA et de les laisser s’affronter.

Le code est disponible sur GitHub. Amusez-vous à expérimenter !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn