PytactX – Prise en main 🚀

Vous souhaitez vous initier à la programmation avec Python tout en vous amusant ? Dans ce tutoriel, vous allez apprendre comment programmer un agent gladiateur dans une arène de jeu pyTactX, pour affronter les agents ennemis en temps réel.

1. Connexion à une arène du jeu

Avant de se lancer dans le combat dans l’arène, il vous faut d’abord obtenir vos identifiants. Pour cela, rien de plus simple, rendez vous sur jusdeliens.com/pytactx-free/ et renseignez votre Prénom, Nom et Email. Vous recevrez vos identifiants gratuitement sous 48h.

Une fois reçus par mail, à vos claviers et neurones ! Sur jusdeliens.com/play/pytactx/ renseignez vos username et password communiqués par mail, puis sélectionnez l’arène que vous souhaitez rejoindre.

L’accès aux arènes publiques est entièrement gratuit mais limité. Elles sont ouvertes à l’occasion d’affrontements ou de formations jusdeliens dont les dates vous seront communiquées via la newsletter (pour vous abonner, cliquez ici).

Pour plus de liberté, vous pouvez créer votre propre arène privée hébergée sur un serveur jusdeliens, ouverte 24h/24, 7 jours sur 7 et accessible dans le monde entier avec Pytactx ARENA. Les tarifs sont indiqués ici. Dans ce cas, votre arène privée sera uniquement accessible à ceux à qui vous communiquerez son nom.

Pour les plus téméraires, un tutoriel sera bientôt mis en ligne pour créer votre arène et l’héberger sur votre serveur privé (avec OVH ou free). Vous pouvez aussi vous inscrire à une session de formation jusdeliens en cliquant ici.

2. Vos premiers pas

2.1. Les modules

Premier concept à maîtriser : la notion de module en python.

Un module en programmation (appelé encore librairie) est un fichier développé par d’autres personnes. Il contient un autre programme que vous allez pouvoir utiliser dans votre programme principale. Son intérêt principal est de vous faire gagner du temps pour ne pas avoir à tout recoder vous-même.

Pour jouer à pyTactX, on va importer le module pytactx contenu dans un autre fichier, à côté de votre fichier main dans l’arborescence du projet.

Il y a par défaut 2 fichiers programmes dans votre projet. Le fichier main.py contient votre programme principal, c’est dedans que vous développerez votre programme. Le fichier pytactx.py contient tout ce qu’il vous faut pour jouer à pyTactX. L’extension .py signifie programme PYthon.

Dans le fichier main.py, ajoutons donc au début du programme la ligne suivante pour pouvoir jouer à pyTactX :

import pytactx

Et voilà ! Nous pouvons désormais créer notre agent pour combattre dans l’arène !

2.2. Les variables

Pour incarner notre agent, il nous faut maîtriser un 2e concept : la notion de variable.

Dans un programme, une variable est comme une boîte de rangement. Elle vous permet de stocker une information (un texte, un nombre, une image …) afin de la manipuler par la suite. On donne un nom à cette boîte afin de pouvoir s’en servir par la suite.

Dans pyTactX, la première variable à créer est votre agent. Pour créer cette variable nommée « agent » en Python, on utilise l’opérateur égal « = » (dit aussi opérateur d’affectation). Cette opérateur va nous permettre de placer dans notre « boîte » agent ce qu’il y a à droite du égal (on dit qu’on initialise la variable).

agent = pytactx.Agent(nom="LeNomDeMonSuperAgent", username="VotreUserName", password="VotrePassword", arene="nomDeLArene")

L’expression à droite permet de créer votre agent et de le connecter à l’arène de jeu. A vous de remplacer les caractères entre guillemets:

  • « LeNomDeMonSuperAgent » : c’est le nom de votre agent qui apparaitra dans l’arène
  • « VotreUserName » : à remplacer par le username transmis par mail
  • « VotrePassword » : à remplacer par le password transmis par mail
  • « NomDeLArene » : à remplacer par le nom de l’arène à rejoindre

