Parcours Le Sokoban Étape 1
Lire un niveau écrit en texte
Décrire un niveau avec un simple texte, le découper en lignes et en caractères, et dessiner les murs, le sol et les cibles.
Notions :decoupercopiermaximumtableau à une dimension
Les niveaux de Sokoban s'écrivent traditionnellement avec des caractères :
#un mur, une espace le sol ;.une cible,$une caisse,@le gardien ;*une caisse déjà sur une cible,+le gardien sur une cible.
On range chaque niveau dans un seul texte, les lignes séparées par / : "#######/# #/# $ . #/# @ #/#######".
Découper
decouper(texte, "/") renvoie un tableau de lignes. Puis, pour chaque case, copier(ligne, cc + 1, 1) lit un caractère : attention, dans un texte, les positions commencent à 1, d'où le + 1.
Une grille dans un tableau
Les murs et les cibles sont rangés dans des tableaux de largeurN × hauteurN cases. La case de la ligne l et de la colonne c est à l'indice l * largeurN + c, calculé par idxCase. La largeur est celle de la plus longue ligne, trouvée avec maximum.
Chaque case fait 40 pixels ; la toile est redimensionnée selon le niveau, avec une bande de 40 pixels en haut pour les messages.
Ouvrez CoddyRun et partez d'un programme vide : tout commence ici.
Il te faut le logiciel pour faire cette étape. Il est gratuit : crée ton compte pour le télécharger, puis reviens ici, ta place t'attend.
Créer mon compte et téléchargerIndice 1
sialors(car = "#", 1, 0) donne 1 pour un mur, 0 sinon : on l'ajoute directement au tableau.
Indice 2
Une cible est ., mais aussi * et +, qui sont posés sur une cible.
Indice 3
Le premier niveau fait 7 × 5 cases : la toile mesure 280 × 240 pixels.
Voir la solution complète
Essayez d'abord par vous-même : c'est en cherchant qu'on apprend. La solution sert à vérifier ou à se débloquer.
@ Les déclarations
jeu est une toile
niveaux, murs, cibles est un tableau
largeurN, hauteurN est un nombre
message est un texte
@ La position d'une case
fonction idxCase(l, c)
retourne l * largeurN + c
fin fonction
@ Lire un niveau
procédure chargerNiveau(n)
plan est un tableau
car est un texte
// un niveau est un texte, chaque ligne étant séparée par « / »
plan vaut decouper(niveaux[n - 1], "/")
hauteurN vaut longueur(plan)
largeurN vaut 0
pour r de 0 à hauteurN - 1
largeurN vaut maximum(largeurN, longueur(plan[r]))
fin pour
vide murs
vide cibles
pour r de 0 à hauteurN - 1
pour cc de 0 à largeurN - 1
car vaut " "
si cc < longueur(plan[r]) alors
car vaut copier(plan[r], cc + 1, 1)
fin si
murs ajoute sialors(car = "#", 1, 0)
cibles ajoute sialors(car = "." ou car = "*" ou car = "+", 1, 0)
fin pour
fin pour
dimension(jeu, largeurN * 40, hauteurN * 40 + 40)
fin procédure
@ Le dessin
procédure dessiner()
px, py, ic est un nombre
effacer(jeu)
remplir(jeu, #3E2F23)
label(jeu, 8, 27, message, #FFFFFF, 15)
pour r de 0 à hauteurN - 1
pour cc de 0 à largeurN - 1
ic vaut idxCase(r, cc)
px vaut cc * 40
py vaut 40 + r * 40
si murs[ic] = 1 alors
rectangle(jeu, px, py, 40, 40, #7F8C8D)
rectangle(jeu, px + 2, py + 2, 36, 36, #95A5A6)
sinon
rectangle(jeu, px, py, 40, 40, #D9C7A7)
fin si
si cibles[ic] = 1 alors
cercle(jeu, px + 20, py + 20, 7, #E74C3C)
fin si
fin pour
fin pour
affiche jeu
fin procédure
@ Programme principal
niveaux vaut ["#######/# #/# $ . #/# @ #/#######", "########/# . #/# $#$ #/# @ . #/########", "#########/# # #/# $ $ #/# ### #/#. @ .#/#########"]
appelle chargerNiveau(1)
message vaut "Niveau 1"
appelle dessiner()