Prise en main de l’API PytactX 🚀

Vous souhaitez vous initier Ă  la programmation avec Python tout en vous amusant ?

Dans ce tutoriel, vous allez apprendre comment programmer un robot virtuel gladiateur (i.e. un agent) dans une arĂšne de jeu TactX, pour lui transmettre de l’intelligence afin de lui permettre d’affronter les agents ennemis en temps rĂ©el, et tout ceci de maniĂšre autonome.

🌐 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, 👉renseignez votre PrĂ©nom, Nom et Email dans ce formulaire. Vous recevrez vos identifiants gratuitement sous 48h.

Une fois reçus par mail, Ă  vos claviers et neurones ! Sur play.jusdeliens.com 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 (👉par ici pour vous abonner).

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 IDEAL Arena. 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 Ă  notre prochaine session de formation.

👣 Vos premiers pas

📚 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 dans une arĂšne TactX, on va importer le module pytactx contenu dans un autre fichier, Ă  cĂŽtĂ© de votre fichier main dans l’arborescence du projet.

Le fichier main.py contient votre programme principal, c’est dedans que vous dĂ©velopperez votre programme. Le fichier agent.py dans le dossier j2l/pytactx contient tout ce qu’il vous faut pour jouer. L’extension .py signifie programme PYthon.

Dans le fichier main.py, ajoutons donc au début du programme la ligne suivante :

import j2l.pytactx.agent as pytactx

Et voilĂ  ! Nous pouvons dĂ©sormais crĂ©er notre agent pour combattre dans l’arĂšne !

đŸ’Ÿ 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 le module 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(playerId="LeNomDeMonSuperAgent", username="VotreUserName", password="VotrePassword", arena="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Ă©Ă©e, 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 !

⚙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 math

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

# Appelle la fonction pow pour calculer 2 Ă  la puissance 4 
math.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 exĂ©cutĂ©, 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.fire(True)
agent.moveTowards(6,7)
agent.update()

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

đŸ€” Tu as mis un « T » majuscule Ă  Towards c’est normal ?

⛔ Important
Oui, Python n’aime pas les caractĂšres spĂ©ciaux comme les espaces ou les accents dans les noms de variables et de fonctions. Du coup, on peut mettre une majuscule Ă  la place de l’espace, c’est la convention camelCase (comme les bosses du chameau đŸ«), ou bien un underscore (le tiret du 8 qui rampe au sol comme un serpent 🐍) qui est la convention snake_case. Notez que Python est sensible Ă  la casse, donc agent.movetowards() ne marchera pas car la fonction est connu sous le nom agent.moveTowards().

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 !

đŸšȘ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 ? Il faut que j’aille voir mon dentiste ?!

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 ?

⛔ Important
Les indentations ne sont pas des caractĂšres d’espace comme les autres. Il est coutume d’utiliser la touche tabulation sur le clavier pour faire une indentation (la touche avec 2 flĂšches parallĂšles horizontales et opposĂ©es en haut Ă  gauche du clavier ↔). C’est donc UN SEUL CARACTÈRE TABULATION qui est recommandĂ©, plutĂŽt que plusieurs caractĂšres avec la touche espace.

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

import j2l.pytactx.agent as pytactx

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

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

agent.update()

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 !

➿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 j2l.pytactx.agent as pytactx

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

while (agent.life> 0 ):
     if ( agent.distance != 0 ):
          agent.fire(True)
     else:
          agent.fire(False)

     agent.update()

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 !

đŸŽČ 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 :

  • dx = 1er nombre alĂ©atoire compris entre -1 et +1 inclus.
  • dy = 2e nombre alĂ©atoire compris entre -1 et +1 inclus.

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 j2l.pytactx.agent as pytactx
import random

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

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

  # Déplacer et orienter de maniÚre aléatoire
  dx = random.randint(-1,1)
  dy = random.randint(-1,1)
  agent.move(dx, dy)
  dir = random.randint(0,3)
  agent.lookAt(dir)

  # Envoyer les ordres au serveur
  agent.update()

đŸ›Łïž Et aprĂšs ?

Vous avez aimĂ© ce tutoriel et vous en voulez d’autres ?

Faites le nous savoir en 👉 donnant vos avis et vos envies et nous nous empresserons de vous en rĂ©digez d’autres 😉

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