Une fois créee, cette variable agent va notamment vous permettre d’accéder aux variables de votre agent indiquée ci-dessous. Attention par contre, ces variables sont en lecture seule, autrement dit vous ne pourrez pas les modifier directement ! (Désolé les tricheurs en herbe 😉 )

Les variables de l’agent vous renseignent sur l’état de votre agent dans le jeu. Elles ne sont accessibles qu’en lecture seule. Les nombres qu’elles contiennent sont des entiers positifs (type ‘int’ pour integer en Python).

Grâce à ces variables, vous pourrez modifier le comportement de votre agent en fonction de son environnement. Par exemple, si sa vie diminue, c’est … qu’il SE FAIT TIRER DESSUS !! Auquel cas, il serait pertinent de riposter !

Mais tu nous a pourtant dit qu’il n’était pas possible de les modifier directement ?

Et oui, pour les modifier, il faudra utiliser quelque chose d’autre de bien plus puissant, les fonctions !

2.3. Les fonctions

Heureusement, il est aussi possible de faire passer votre agent à l’action ! 3e concept : les fonctions.

Une fonction est un sous programme qui, dès lors qu’on l’appelle, exécute une suite d’instructions. Vous pouvez créer vos propres fonctions, par exemple si vous souhaitez ordonner votre programme, ou appeler plusieurs fois la même suite d’instructions (comme une routine ou une procédure). Vous pouvez aussi utiliser des fonctions que d’autres développeurs ont codées pour vous.

Pour appeler une fonction en Python, il suffit d’écrire sur une nouvelle ligne :

nomDeVotreFonction(parametre1, parametre2)

On reconnait une fonction par ses parenthèses après le nom de la fonction. Ces parenthèses délimitent les paramètres d’entrée à passer à la fonction. Selon la fonction, le nombre de paramètres peut varier. S’il y en a plusieurs, ils sont séparés par des virgules. Il peut ne pas avoir de paramètre du tout. Auquel cas, il n’y aura rien à mettre en parenthèse

# Importe le module de maths pour faire des calculs complexes
import maths

# Appelle la fonction sqrt pour calculer la racine carré du nombre 4
maths.sqrt(4)

# Appelle la fonction pow pour calculer 2 à la puissance 4 
maths.pow(2,4) 

C’est quoi ces lignes qui commencent par des ‘#’ ?

Ce sont des commentaires en python. Ce n’est pas du code qui sera executé, mais une aide pour mieux se repérer dans le code. Une bonne habitude à prendre avant de coder est de toujours commencer par le commentaire, puis d’ajouter le code correspondant. De cette manière, si vous deviez reprendre votre code des mois plus tard, ou si un autre développeur devait reprendre votre travail, cela serait d’une aide considérable !

Bon, pour le moment, nous allons nous contenter d’utiliser les fonctions de votre agent qui ont déjà été développées pour vous. Voici les principales :

Les fonctions de votre agent vous permettent de la faire agir pour changer son état.

Pour tirer en rafale tout en déplaçant votre agent à la colonne 6 en partant de la gauche et à la ligne 7 en partant du haut de la grille, il faut donc écrire :

agent.tirer(True)
agent.deplacer(6,7)
agent.actualiser()

N’oubliez pas d’appeler la fonction actualiser() une fois toutes vos actions effectuées, afin d’envoyer votre demande au serveur.

Tu as oublié l’accent aigüe sur « déplacer » c’est normal ?

Oui, faites bien attention, en général Python n’aime pas les accents ni les espaces dans les noms de variables ou de fonctions. Notez aussi que Python est sensible à la casse, donc agent.Deplacer() (avec le D majuscule) ne marchera pas non plus.

Bien maintenant que vous savez comment créer votre agent, récupérer ses variables d’état et le faire exécuter des actions, il ne reste plus qu’à relier tout cela avec de belles structures conditionnelles !

Des quoi ??

2.4. Les structures conditionnelles

Et bien oui, c’est bien beau de savoir tirer mais vu votre nombre de munitions, il vaut mieux tirer uniquement quand un ennemi est devant vous non ? Et pour ça, il nous faut traduire l’expression suivante :

