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 ūüėČ