Un Snake codé en python pour la NumWorks

Projets

Le snake est un jeu très ancien, apparu en 1976 dans Blockade. Le principe est simple : le joueur dirige un serpent qui grandit, et doit éviter le plus longtemps possible de se mordre la queue ou les bordures. Il existe cependant de très nombreuses variantes. Nous vous proposons ici un snake codé en python pour la NumWorks.

Un classique des portables Nokia sous Symbian OS

Sa simplicité apparente et son caractère addictif l’ont mené à être porté sur de très nombreuses plateformes, provoquant un succès planétaire. Nokia y a grandement participé en l’intégrant sur ses téléphones dès 1998, y compris l’iconique 3310.

Cet article présente donc une énième version de ce jeu, cette fois pour la calculatrice NumWorks.

Evolution et défis

La première version ne propose pas d’option et stocke le corps du serpent dans une liste constituée des coordonnées, en divisant l’écran en une grille de 32 par 20 carreaux :

snake = [[3, 3], [4, 3], [5, 3], [6, 3]] # Corps du serpent, de la queue à la tête

Fonctionnel, très pratique pour le faire avancer, par les méthodes pop()et append(), et pour savoir comment dessiner les bordures. Cependant un problème apparaît rapidement : l’occupation de la mémoire. En effet, les listes, et tout particulièrement les listes de listes, sont très coûteuses.

La première évolution a donc consisté à changer le système de stockage du serpent : désormais, seules les coordonnées de la queue et la tête sont enregistrées, diminuant considérablement la place occupée en mémoire, et ce quelle que soit la longueur du serpent.

snake = [3, 3, 6, 3] # Coordonnées de la queue et de la tête

Cela demande en revanche de modifier l’ensemble des procédures graphiques, et d’utiliser une méthode de détection de couleur de pixel, kandinsky.get_pixel(). Les fonctions get_pixel() et set_pixel()n’étant pas bijectives, il a fallu s’assurer de la bijectivité des couleurs utilisées. (Ceci fera l’objet prochainement d’un article dédié)

Pour éviter des conversions fréquentes entre les coordonnées de la grille et celles des pixels, l’ensemble des coordonnées est ensuite modifié pour ne présenter uniquement des coordonnées en pixels.

snake = [30, 52, 60, 52] # Coordonnées de la queue et de la tête

La gestion de la direction a également suscité réflexion, car il faut pouvoir saisir à tout moment les instructions de changement de direction, et il faut également éviter au joueur de mourir lors des demi-tours. Après quelques améliorations, on arrive à ce code :

# Gestion du temps et de la direction
direction = di
while monotonic() < time + speed: # Attente du prochain rafraîchissement du serpent
    for k in range(4): # Changement de direction
        if keydown(k) and direction+k != 3: di = k
    if keydown(6): start() # Retour au menu
time = monotonic()

A la demande de Robert Vincent, j’adapte le code pour pouvoir implémenter un mode où la téléportation d’un bord à l’autre de l’écran est possible, par un jeu de modulos. Le script perd en optimisation, mais gagne en polyvalence.

Les étapes suivantes sont moins lourdes de conséquences :

  • ajout de différents niveaux de difficulté, modifiant la vitesse du serpent et l’intensité de son agrandissement à chaque pomme mangée. 
  • ajout du mode « Dingue », où le serpent grandi et accélère tout seul, progressivement, au lieu de manger des pommes. 

Les dernières étapes ont été de brancher le jeu sur un menu polyvalent graphique en python codé en parallèle, et de finaliser les options d’accessibilité : 

  • choix définitif des touches utilisées
  • amélioration du dessin de la pomme 
  • ajustement du système de points

L’ajout d’autres modes n’est pas exclu.

Images

MenuInterface de jeu
TéléportationPartie perdue

Réagir à cet article

Vous pouvez réagir à cet article sur le topic tiplanet.org de cette news : 
Snake, calcul mental, et interface lancement jeux Python