Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ CONFIGURATION
ecran est une toile
dimension(ecran, 1000, 680)
NC est une constante vaut 9
NL est une constante vaut 8
CEL est une constante vaut 58
BX est une constante vaut 50
BY est une constante vaut 118
// Fond de l'écran (dégradé gauche -> droite)
fondDeg est un tableau
fondDeg ajoute #0E1319
fondDeg ajoute #18212B
// Directions : 0 = haut, 1 = droite, 2 = bas, 3 = gauche
dirL est un tableau
dirC est un tableau
dirL ajoute 0 - 1
dirL ajoute 0
dirL ajoute 1
dirL ajoute 0
dirC ajoute 0
dirC ajoute 1
dirC ajoute 0
dirC ajoute 0 - 1
// Couleurs des véhicules et des passagers (claire / foncée)
palette est un tableau
paletteSombre est un tableau
palette ajoute #EF4444
paletteSombre ajoute #A31F1F
palette ajoute #3B82F6
paletteSombre ajoute #1E4FA8
palette ajoute #22C55E
paletteSombre ajoute #15803D
palette ajoute #FACC15
paletteSombre ajoute #B48A06
palette ajoute #A855F7
paletteSombre ajoute #6B21A8
palette ajoute #F97316
paletteSombre ajoute #B4500C
@ PLATEAU ET VÉHICULES
// occ[l][c] = numéro du véhicule sur la case, ou -1 si libre
occ est un tableau
pour i de 0 à NL - 1
ligO est un tableau
pour j de 0 à NC - 1
ligO ajoute 0 - 1
fin pour
occ ajoute ligO
fin pour
// Un véhicule = case de l'avant (vL, vC), direction, longueur,
// couleur, capacité, état (0 parking, 1 en route, 2 au quai, 3 parti)
vL, vC, vDir, vLong, vCoul, vCap, vEtat, vDx, vDy est un tableau
nbV est un nombre
// Le quai : 5 places au maximum (4 + joker)
slotVeh, slotPlein, slotDy est un tableau
pour s de 0 à 4
slotVeh ajoute 0 - 1
slotPlein ajoute 0
slotDy ajoute 0
fin pour
nbSlots est un nombre
nbSlots vaut 4
// File d'attente des passagers (numéros de couleur, le premier en tête)
file est un tableau
@ SAUVEGARDE
niveau est un nombre
niveauMax est un nombre
essayer
niveauMax vaut paramètre('bus_parking', 'niveau')
attraper
niveauMax vaut 1
paramètre('bus_parking', 'niveau', 1)
fin essayer
niveau vaut niveauMax
@ VARIABLES DU JEU
etatPartie est un nombre
// 0 = en cours, 1 = gagné, 2 = perdu
coups est un nombre
message est un texte
ecranTitre, aideVisible, jokerDispo, aGenerer est un booléen
ecranTitre vaut vrai
aGenerer vaut vrai
jokerDispo vaut vrai
// Variables de travail du programme principal
xc, yc, ll, cc, vi, dr, dist, pl, pc, off, total, slotLibre est un nombre
gl, gc, gd, lg, tl, tc, essais, nbVoulu, nbCoul, tirage, prochain, ka est un nombre
coulTete, trouve, restants, libres, sd est un nombre
bloque, ok, encore est un booléen
actifs, restP est un tableau
// Variables du dessin (préfixe r : réservées au processus de rendu)
rI, rK, rS, rX, rY, rW, rH, rV, rNb, rSW, rSX, rTL, rTC, rMinL, rMinC, rMaxL, rMaxC est un nombre
rT, rMX, rMY, rHv, rPL, rPC, rAl, rEt, rQX, rQY est un nombre
rBl est un booléen
rTxt est un texte
@ PROCÉDURES DE DESSIN
// Un véhicule vu de dessus : roues, carrosserie, reflet, vitres,
// phares à l'avant, feux rouges à l'arrière, flèche de direction.
procédure dessinerVehicule(t, x, y, w, h, dir, coul, sombre, lg, avecFleche)
cx, cy, k, n, ecart est un nombre
vert est un booléen
vert vaut dir = 0 ou dir = 2
cx vaut x + w / 2
cy vaut y + h / 2
// Ombre portée
rectangle_arrondi(t, x + 3, y + 5, w, h, 10, rgba(0, 0, 0, 0.45))
// Roues
si vert alors
rectangle_arrondi(t, x - 3, y + 9, 6, 13, 2, #111418)
rectangle_arrondi(t, x + w - 3, y + 9, 6, 13, 2, #111418)
rectangle_arrondi(t, x - 3, y + h - 22, 6, 13, 2, #111418)
rectangle_arrondi(t, x + w - 3, y + h - 22, 6, 13, 2, #111418)
sinon
rectangle_arrondi(t, x + 9, y - 3, 13, 6, 2, #111418)
rectangle_arrondi(t, x + w - 22, y - 3, 13, 6, 2, #111418)
rectangle_arrondi(t, x + 9, y + h - 3, 13, 6, 2, #111418)
rectangle_arrondi(t, x + w - 22, y + h - 3, 13, 6, 2, #111418)
fin si
// Carrosserie (bord foncé + teinte principale)
rectangle_arrondi(t, x, y, w, h, 10, sombre)
rectangle_arrondi(t, x + 2, y + 2, w - 4, h - 4, 9, coul)
// Toit légèrement ombré au centre
si vert alors
rectangle_arrondi(t, x + 9, y + 22, w - 18, h - 44, 6, rgba(0, 0, 0, 0.14))
rectangle_arrondi(t, x + 5, y + 16, 4, h - 32, 2, rgba(255, 255, 255, 0.3))
sinon
rectangle_arrondi(t, x + 22, y + 9, w - 44, h - 18, 6, rgba(0, 0, 0, 0.14))
rectangle_arrondi(t, x + 16, y + 5, w - 32, 4, 2, rgba(255, 255, 255, 0.3))
fin si
// Vitres latérales pour le minibus et le bus
si lg >= 3 alors
n vaut lg * 2 - 2
si vert alors
ecart vaut (h - 48) / n
pour k de 0 à n - 1
rectangle(t, x + 3, y + 24 + k * ecart + 2, 3, ecart - 4, #A9D3F5)
rectangle(t, x + w - 6, y + 24 + k * ecart + 2, 3, ecart - 4, #A9D3F5)
fin pour
sinon
ecart vaut (w - 48) / n
pour k de 0 à n - 1
rectangle(t, x + 24 + k * ecart + 2, y + 3, ecart - 4, 3, #A9D3F5)
rectangle(t, x + 24 + k * ecart + 2, y + h - 6, ecart - 4, 3, #A9D3F5)
fin pour
fin si
fin si
// Pare-brise, lunette arrière, phares et feux
si dir = 0 alors
rectangle_arrondi(t, x + 6, y + 8, w - 12, 10, 4, #D4ECFF)
rectangle_arrondi(t, x + 9, y + h - 13, w - 18, 6, 3, #7FA8CC)
cercle(t, x + 8, y + 4, 2.5, #FFF7AE)
cercle(t, x + w - 8, y + 4, 2.5, #FFF7AE)
rectangle(t, x + 5, y + h - 4, 7, 2, #FF4D4D)
rectangle(t, x + w - 12, y + h - 4, 7, 2, #FF4D4D)
sinon si dir = 2 alors
rectangle_arrondi(t, x + 6, y + h - 18, w - 12, 10, 4, #D4ECFF)
rectangle_arrondi(t, x + 9, y + 7, w - 18, 6, 3, #7FA8CC)
cercle(t, x + 8, y + h - 4, 2.5, #FFF7AE)
cercle(t, x + w - 8, y + h - 4, 2.5, #FFF7AE)
rectangle(t, x + 5, y + 2, 7, 2, #FF4D4D)
rectangle(t, x + w - 12, y + 2, 7, 2, #FF4D4D)
sinon si dir = 1 alors
rectangle_arrondi(t, x + w - 18, y + 6, 10, h - 12, 4, #D4ECFF)
rectangle_arrondi(t, x + 7, y + 9, 6, h - 18, 3, #7FA8CC)
cercle(t, x + w - 4, y + 8, 2.5, #FFF7AE)
cercle(t, x + w - 4, y + h - 8, 2.5, #FFF7AE)
rectangle(t, x + 2, y + 5, 2, 7, #FF4D4D)
rectangle(t, x + 2, y + h - 12, 2, 7, #FF4D4D)
sinon
rectangle_arrondi(t, x + 8, y + 6, 10, h - 12, 4, #D4ECFF)
rectangle_arrondi(t, x + w - 13, y + 9, 6, h - 18, 3, #7FA8CC)
cercle(t, x + 4, y + 8, 2.5, #FFF7AE)
cercle(t, x + 4, y + h - 8, 2.5, #FFF7AE)
rectangle(t, x + w - 4, y + 5, 2, 7, #FF4D4D)
rectangle(t, x + w - 4, y + h - 12, 2, 7, #FF4D4D)
fin si
// Flèche de direction dans une pastille
si avecFleche alors
cercle(t, cx, cy, 12, rgba(0, 0, 0, 0.3))
si dir = 0 alors
triangle(t, cx, cy - 8, cx - 7, cy + 5, cx + 7, cy + 5, #FFFFFF)
sinon si dir = 2 alors
triangle(t, cx, cy + 8, cx - 7, cy - 5, cx + 7, cy - 5, #FFFFFF)
sinon si dir = 1 alors
triangle(t, cx + 8, cy, cx - 5, cy - 7, cx - 5, cy + 7, #FFFFFF)
sinon
triangle(t, cx - 8, cy, cx + 5, cy - 7, cx + 5, cy + 7, #FFFFFF)
fin si
fin si
fin procédure
// Les sièges d'un véhicule garé au quai (vu de dessus, vertical) :
// une tête pour chaque passager monté, un siège vide sinon.
procédure dessinerSieges(t, x, y, w, h, lg, plein)
k, rang, col, sx, sy, ecart est un nombre
ecart vaut (h - 50) / (lg - 1)
pour k de 0 à lg * 2 - 1
rang vaut arrondi_inferieur(k / 2)
col vaut k mod 2
sx vaut x + w / 2 + sialors(col = 0, 0 - 9, 9)
sy vaut y + 26 + rang * ecart
si k < plein alors
cercle(t, sx, sy, 6.5, #FFDDBB)
ellipse(t, sx, sy - 2, 6, 4, #4A3428)
sinon
rectangle_arrondi(t, sx - 6, sy - 6, 12, 12, 3, rgba(0, 0, 0, 0.28))
fin si
fin pour
fin procédure
// Un passager de la file : ombre, corps, tête, casquette, yeux
procédure dessinerPassager(t, x, y, coul, sombre)
ellipse(t, x, y + 21, 9, 3, rgba(0, 0, 0, 0.4))
rectangle_arrondi(t, x - 8, y + 3, 16, 17, 6, coul)
rectangle_arrondi(t, x - 8, y + 13, 16, 7, 3, sombre)
cercle(t, x, y - 5, 7, #FFDDBB)
ellipse(t, x, y - 10, 7.5, 3.5, sombre)
cercle(t, x - 2.5, y - 4, 1.2, #3A2A20)
cercle(t, x + 2.5, y - 4, 1.2, #3A2A20)
fin procédure
procédure dessinerBouton(t, bx, by, lb, hb, texteB, fond, coulTexte, taillePolice)
rectangle_arrondi(t, bx, by + 4, lb, hb, 12, rgba(0, 0, 0, 0.4))
rectangle_arrondi(t, bx, by, lb, hb, 12, fond)
rectangle_arrondi(t, bx + 4, by + 3, lb - 8, hb / 2 - 3, 9, rgba(255, 255, 255, 0.12))
label(t, bx + lb / 2 - label_largeur(texteB, taillePolice) / 2, by + hb / 2 + taillePolice * 0.36, texteB, coulTexte, taillePolice)
fin procédure
procédure dessinerBoutonRejouer(t, x, y)
rectangle_arrondi(t, x, y + 4, 40, 40, 12, rgba(0, 0, 0, 0.4))
rectangle_arrondi(t, x, y, 40, 40, 12, #2A3542)
cercle(t, x + 20, y + 21, 11, #FFFFFF)
cercle(t, x + 20, y + 21, 7, #2A3542)
rectangle(t, x + 20, y + 8, 13, 13, #2A3542)
pF est un tableau
pF ajoute x + 16
pF ajoute y + 5
pF ajoute x + 29
pF ajoute y + 10
pF ajoute x + 21
pF ajoute y + 19
polygone(t, pF, #FFFFFF)
fin procédure
// Petite carte d'information du bandeau (titre gris + valeur)
procédure dessinerPuce(t, x, y, w, titre, valeur, coulVal)
rectangle_arrondi(t, x, y, w, 44, 12, #1C242E)
label(t, x + 14, y + 17, titre, #7D8A98, 10)
label(t, x + 14, y + 36, valeur, coulVal, 17)
fin procédure
// Étoile à 5 branches (écran de victoire)
procédure dessinerEtoile(t, cx, cy, r, coul)
pE est un tableau
k, ang, rr est un nombre
pour k de 0 à 9
ang vaut 0 - pi() / 2 + k * pi() / 5
rr vaut sialors(k mod 2 = 0, r, r * 0.45)
pE ajoute cx + rr * cosinus(ang)
pE ajoute cy + rr * sinus(ang)
fin pour
polygone(t, pE, coul)
fin procédure
@ PROCESSUS DE RENDU (dessine l'écran en continu, pendant que le jeu réfléchit)
processus Rendu()
tant que vrai
rT ajoute 1
effacer(ecran)
contour(ecran, #0)
dégradé(ecran, fondDeg)
// ================= LE PARKING (à gauche) =================
// Route autour du parking, avec sa ligne jaune pointillée
rectangle_arrondi(ecran, BX - 30, BY - 30, NC * CEL + 60, NL * CEL + 60, 22, #1F252D)
pour rK de 0 à arrondi_inferieur((NC * CEL + 18) / 24)
rX vaut BX - 15 + rK * 24
ligne(ecran, rX, BY - 15, rX + 12, BY - 15, rgba(250, 204, 21, 0.45), 2)
ligne(ecran, rX, BY + NL * CEL + 15, rX + 12, BY + NL * CEL + 15, rgba(250, 204, 21, 0.45), 2)
fin pour
pour rK de 0 à arrondi_inferieur((NL * CEL + 18) / 24)
rY vaut BY - 15 + rK * 24
ligne(ecran, BX - 15, rY, BX - 15, rY + 12, rgba(250, 204, 21, 0.45), 2)
ligne(ecran, BX + NC * CEL + 15, rY, BX + NC * CEL + 15, rY + 12, rgba(250, 204, 21, 0.45), 2)
fin pour
// Bitume et places de parking
rectangle_arrondi(ecran, BX - 5, BY - 5, NC * CEL + 10, NL * CEL + 10, 10, #2C3540)
pour rK de 0 à NL - 1
pour rI de 0 à NC - 1
si (rK + rI) mod 2 = 0 alors
rectangle(ecran, BX + rI * CEL, BY + rK * CEL, CEL, CEL, rgba(255, 255, 255, 0.025))
fin si
fin pour
fin pour
pour rK de 0 à NC
ligne(ecran, BX + rK * CEL, BY, BX + rK * CEL, BY + NL * CEL, rgba(255, 255, 255, 0.10), 1)
fin pour
pour rK de 0 à NL
ligne(ecran, BX, BY + rK * CEL, BX + NC * CEL, BY + rK * CEL, rgba(255, 255, 255, 0.10), 1)
fin pour
// Véhicule survolé par la souris : on montre sa route
rHv vaut 0 - 1
rMX vaut souris_x(ecran)
rMY vaut souris_y(ecran)
si etatPartie = 0 et non ecranTitre et non aideVisible alors
si rMX >= BX et rMX < BX + NC * CEL et rMY >= BY et rMY < BY + NL * CEL alors
rHv vaut occ[limiter(arrondi_inferieur((rMY - BY) / CEL), 0, NL - 1)][limiter(arrondi_inferieur((rMX - BX) / CEL), 0, NC - 1)]
fin si
fin si
si rHv >= 0 alors
si vEtat[rHv] = 0 et vDx[rHv] = 0 et vDy[rHv] = 0 alors
rPL vaut vL[rHv] + dirL[vDir[rHv]]
rPC vaut vC[rHv] + dirC[vDir[rHv]]
rBl vaut faux
tant que non rBl et rPL >= 0 et rPL < NL et rPC >= 0 et rPC < NC
si occ[rPL][rPC] >= 0 alors
rBl vaut vrai
rectangle_arrondi(ecran, BX + rPC * CEL + 3, BY + rPL * CEL + 3, CEL - 6, CEL - 6, 8, rgba(239, 68, 68, 0.35))
sinon
rectangle_arrondi(ecran, BX + rPC * CEL + 6, BY + rPL * CEL + 6, CEL - 12, CEL - 12, 8, rgba(255, 255, 255, 0.10))
rPL vaut rPL + dirL[vDir[rHv]]
rPC vaut rPC + dirC[vDir[rHv]]
fin si
fin tant que
sinon
rHv vaut 0 - 1
fin si
fin si
// Les véhicules du parking
si nbV > 0 alors
pour rI de 0 à nbV - 1
si vEtat[rI] <= 1 alors
rTL vaut vL[rI] - (vLong[rI] - 1) * dirL[vDir[rI]]
rTC vaut vC[rI] - (vLong[rI] - 1) * dirC[vDir[rI]]
rMinL vaut minimum(vL[rI], rTL)
rMinC vaut minimum(vC[rI], rTC)
rMaxL vaut maximum(vL[rI], rTL)
rMaxC vaut maximum(vC[rI], rTC)
rX vaut BX + rMinC * CEL + 5 + vDx[rI]
rY vaut BY + rMinL * CEL + 5 + vDy[rI]
rW vaut (rMaxC - rMinC + 1) * CEL - 10
rH vaut (rMaxL - rMinL + 1) * CEL - 10
appelle dessinerVehicule(ecran, rX, rY, rW, rH, vDir[rI], palette[vCoul[rI]], paletteSombre[vCoul[rI]], vLong[rI], vrai)
si rI = rHv alors
contour(ecran, #FFFFFF, 3)
rectangle_arrondi(ecran, rX - 3, rY - 3, rW + 6, rH + 6, 12, rgba(255, 255, 255, 0.08))
contour(ecran, #0)
fin si
fin si
fin pour
fin si
// ================= BANDEAU DU HAUT =================
rectangle(ecran, 0, 0, 1000, 76, #10161D)
ligne(ecran, 0, 76, 1000, 76, #263140, 2)
appelle dessinerVehicule(ecran, 24, 22, 66, 34, 1, #FACC15, #B48A06, 2, faux)
label(ecran, 108, 40, "BUS PARKING OUT", #FFFFFF, 24)
label(ecran, 110, 60, "Libère le parking, remplis les bus", #7D8A98, 12)
appelle dessinerPuce(ecran, 500, 16, 116, "NIVEAU", convertir_texte(niveau), #FACC15)
appelle dessinerPuce(ecran, 626, 16, 116, "RECORD", "niveau " + convertir_texte(niveauMax), #FFFFFF)
appelle dessinerPuce(ecran, 752, 16, 116, "COUPS", convertir_texte(coups), #FFFFFF)
appelle dessinerBouton(ecran, 888, 16, 40, 40, "?", #2A3542, #FFFFFF, 20)
appelle dessinerBoutonRejouer(ecran, 940, 16)
// ================= LE QUAI (en haut à droite) =================
rectangle_arrondi(ecran, 624, 92, 356, 226, 18, #1A212A)
label(ecran, 644, 118, "QUAI", #FFFFFF, 16)
rTxt vaut convertir_texte(nbSlots) + " places"
label(ecran, 960 - label_largeur(rTxt, 12), 117, rTxt, #7D8A98, 12)
rSW vaut (324 - (nbSlots - 1) * 8) / nbSlots
pour rS de 0 à nbSlots - 1
rSX vaut 640 + rS * (rSW + 8)
si rS = 4 alors
contour(ecran, #FACC15, 2)
fin si
rectangle_arrondi(ecran, rSX, 130, rSW, 176, 12, #232C37)
contour(ecran, #0)
// Ligne d'arrêt et marquage de la place
rectangle(ecran, rSX + 8, 286, rSW - 16, 3, rgba(255, 255, 255, 0.18))
si slotVeh[rS] >= 0 alors
rV vaut slotVeh[rS]
rH vaut 20 + vLong[rV] * 30
rQX vaut rSX + rSW / 2 - 22
rQY vaut 136 + (144 - rH) / 2 + slotDy[rS]
appelle dessinerVehicule(ecran, rQX, rQY, 44, rH, 0, palette[vCoul[rV]], paletteSombre[vCoul[rV]], vLong[rV], faux)
appelle dessinerSieges(ecran, rQX, rQY, 44, rH, vLong[rV], slotPlein[rS])
si slotDy[rS] = 0 alors
rTxt vaut convertir_texte(slotPlein[rS]) + " / " + convertir_texte(vCap[rV])
label(ecran, rSX + rSW / 2 - label_largeur(rTxt, 13) / 2, 302, rTxt, #FFFFFF, 13)
fin si
sinon
label(ecran, rSX + rSW / 2 - label_largeur("P", 30) / 2, 230, "P", #34404E, 30)
fin si
fin pour
// ================= LA FILE D'ATTENTE =================
rectangle_arrondi(ecran, 624, 332, 356, 182, 18, #1A212A)
label(ecran, 644, 358, "FILE D'ATTENTE", #FFFFFF, 16)
rTxt vaut convertir_texte(longueur(file)) + " passagers"
label(ecran, 960 - label_largeur(rTxt, 12), 357, rTxt, #7D8A98, 12)
rNb vaut minimum(longueur(file), 33)
si longueur(file) > 33 alors
rNb vaut 32
fin si
si rNb > 0 alors
pour rK de 0 à rNb - 1
rX vaut 652 + (rK mod 11) * 30
rY vaut 388 + arrondi_inferieur(rK / 11) * 42
si rK = 0 alors
rAl vaut 0.16 + 0.10 * sinus(rT / 4)
rectangle_arrondi(ecran, rX - 13, rY - 17, 26, 42, 9, rgba(255, 255, 255, rAl))
fin si
appelle dessinerPassager(ecran, rX, rY, palette[file[rK]], paletteSombre[file[rK]])
fin pour
si longueur(file) > 33 alors
rX vaut 652 + 10 * 30
rY vaut 388 + 2 * 42
rTxt vaut "+" + convertir_texte(longueur(file) - 32)
rectangle_arrondi(ecran, rX - 14, rY - 14, 30, 30, 8, #2A3542)
label(ecran, rX + 1 - label_largeur(rTxt, 12) / 2, rY + 6, rTxt, #FFFFFF, 12)
fin si
sinon
rTxt vaut "Tous les passagers sont partis"
label(ecran, 802 - label_largeur(rTxt, 15) / 2, 440, rTxt, #4ADE80, 15)
fin si
// ================= JOKER =================
si jokerDispo alors
appelle dessinerBouton(ecran, 624, 530, 356, 50, "Joker : +1 place au quai", #F59E0B, #1A1205, 16)
sinon
appelle dessinerBouton(ecran, 624, 530, 356, 50, "Joker utilisé", #232C37, #66727F, 16)
fin si
label(ecran, 636, 604, "Une 5e place, une seule fois par niveau.", #66727F, 11)
// ================= BARRE DE MESSAGE =================
rectangle_arrondi(ecran, 20, 630, 960, 38, 12, #1A212A)
rNb vaut 0
si nbV > 0 alors
pour rI de 0 à nbV - 1
si vEtat[rI] = 0 alors
rNb ajoute 1
fin si
fin pour
fin si
label(ecran, 40, 654, "Au parking : " + convertir_texte(rNb), #C9D2DC, 13)
rTxt vaut "Couleurs : " + convertir_texte(minimum(3 + arrondi_inferieur(niveau / 2), 6))
label(ecran, 960 - label_largeur(rTxt, 13), 654, rTxt, #C9D2DC, 13)
label(ecran, 500 - label_largeur(message, 15) / 2, 655, message, #FCD34D, 15)
// ================= ÉCRANS PAR-DESSUS =================
si ecranTitre alors
rectangle(ecran, 0, 0, 1000, 680, rgba(0, 0, 0, 0.8))
rectangle_arrondi(ecran, 270, 90, 460, 500, 22, #1A212A)
rectangle_arrondi(ecran, 290, 110, 420, 150, 16, #2C3540)
appelle dessinerVehicule(ecran, 310, 130, 160, 46, 1, #EF4444, #A31F1F, 3, vrai)
appelle dessinerVehicule(ecran, 500, 126, 48, 120, 2, #3B82F6, #1E4FA8, 2, vrai)
appelle dessinerVehicule(ecran, 580, 196, 110, 46, 3, #22C55E, #15803D, 2, vrai)
pour rK de 0 à 5
appelle dessinerPassager(ecran, 330 + rK * 26, 220, palette[rK], paletteSombre[rK])
fin pour
rTxt vaut "BUS PARKING OUT"
label(ecran, 500 - label_largeur(rTxt, 34) / 2, 312, rTxt, #FFFFFF, 34)
rTxt vaut "Sors les véhicules dans le sens de leur flèche,"
label(ecran, 500 - label_largeur(rTxt, 15) / 2, 352, rTxt, #C9D2DC, 15)
rTxt vaut "envoie-les au quai et fais monter les passagers"
label(ecran, 500 - label_largeur(rTxt, 15) / 2, 376, rTxt, #C9D2DC, 15)
rTxt vaut "de la même couleur."
label(ecran, 500 - label_largeur(rTxt, 15) / 2, 400, rTxt, #C9D2DC, 15)
rTxt vaut "Niveau " + convertir_texte(niveau)
label(ecran, 500 - label_largeur(rTxt, 22) / 2, 452, rTxt, #FACC15, 22)
rAl vaut 0.6 + 0.4 * sinus(rT / 5)
appelle dessinerBouton(ecran, 380, 490, 240, 56, "Jouer", #16A34A, rgba(255, 255, 255, rAl), 22)
fin si
si aideVisible alors
rectangle(ecran, 0, 0, 1000, 680, rgba(0, 0, 0, 0.8))
rectangle_arrondi(ecran, 260, 70, 480, 540, 22, #1A212A)
label(ecran, 290, 114, "COMMENT JOUER", #FFFFFF, 24)
label(ecran, 290, 156, "Clique sur un véhicule : il avance tout droit", #C9D2DC, 15)
label(ecran, 290, 178, "dans le sens de sa flèche.", #C9D2DC, 15)
label(ecran, 290, 212, "Voie libre : il sort et se gare au quai.", #C9D2DC, 15)
label(ecran, 290, 234, "Voie bloquée : il cogne et revient (1 coup).", #C9D2DC, 15)
label(ecran, 290, 268, "Passe la souris sur un véhicule pour voir sa", #93C5FD, 15)
label(ecran, 290, 290, "route (en rouge : ce qui le bloque).", #93C5FD, 15)
label(ecran, 290, 324, "Les passagers montent dans l'ordre de la file,", #C9D2DC, 15)
label(ecran, 290, 346, "dans un véhicule de leur couleur.", #C9D2DC, 15)
label(ecran, 290, 380, "Voiture 4 places · Minibus 6 · Bus 8.", #C9D2DC, 15)
label(ecran, 290, 402, "Un véhicule plein part et libère sa place.", #C9D2DC, 15)
label(ecran, 290, 436, "Quai plein et personne ne peut monter :", #FCA5A5, 15)
label(ecran, 290, 458, "la partie est perdue.", #FCA5A5, 15)
label(ecran, 290, 492, "Joker : +1 place au quai, une fois par niveau.", #C9D2DC, 15)
label(ecran, 290, 526, "Regarde la file AVANT de choisir.", #FCD34D, 15)
label(ecran, 290, 580, "Clique pour fermer", #4ADE80, 16)
fin si
si etatPartie = 1 alors
rectangle(ecran, 0, 0, 1000, 680, rgba(0, 0, 0, 0.75))
rectangle_arrondi(ecran, 320, 190, 360, 290, 22, #1A212A)
rTxt vaut "NIVEAU TERMINÉ !"
label(ecran, 500 - label_largeur(rTxt, 28) / 2, 240, rTxt, #4ADE80, 28)
rEt vaut sialors(coups <= nbV, 3, sialors(coups <= nbV + 3, 2, 1))
pour rK de 0 à 2
si rK < rEt alors
appelle dessinerEtoile(ecran, 440 + rK * 60, 292, 24, #FACC15)
sinon
appelle dessinerEtoile(ecran, 440 + rK * 60, 292, 24, #34404E)
fin si
fin pour
rTxt vaut "Réussi en " + convertir_texte(coups) + " coups"
label(ecran, 500 - label_largeur(rTxt, 17) / 2, 350, rTxt, #FFFFFF, 17)
rTxt vaut "3 étoiles = aucun choc"
label(ecran, 500 - label_largeur(rTxt, 12) / 2, 372, rTxt, #7D8A98, 12)
appelle dessinerBouton(ecran, 380, 396, 240, 56, "Niveau suivant", #16A34A, #FFFFFF, 20)
fin si
si etatPartie = 2 alors
rectangle(ecran, 0, 0, 1000, 680, rgba(0, 0, 0, 0.75))
rectangle_arrondi(ecran, 320, 180, 360, 310, 22, #1A212A)
rTxt vaut "LE QUAI EST PLEIN !"
label(ecran, 500 - label_largeur(rTxt, 26) / 2, 232, rTxt, #FCA5A5, 26)
rTxt vaut "Le prochain passager ne peut monter"
label(ecran, 500 - label_largeur(rTxt, 15) / 2, 270, rTxt, #C9D2DC, 15)
rTxt vaut "dans aucun véhicule du quai."
label(ecran, 500 - label_largeur(rTxt, 15) / 2, 292, rTxt, #C9D2DC, 15)
si longueur(file) > 0 alors
appelle dessinerPassager(ecran, 500, 316, palette[file[0]], paletteSombre[file[0]])
fin si
si jokerDispo alors
appelle dessinerBouton(ecran, 370, 350, 260, 50, "Joker : +1 place", #F59E0B, #1A1205, 18)
fin si
appelle dessinerBouton(ecran, 370, 418, 260, 50, "Recommencer le niveau", #DC2626, #FFFFFF, 18)
fin si
affiche ecran
pause 40
fin tant que
fin processus
@ BOUCLE PRINCIPALE (logique du jeu)
Rendu()
tant que vrai
// ==================================================
// GÉNÉRATION D'UN NIVEAU
// ==================================================
si aGenerer alors
aGenerer vaut faux
pour gl de 0 à NL - 1
pour gc de 0 à NC - 1
occ[gl][gc] vaut 0 - 1
fin pour
fin pour
vide vL
vide vC
vide vDir
vide vLong
vide vCoul
vide vCap
vide vEtat
vide vDx
vide vDy
nbV vaut 0
pour s de 0 à 4
slotVeh[s] vaut 0 - 1
slotPlein[s] vaut 0
slotDy[s] vaut 0
fin pour
nbSlots vaut 4
jokerDispo vaut vrai
coups vaut 0
etatPartie vaut 0
nbVoulu vaut minimum(7 + niveau, 24)
nbCoul vaut minimum(3 + arrondi_inferieur(niveau / 2), 6)
essais vaut 0
// Chaque nouveau véhicule doit avoir sa sortie libre au moment
// où on le pose : en les sortant dans l'ordre inverse, le
// niveau est donc toujours faisable.
tant que nbV < nbVoulu et essais < 4000
essais ajoute 1
tirage vaut hasard(1, 100)
si tirage <= 50 alors
lg vaut 2
sinon si tirage <= 85 alors
lg vaut 3
sinon
lg vaut 4
fin si
gd vaut hasard(0, 3)
gl vaut hasard(0, NL - 1)
gc vaut hasard(0, NC - 1)
ok vaut vrai
// Le véhicule tient-il sur des cases libres ?
pour s de 0 à lg - 1
tl vaut gl - s * dirL[gd]
tc vaut gc - s * dirC[gd]
si tl < 0 ou tl >= NL ou tc < 0 ou tc >= NC alors
ok vaut faux
sinon si occ[tl][tc] >= 0 alors
ok vaut faux
fin si
fin pour
// Sa voie de sortie est-elle libre ?
si ok alors
tl vaut gl + dirL[gd]
tc vaut gc + dirC[gd]
tant que tl >= 0 et tl < NL et tc >= 0 et tc < NC
si occ[tl][tc] >= 0 alors
ok vaut faux
fin si
tl vaut tl + dirL[gd]
tc vaut tc + dirC[gd]
fin tant que
fin si
si ok alors
vL ajoute gl
vC ajoute gc
vDir ajoute gd
vLong ajoute lg
vCoul ajoute hasard(0, nbCoul - 1)
vCap ajoute lg * 2
vEtat ajoute 0
vDx ajoute 0
vDy ajoute 0
pour s de 0 à lg - 1
occ[gl - s * dirL[gd]][gc - s * dirC[gd]] vaut nbV
fin pour
nbV ajoute 1
fin si
fin tant que
// File d'attente : on mélange les passagers de 3 véhicules
// à la fois (dans l'ordre de sortie possible), pour que le
// quai de 4 places suffise toujours si on joue bien.
vide file
vide actifs
vide restP
prochain vaut nbV - 1
tant que longueur(actifs) < 3 et prochain >= 0
actifs ajoute prochain
restP ajoute vCap[prochain]
prochain soustrait 1
fin tant que
tant que longueur(actifs) > 0
ka vaut hasard(0, longueur(actifs) - 1)
file ajoute vCoul[actifs[ka]]
restP[ka] vaut restP[ka] - 1
si restP[ka] = 0 alors
actifs supprime ka
restP supprime ka
si prochain >= 0 alors
actifs ajoute prochain
restP ajoute vCap[prochain]
prochain soustrait 1
fin si
fin si
fin tant que
message vaut "Clique sur un véhicule pour le faire sortir"
fin si
// ==================================================
// ATTENTE D'UN CLIC
// ==================================================
cliquer ecran dans xc, yc
si ecranTitre alors
ecranTitre vaut faux
continue
fin si
si aideVisible alors
aideVisible vaut faux
continue
fin si
// ----- Niveau gagné -----
si etatPartie = 1 alors
si clique(xc, yc, 380, 396, 240, 56) alors
niveau ajoute 1
si niveau > niveauMax alors
niveauMax vaut niveau
paramètre('bus_parking', 'niveau', niveauMax)
fin si
aGenerer vaut vrai
fin si
continue
fin si
// ----- Partie perdue -----
si etatPartie = 2 alors
si jokerDispo et clique(xc, yc, 370, 350, 260, 50) alors
jokerDispo vaut faux
nbSlots vaut 5
etatPartie vaut 0
message vaut "Joker : une 5e place s'ouvre au quai"
sinon si clique(xc, yc, 370, 418, 260, 50) alors
aGenerer vaut vrai
fin si
continue
fin si
// ----- Boutons -----
si clique(xc, yc, 888, 16, 40, 40) alors
aideVisible vaut vrai
continue
fin si
si clique(xc, yc, 940, 16, 40, 40) alors
aGenerer vaut vrai
continue
fin si
si clique(xc, yc, 624, 530, 356, 50) alors
si jokerDispo alors
jokerDispo vaut faux
nbSlots vaut 5
message vaut "Joker : une 5e place s'ouvre au quai"
sinon
message vaut "Le joker est déjà utilisé pour ce niveau"
fin si
continue
fin si
// ----- Clic dans le parking -----
si xc < BX ou xc >= BX + NC * CEL ou yc < BY ou yc >= BY + NL * CEL alors
continue
fin si
cc vaut limiter(arrondi_inferieur((xc - BX) / CEL), 0, NC - 1)
ll vaut limiter(arrondi_inferieur((yc - BY) / CEL), 0, NL - 1)
vi vaut occ[ll][cc]
si vi < 0 alors
continue
fin si
// Une place libre au quai ?
slotLibre vaut 0 - 1
pour s de 0 à nbSlots - 1
si slotLibre < 0 et slotVeh[s] < 0 alors
slotLibre vaut s
fin si
fin pour
// Le chemin devant le véhicule est-il dégagé ?
dr vaut vDir[vi]
dist vaut 0
bloque vaut faux
pl vaut vL[vi] + dirL[dr]
pc vaut vC[vi] + dirC[dr]
tant que non bloque et pl >= 0 et pl < NL et pc >= 0 et pc < NC
si occ[pl][pc] >= 0 alors
bloque vaut vrai
sinon
dist ajoute 1
pl vaut pl + dirL[dr]
pc vaut pc + dirC[dr]
fin si
fin tant que
si bloque alors
// ----- Bloqué : il avance, cogne, et revient -----
coups ajoute 1
message vaut "Bloqué ! Un autre véhicule est sur sa route"
total vaut dist * CEL + 8
off vaut 0
tant que off < total
off vaut minimum(off + 14, total)
vDx[vi] vaut off * dirC[dr]
vDy[vi] vaut off * dirL[dr]
pause 30
fin tant que
tant que off > 0
off vaut maximum(off - 14, 0)
vDx[vi] vaut off * dirC[dr]
vDy[vi] vaut off * dirL[dr]
pause 30
fin tant que
sinon si slotLibre < 0 alors
// ----- Quai plein : il tremble sur place -----
message vaut "Le quai est plein : attends qu'un véhicule parte"
pour s de 1 à 4
vDx[vi] vaut 4 * dirL[dr] * sialors(pair(s), 1, 0 - 1)
vDy[vi] vaut 4 * dirC[dr] * sialors(pair(s), 1, 0 - 1)
pause 40
fin pour
vDx[vi] vaut 0
vDy[vi] vaut 0
sinon
// ----- Voie libre : il sort du parking -----
coups ajoute 1
pour s de 0 à vLong[vi] - 1
occ[vL[vi] - s * dirL[dr]][vC[vi] - s * dirC[dr]] vaut 0 - 1
fin pour
vEtat[vi] vaut 1
total vaut (dist + vLong[vi]) * CEL + 20
off vaut 0
tant que off < total
off vaut minimum(off + 30, total)
vDx[vi] vaut off * dirC[dr]
vDy[vi] vaut off * dirL[dr]
pause 30
fin tant que
vEtat[vi] vaut 2
vDx[vi] vaut 0
vDy[vi] vaut 0
// Il arrive au quai par le bas de sa place
slotPlein[slotLibre] vaut 0
slotDy[slotLibre] vaut 90
slotVeh[slotLibre] vaut vi
tant que slotDy[slotLibre] > 0
slotDy[slotLibre] vaut maximum(slotDy[slotLibre] - 15, 0)
pause 30
fin tant que
message vaut "Montée des passagers..."
pause 120
// ----- Montée des passagers, dans l'ordre de la file -----
encore vaut vrai
tant que encore
encore vaut faux
si longueur(file) > 0 alors
coulTete vaut file[0]
trouve vaut 0 - 1
pour s de 0 à nbSlots - 1
si trouve < 0 et slotVeh[s] >= 0 et slotDy[s] = 0 alors
si vCoul[slotVeh[s]] = coulTete et slotPlein[s] < vCap[slotVeh[s]] alors
trouve vaut s
fin si
fin si
fin pour
si trouve >= 0 alors
file supprime 0
slotPlein[trouve] vaut slotPlein[trouve] + 1
encore vaut vrai
pause 70
// Véhicule plein : il démarre et quitte le quai
si slotPlein[trouve] >= vCap[slotVeh[trouve]] alors
sd vaut 0
message vaut "Complet : le véhicule démarre"
tant que sd > 0 - 320
sd vaut sd - 22
slotDy[trouve] vaut sd
pause 30
fin tant que
vEtat[slotVeh[trouve]] vaut 3
slotVeh[trouve] vaut 0 - 1
slotPlein[trouve] vaut 0
slotDy[trouve] vaut 0
fin si
fin si
fin si
fin tant que
message vaut "Choisis le prochain véhicule"
fin si
// ==================================================
// VICTOIRE OU DÉFAITE ?
// ==================================================
restants vaut 0
pour s de 0 à nbV - 1
si vEtat[s] < 3 alors
restants ajoute 1
fin si
fin pour
libres vaut 0
pour s de 0 à nbSlots - 1
si slotVeh[s] < 0 alors
libres ajoute 1
fin si
fin pour
si restants = 0 et longueur(file) = 0 alors
etatPartie vaut 1
message vaut "Bravo !"
sinon si libres = 0 et longueur(file) > 0 alors
etatPartie vaut 2
message vaut "Perdu..."
fin si
fin tant que