Si un ennemi est devant nous
    Alors on lui tire dessus en rafale
Sinon
    On arrête de tirer en rafale pour économiser nos précieuses munitions

Cette expression « Si Alors Sinon » est dite conditionnelle car l’action à réaliser dépend d’une condition. En python, cette expression se traduirait par cela :

if ( agent.distance != 0 ):
     agent.tirer(True)
else:
     agent.tirer(False)

Pour savoir si un ennemi est devant nous, nous comparons la variable d’état de l’agent « agent.distance ». Si elle est différente de 0, c’est qu’un ennemi est devant dans la direction de notre agent. Si elle est égale à 0, c’est qu’aucun ennemi n’est visible dans cette direction.

En python, on peut réaliser différents tests à l’aides des opérateurs suivants.

COMPARAISONOPÉRATEUR PYTHON
Strictement supérieur à>
Supérieur ou égal à>=
Strictement inférieur à<
Inférieur ou égal à<=
Egal à==
Différent de!=

C’est normal que tu aies mis 2 signes égal pour la comparaison « égal à » ?

Absolument ! Souvenez vous, on a vu au début l’opérateur d’affection ‘=’ pour créer et initialiser une variable. Pour distinguer l’affection de la comparaison, python (comme d’autres langages) a fait le choix d’utiliser 2 signes égal ‘==’ pour la comparaison.

Pourquoi as-tu mis ‘:’ à la fin du ‘if’ et du ‘else’ ?

En python les structures conditionnelles, ainsi que les boucles et définitions de fonctions sont des blocs. Comme les blocs qui s’encapsulent sous Scratch, un bloc un python commence par ‘:’ . Les instructions à exécuter dans ce bloc doivent être précédés d’une indentation.

Bloc « Si Alors » en Scratch à gauche, et le bloc conditionnel correspondant en python à droite

Une indentation ? Ça se mange cette bête la ?

Une indentation permet une meilleur lisibilité du code. De cette manière on peut rapidement voir les blocs d’instructions qui seront exécutés selon les conditions. En python, en plus des ‘:’ au début du bloc, l’INDENTATION EST OBLIGATOIRE pour signifier que chaque instruction indentée est à exécuter dans le bloc supérieur qui la contient.

Combien de caractères espaces as-tu mis pour faire l’indentation ?

ATTENTION ! Ce ne sont pas des caractères d’espace mais un seul CARACTERE TABULATION (la touche avec 2 flèches parallèles horizontales et opposées en haut à gauche du clavier).

Bon maintenant que toutes ces notions sont comprises, on va pouvoir exécuter le code suivant.

import pytactx

agent = pytactx.Agent(nom="jusdeliens", username="monUserName", password="vousNeLeSaurezJamais!", arene="leNomDeVotreArene")

if ( agent.distance != 0 ):
     agent.tirer(True)
else:
     agent.tirer(False)

agent.actualiser()

Sous repl.it, il ne vous reste plus qu’à cliquer sur le bouton « Run » pour démarrer votre programme.

Lancement du programme sous repl.it en appuyant sur le bouton « Run »

Dans la console (fenêtre noire à droite), entrer les informations demandées puis entrer. Si la valeur par défaut est correcte, tapez simplement entrer.

Entrez les informations demandées dans la console puis entrer.

Il ne se passe rien dans l’arène, je ne vois pas mon agent, c’est normal ?

C’est normal ! Nous avons oublié une dernière chose !

2.5. Les boucles

Si votre agent n’apparait pas, c’est parce le programme s’est terminé trop vite. L’interpréteur python a bien exécuté ligne par ligne le programme demandé, mais un fois arrivée à la ligne 13 le programme se termine.

Tu veux dire qu’on a oublié de lui dire de répéter nos instructions pour ne pas s’arrêter ?

Exactement ! Et pour ça, il nous faut maîtriser un dernier concept : les boucles !

« Répéter tant que », « répéter pour chaque valeur de 0 jusqu’à 10 », voici de nouveaux blocs qui nous permettront d’enrichir nos programmes !

On distingue 2 types de boucles : les bornées et les non bornées.

  • les boucles bornées : répète des instructions pour un nombre d’itérations données. Par exemple : « répéter 10 fois »
Boucle bornée en Scratch à gauche, et bloc équivalent en Python à droite. Les commentaires entre 3 doubles guillemets sont à remplacer par une ou plusieurs instructions sans les guillemets.
  • les boucles non-bornées : répète des instructions tant qu’une condition est vraie ou jusqu’à ce qu’une condition soit fausse. Par exemple : « répéter tant que mon agent est en vie »
Boucle non bornée en Scratch à gauche, et bloc équivalent en Python à droite. Les commentaires entre 3 doubles guillemets sont à remplacer par des conditions et instructions sans les guillemets.

Comme les structures conditionnelles, les boucles sont des blocs. En python, elle commence donc par un test suivi de ‘:’ puis chaque instruction du bloc est indentée d’une tabulation par rapport au bloc supérieur la contenant.

Parfait ! Maintenant, votre 1er programme fonctionnel !

import pytactx

agent = pytactx.Agent(nom="jusdeliens", username="monUserName", password="vousNeLeSaurezJamais!")

while (agent.vie > 0 ):
     if ( agent.distance != 0 ):
          agent.tirer(True)
     else:
          agent.tirer(False)

     agent.actualiser()

Vous devriez voir apparaître votre agent sur la grille à une position aléatoire. Premier constat, il ne fait pas grand chose … Normal, car il attend qu’un ennemi se présente devant lui pour tirer !

2.6. L’aléatoire comme stratégie de déplacement

Pour animer votre agent, je vous propose de le faire se déplacer de manière aléatoire sur la grille en utilisant le module random en python.

Comme le serveur de jeu contraint les déplacements aux cases adjacentes (c’est à dire que votre agent ne peut se déplacer que comme un roi sur un échiquier), il va falloir générer un x et y aléatoire en + ou – 1 autour de la position de votre agent.

Par exemple, si votre position (x,y) est (6,7) alors il faudrait générer un couple (x,y) aléatoire parmi les valeurs suivantes : (6,7) , (5,7) , (5,6) , (6,6) , (7,6) , (7,7) , (7,8) , (6,8) , (5,8).

Cela revient à générer 2 nombres aléatoire :

  • dxAleatoire = 1er nombre aléatoire compris entre -1 et +1 inclus.
  • dyAleatoire = 2e nombre aléatoire compris entre -1 et +1 inclus.

Puis d’ajouter le x et le y de l’agent pour obtenir une position d’un case adjacente aléatoire :

  • nouveauX = agent.x + dxAleatoire
  • nouveauY = agent.y + dyAleatoire

En python, on génère un nombre aléatoire à l’aide de la fonction randint du module random de la façon suivante. Cette fonction attend 2 paramètres : un minimum et un maximum. Elle renvoie ensuite un nombre entier aléatoire compris entre le min et le max inclus.

import random

dxAleatoire = random.randint(-1,1)

On fait de même pour changer l’orientation de manière aléatoire entre 0 (droite) et 3 (bas) et voici le résultat en python :

import pytactx
import random

# Création de l'agent et connexion à l'arène
agent = pytactx.Agent(nom="jusdeliens", username="monUserName", password="vousNeLeSaurezJamais!")

# Répéter tant que votre agent est en vie
while agent.vie > 0:
  # Tirer si ennemie visible
  if ( agent.distance != 0 ):
    agent.tirer(True)
  else:
    agent.tirer(False)

  # Déplacer et orienter de manière aléatoire
  dxAleatoire = random.randint(-1,1)
  dyAleatoire = random.randint(-1,1)
  nouveauX = agent.x + dxAleatoire
  nouveauY = agent.y + dyAleatoire
  agent.deplacer(nouveauX, nouveauY)
  nouvelleOrientation = random.randint(0,3)
  agent.orienter(nouvelleOrientation)

  # Envoyer les ordres au serveur
  agent.actualiser()

C’est fini pour ce tutoriel ! A vous de jouer maintenant 😉