Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ CONFIGURATION
ecran est une toile
dimension(ecran, 560, 550)
PLAFOND est un nombre
PLAFOND vaut 1000000000000000
SEUIL_REGION est un nombre
SEUIL_REGION vaut 2000000
SUFFIXES est un tableau
SUFFIXES vaut ["k", "M", "Md", "Bn", "Bd", "Tn", "Td", "Qn", "Qd"]
CARTE_Y est un nombre
CARTE_Y vaut 52
CARTE_BAS est un nombre
CARTE_BAS vaut 356
@ LA CARTE
VILLES est un tableau
VILLES vaut ["Valmont", "Rochebrune", "Port-Azur", "Clairefont", "Mirabel", "Saint-Givre", "Belvédère", "Lune-sur-Mer", "Hautepierre", "Cap Soleil"]
VX est un tableau
VX vaut [118, 250, 398, 500, 472, 352, 208, 84, 58, 300]
VY est un tableau
VY vaut [118, 84, 98, 165, 282, 322, 312, 290, 196, 212]
ARB_X est un tableau
ARB_X vaut [120, 510, 538, 150, 371, 45, 447, 521, 444, 501, 20, 270, 361, 380, 529, 349, 386, 136, 511, 453, 522, 506, 112, 208, 228, 383, 261, 540, 524, 493, 446, 75, 144, 485, 43, 90, 163, 115, 427, 456]
ARB_Y est un tableau
ARB_Y vaut [66, 66, 75, 76, 77, 80, 86, 96, 101, 128, 140, 158, 170, 180, 189, 198, 219, 223, 225, 226, 241, 242, 253, 256, 258, 260, 271, 280, 299, 311, 322, 325, 329, 330, 336, 340, 342, 346, 347, 347]
MONT_X est un tableau
MONT_X vaut [511, 130, 527, 526, 53]
MONT_Y est un tableau
MONT_Y vaut [267, 262, 133, 339, 315]
// les trois regions : prairie, desert, montagne enneigee
NOMS_REGION est un tableau
NOMS_REGION vaut ["la Prairie", "le Désert", "les Neiges"]
SOL est un tableau
SOL vaut [#86C97A, #E9C98B, #E6EEF5]
SOL2 est un tableau
SOL2 vaut [#76BB6B, #DDB877, #D5E1EC]
ARBRE est un tableau
ARBRE vaut [#2F8F46, #4D9A4A, #1F5F45]
ARBRE2 est un tableau
ARBRE2 vaut [#3FAE5A, #6DB55E, #2E7D5B]
MONT est un tableau
MONT vaut [#8B9AA8, #C2884E, #7C8DA6]
EAU est un tableau
EAU vaut [#5DADE2, #4FB3BF, #A9CCE3]
COUL_TRAIN est un tableau
COUL_TRAIN vaut [#DC2626, #2563EB, #F59E0B, #7C3AED, #059669, #DB2777]
@ LA LIGNE
// longueur de chaque troncon et position des gares sur la boucle
segL, cumul est un tableau
pour ki de 0 à 10
segL ajoute 0
cumul ajoute 0
fin pour
longueurLigne est un nombre
// le point calcule par pointA()
pX, pY, pDX, pDY est un nombre
ptsWagon est un tableau
pour ki de 0 à 7
ptsWagon ajoute 0
fin pour
@ LES TRAINS
MAX_TRAINS est un nombre
MAX_TRAINS vaut 6
MAX_WAGONS est un nombre
MAX_WAGONS vaut 8
MAX_LOCO est un nombre
MAX_LOCO vaut 8
trS, trTurbo est un tableau
pour ki de 0 à MAX_TRAINS - 1
trS ajoute 0
trTurbo ajoute 0
fin pour
@ LA PARTIE
pieces, totalPartie, totalTout est un nombre
nbGares, nbTrains, nbWagons, nivLoco, nivGrandes, nivBillet est un nombre
medailles, region est un nombre
// etat : 1 jeu, 4 confirmer la nouvelle region, 5 retour, 6 accueil, 7 voyage
etat est un nombre
etat vaut 6
appActif est un booléen
appActif vaut vrai
tic est un nombre
derniereMesure est un nombre
sauveAttente est un nombre
sauveAttente vaut 15
horodatage est un nombre
gainAbsence, dureeAbsence est un nombre
voyageAnim, medaillesGagnees est un nombre
pointe est un nombre
// le ticket dore
ticketAttente est un nombre
ticketAttente vaut 40
ticketVie, ticketGare est un nombre
msgTxt est un texte
msgTxt vaut ""
msgVie est un nombre
// textes qui s'envolent et fumee
ftX, ftY, ftVie, ftTxt est un tableau
pour ki de 0 à 13
ftX ajoute 0
ftY ajoute 0
ftVie ajoute 0
ftTxt ajoute ""
fin pour
ftProchain est un nombre
fuX, fuY, fuVie est un tableau
pour ki de 0 à 29
fuX ajoute 0
fuY ajoute 0
fuVie ajoute 0
fin pour
fuProchain est un nombre
ordres, ordX, ordY est un tableau
pour ki de 0 à 31
ordres ajoute 0
ordX ajoute 0
ordY ajoute 0
fin pour
teteO, queueO est un nombre
action, sourisX, sourisY est un nombre
@ LE TEXTE
procédure centrer(txt, xMil, yTxt, coul, taillePolice)
label(ecran, xMil - label_largeur(txt, taillePolice) / 2, yTxt, txt, coul, taillePolice)
fin procédure
procédure aDroite(txt, xFin, yTxt, coul, taillePolice)
label(ecran, xFin - label_largeur(txt, taillePolice), yTxt, txt, coul, taillePolice)
fin procédure
procédure bouton(x, y, l, hb, txt, fond, coulTxt, taillePolice)
rectangle_arrondi(ecran, x, y + 3, l, hb, 10, rgba(0, 0, 0, 0.25))
rectangle_arrondi(ecran, x, y, l, hb, 10, fond)
appelle centrer(txt, x + l / 2, y + hb / 2 + taillePolice * 0.38, coulTxt, taillePolice)
fin procédure
fonction nombreTexte(v)
si v < 1000 alors
retourne convertir_texte(arrondi_inferieur(v))
fin si
w est un nombre
w vaut v
e est un nombre
e vaut 0
tant que w >= 1000 et e < 9
w vaut w / 1000
e vaut e + 1
fin tant que
t est un texte
si w < 10 alors
t vaut convertir_texte(arrondi_inferieur(w * 100) / 100)
sinon si w < 100 alors
t vaut convertir_texte(arrondi_inferieur(w * 10) / 10)
sinon
t vaut convertir_texte(arrondi_inferieur(w))
fin si
retourne remplacer(t, ".", ",") + " " + SUFFIXES[e - 1]
fin fonction
fonction nombreProd(v)
si v < 100 alors
retourne remplacer(convertir_texte(arrondi_inferieur(v * 10) / 10), ".", ",")
fin si
retourne nombreTexte(v)
fin fonction
fonction dureeTexte(sec)
s est un nombre
s vaut arrondi_inferieur(limiter(sec, 0, 100000000))
si s < 60 alors
retourne convertir_texte(s) + " s"
fin si
hh est un nombre
hh vaut arrondi_inferieur(s / 3600)
mi est un nombre
mi vaut arrondi_inferieur((s mod 3600) / 60)
si hh = 0 alors
retourne convertir_texte(mi) + " min"
fin si
retourne convertir_texte(hh) + " h " + convertir_texte(mi) + " min"
fin fonction
@ CALCULS SANS DEBORDEMENT
// x * y avec y >= 1, sans jamais depasser le plafond
fonction mulSur(x, y)
si x > PLAFOND / y alors
retourne PLAFOND
fin si
retourne x * y
fin fonction
// base * facteur^niveau, multiplie pas a pas
fonction coutSur(base, facteur, niveau)
v est un nombre
v vaut base
k est un nombre
si niveau > 0 alors
pour k de 1 à niveau
v vaut mulSur(v, facteur)
fin pour
fin si
retourne arrondi(v)
fin fonction
@ LA LIGNE ET LES TRAINS
procédure recalculerLigne()
longueurLigne vaut 0
k est un nombre
pour k de 0 à nbGares - 1
suivant est un nombre
suivant vaut (k + 1) mod nbGares
segL[k] vaut hypotenuse(VX[suivant] - VX[k], VY[suivant] - VY[k])
cumul[k] vaut longueurLigne
longueurLigne vaut longueurLigne + segL[k]
fin pour
cumul[nbGares] vaut longueurLigne
fin procédure
// le point de la ligne a la distance s du depart (et la direction)
procédure pointA(s)
d est un nombre
d vaut s
tant que d < 0
d vaut d + longueurLigne
fin tant que
tant que d >= longueurLigne
d vaut d - longueurLigne
fin tant que
seg est un nombre
seg vaut 0
k est un nombre
pour k de 0 à nbGares - 1
si d >= cumul[k] alors
seg vaut k
fin si
fin pour
suivant est un nombre
suivant vaut (seg + 1) mod nbGares
u est un nombre
u vaut (d - cumul[seg]) / segL[seg]
pX vaut VX[seg] + (VX[suivant] - VX[seg]) * u
pY vaut VY[seg] + (VY[suivant] - VY[seg]) * u
pDX vaut (VX[suivant] - VX[seg]) / segL[seg]
pDY vaut (VY[suivant] - VY[seg]) / segL[seg]
fin procédure
procédure espacerTrains()
k est un nombre
pour k de 0 à nbTrains - 1
trS[k] vaut longueurLigne * k / nbTrains
fin pour
fin procédure
fonction vitesseTrain()
retourne 40 + nivLoco * 22
fin fonction
fonction bonusMedailles()
retourne 1 + medailles * 0.2
fin fonction
// ce que rapporte un train qui passe dans une gare
fonction gainPassage()
v est un nombre
v vaut nbWagons * 2
v vaut mulSur(v, puissance(2, limiter(nivBillet, 0, 40)))
v vaut mulSur(v, 1 + nivGrandes)
v vaut mulSur(v, nbGares * 0.5)
v vaut mulSur(v, bonusMedailles())
si pointe > 0 alors
v vaut mulSur(v, 5)
fin si
retourne v
fin fonction
// revenu moyen par seconde (pour l'affichage et l'absence)
fonction revenuSec()
v est un nombre
v vaut mulSur(gainPassage(), nbTrains * nbGares)
retourne v / longueurLigne * vitesseTrain()
fin fonction
fonction regionsGagnables()
retourne arrondi_inferieur(racine(totalPartie / SEUIL_REGION))
fin fonction
@ LA BOUTIQUE
NOMS_ACHAT est un tableau
NOMS_ACHAT vaut ["Nouveau train", "Wagon", "Locomotive", "Nouvelle gare", "Grandes gares", "Billets premium"]
fonction coutAchat(k)
si k = 0 alors
retourne coutSur(50, 9, nbTrains - 1)
sinon si k = 1 alors
retourne coutSur(20, 6, nbWagons - 1)
sinon si k = 2 alors
retourne coutSur(100, 6, nivLoco)
sinon si k = 3 alors
retourne coutSur(300, 7, nbGares - 2)
sinon si k = 4 alors
retourne coutSur(2000, 4, nivGrandes)
fin si
retourne coutSur(10000, 9, nivBillet)
fin fonction
fonction achatAuMax(k)
si k = 0 et nbTrains >= MAX_TRAINS alors
retourne vrai
sinon si k = 1 et nbWagons >= MAX_WAGONS alors
retourne vrai
sinon si k = 2 et nivLoco >= MAX_LOCO alors
retourne vrai
sinon si k = 3 et nbGares >= 10 alors
retourne vrai
fin si
retourne faux
fin fonction
fonction texteNiveau(k)
si k = 0 alors
retourne convertir_texte(nbTrains) + " / " + convertir_texte(MAX_TRAINS)
sinon si k = 1 alors
retourne convertir_texte(nbWagons) + " / " + convertir_texte(MAX_WAGONS)
sinon si k = 2 alors
retourne "niv. " + convertir_texte(nivLoco) + " / " + convertir_texte(MAX_LOCO)
sinon si k = 3 alors
retourne convertir_texte(nbGares) + " / 10"
sinon si k = 4 alors
retourne "gares x" + convertir_texte(1 + nivGrandes)
fin si
retourne "billet x" + nombreTexte(puissance(2, limiter(nivBillet, 0, 40)))
fin fonction
@ SAUVEGARDE
procédure lireHorloge()
horodatage vaut 0
essayer
an est un nombre
an vaut annee_de(maintenant())
mo est un nombre
mo vaut mois_de(maintenant())
jo est un nombre
jo vaut jour_de(maintenant())
hr est un nombre
hr vaut heure_de(maintenant())
mn est un nombre
mn vaut minute_de(maintenant())
sd est un nombre
sd vaut seconde_de(maintenant())
valide est un booléen
valide vaut vrai
si an < 2000 ou an > 2200 ou mo < 1 ou mo > 12 ou jo < 1 ou jo > 31 alors
valide vaut faux
fin si
si hr < 0 ou hr > 23 ou mn < 0 ou mn > 59 ou sd < 0 ou sd > 59 alors
valide vaut faux
fin si
si valide alors
horodatage vaut (((an - 2000) * 12 + mo) * 31 + jo) * 86400 + hr * 3600 + mn * 60 + sd
fin si
attraper
horodatage vaut 0
fin essayer
fin procédure
procédure sauverPartie()
appelle lireHorloge()
essayer
parametre('trainexpress', 'pieces', pieces)
parametre('trainexpress', 'totalPartie', totalPartie)
parametre('trainexpress', 'totalTout', totalTout)
parametre('trainexpress', 'gares', nbGares)
parametre('trainexpress', 'trains', nbTrains)
parametre('trainexpress', 'wagons', nbWagons)
parametre('trainexpress', 'loco', nivLoco)
parametre('trainexpress', 'grandes', nivGrandes)
parametre('trainexpress', 'billet', nivBillet)
parametre('trainexpress', 'medailles', medailles)
parametre('trainexpress', 'region', region)
parametre('trainexpress', 'horloge', horodatage)
attraper
msgVie vaut 0
fin essayer
fin procédure
procédure nouvellePartie()
pieces vaut 0
totalPartie vaut 0
nbGares vaut 2
nbTrains vaut 1
nbWagons vaut 1
nivLoco vaut 0
nivGrandes vaut 0
nivBillet vaut 0
pointe vaut 0
fin procédure
procédure charger()
appelle nouvellePartie()
essayer
pieces vaut parametre('trainexpress', 'pieces')
totalPartie vaut parametre('trainexpress', 'totalPartie')
totalTout vaut parametre('trainexpress', 'totalTout')
nbGares vaut limiter(parametre('trainexpress', 'gares'), 2, 10)
nbTrains vaut limiter(parametre('trainexpress', 'trains'), 1, MAX_TRAINS)
nbWagons vaut limiter(parametre('trainexpress', 'wagons'), 1, MAX_WAGONS)
nivLoco vaut limiter(parametre('trainexpress', 'loco'), 0, MAX_LOCO)
nivGrandes vaut parametre('trainexpress', 'grandes')
nivBillet vaut parametre('trainexpress', 'billet')
medailles vaut parametre('trainexpress', 'medailles')
region vaut parametre('trainexpress', 'region')
etat vaut 1
attraper
appelle nouvellePartie()
etat vaut 6
fin essayer
appelle recalculerLigne()
appelle espacerTrains()
si etat = 1 alors
ancien est un nombre
ancien vaut 0
essayer
ancien vaut parametre('trainexpress', 'horloge')
attraper
ancien vaut 0
fin essayer
si ancien < 0 ou ancien > 1000000000000 alors
ancien vaut 0
fin si
appelle lireHorloge()
// les trains ont roule pendant l'absence (a moitie, 8 heures au plus)
si ancien > 0 et horodatage > ancien + 60 et horodatage < ancien + 5184000 alors
dureeAbsence vaut horodatage - ancien
gainAbsence vaut minimum(revenuSec(), PLAFOND / 14400) * minimum(dureeAbsence, 28800) * 0.5
si gainAbsence >= 1 alors
pieces vaut minimum(pieces + gainAbsence, PLAFOND)
totalPartie vaut minimum(totalPartie + gainAbsence, PLAFOND)
totalTout vaut minimum(totalTout + gainAbsence, PLAFOND)
etat vaut 5
fin si
fin si
fin si
fin procédure
@ LES ACTIONS
procédure annoncer(txt)
msgTxt vaut txt
msgVie vaut 3
fin procédure
procédure gagner(v)
w est un nombre
w vaut minimum(v, PLAFOND)
pieces vaut minimum(pieces + w, PLAFOND)
totalPartie vaut minimum(totalPartie + w, PLAFOND)
totalTout vaut minimum(totalTout + w, PLAFOND)
fin procédure
procédure lancerTexte(x, y, txt)
ftX[ftProchain] vaut x
ftY[ftProchain] vaut y
ftVie[ftProchain] vaut 1
ftTxt[ftProchain] vaut txt
ftProchain vaut (ftProchain + 1) mod 14
fin procédure
procédure acheter(k)
cout est un nombre
cout vaut coutAchat(k)
si non achatAuMax(k) et cout < PLAFOND et pieces >= cout alors
pieces vaut pieces - cout
si k = 0 alors
nbTrains vaut nbTrains + 1
appelle espacerTrains()
appelle annoncer("Un nouveau train entre en service !")
sinon si k = 1 alors
nbWagons vaut nbWagons + 1
sinon si k = 2 alors
nivLoco vaut nivLoco + 1
appelle annoncer("Locomotives plus rapides !")
sinon si k = 3 alors
appelle annoncer("Nouvelle gare : " + VILLES[nbGares] + " !")
nbGares vaut nbGares + 1
appelle recalculerLigne()
appelle espacerTrains()
sinon si k = 4 alors
nivGrandes vaut nivGrandes + 1
sinon
nivBillet vaut nivBillet + 1
fin si
fin si
fin procédure
procédure vendreBillets(g)
v est un nombre
v vaut 2 + revenuSec() * 0.08
appelle gagner(v)
appelle lancerTexte(VX[g], VY[g] - 22, "+" + nombreProd(v))
fin procédure
fonction ticketY()
si VY[ticketGare] - 38 < CARTE_Y + 16 alors
retourne VY[ticketGare] + 36
fin si
retourne VY[ticketGare] - 38
fin fonction
procédure attraperTicket()
x est un nombre
x vaut VX[ticketGare]
y est un nombre
y vaut ticketY()
si hasard(0, 1) = 0 alors
v est un nombre
v vaut minimum(pieces * 0.15, minimum(revenuSec(), PLAFOND / 900) * 900) + 40
appelle gagner(v)
appelle annoncer("Ticket doré : +" + nombreTexte(v) + " pièces !")
appelle lancerTexte(x, y, "+" + nombreTexte(v))
sinon
pointe vaut 30
appelle annoncer("Heure de pointe : billets x5 pendant 30 s !")
fin si
ticketVie vaut 0
fin procédure
procédure changerRegion()
medaillesGagnees vaut regionsGagnables()
medailles vaut medailles + medaillesGagnees
region vaut (region + 1) mod 3
appelle nouvellePartie()
appelle recalculerLigne()
appelle espacerTrains()
voyageAnim vaut 2.5
etat vaut 7
appelle sauverPartie()
fin procédure
@ LE TEMPS QUI PASSE
procédure avancer(dt)
k est un nombre
j est un nombre
pour k de 0 à nbTrains - 1
ds est un nombre
ds vaut vitesseTrain() * dt
si trTurbo[k] > 0 alors
ds vaut ds * 2
trTurbo[k] vaut trTurbo[k] - dt
fin si
ancienS est un nombre
ancienS vaut trS[k]
nouveauS est un nombre
nouveauS vaut ancienS + ds
pour j de 0 à nbGares - 1
passe est un booléen
passe vaut faux
si cumul[j] > ancienS et cumul[j] <= nouveauS alors
passe vaut vrai
fin si
si cumul[j] + longueurLigne > ancienS et cumul[j] + longueurLigne <= nouveauS alors
passe vaut vrai
fin si
si passe alors
v est un nombre
v vaut gainPassage()
appelle gagner(v)
appelle lancerTexte(VX[j], VY[j] - 20, "+" + nombreProd(v))
fin si
fin pour
si nouveauS >= longueurLigne alors
nouveauS vaut nouveauS - longueurLigne
fin si
trS[k] vaut nouveauS
fin pour
// la fumee des locomotives
si tic mod 3 = 0 alors
pour k de 0 à nbTrains - 1
appelle pointA(trS[k])
fuX[fuProchain] vaut pX + pDX * 6
fuY[fuProchain] vaut pY + pDY * 6 - 6
fuVie[fuProchain] vaut 1
fuProchain vaut (fuProchain + 1) mod 30
fin pour
fin si
pour k de 0 à 29
si fuVie[k] > 0 alors
fuVie[k] vaut fuVie[k] - dt * 1.3
fuY[k] vaut fuY[k] - dt * 14
fin si
fin pour
pour k de 0 à 13
si ftVie[k] > 0 alors
ftVie[k] vaut ftVie[k] - dt * 1.1
ftY[k] vaut ftY[k] - dt * 30
fin si
fin pour
si pointe > 0 alors
pointe vaut pointe - dt
fin si
si ticketVie > 0 alors
ticketVie vaut ticketVie - dt
sinon
ticketAttente vaut ticketAttente - dt
si ticketAttente <= 0 alors
ticketVie vaut 10
ticketGare vaut hasard(0, nbGares - 1)
ticketAttente vaut hasard(50, 100)
fin si
fin si
si msgVie > 0 alors
msgVie vaut msgVie - dt
fin si
si voyageAnim > 0 alors
voyageAnim vaut voyageAnim - dt
si voyageAnim <= 0 et etat = 7 alors
etat vaut 1
appelle annoncer("Bienvenue dans " + NOMS_REGION[region] + " !")
fin si
fin si
fin procédure
@ DESSIN DE LA CARTE
procédure dessinerArbre(x, y)
si region = 1 alors
// un cactus
rectangle_arrondi(ecran, x - 3, y - 14, 6, 16, 3, ARBRE[1])
rectangle_arrondi(ecran, x - 9, y - 9, 4, 7, 2, ARBRE[1])
rectangle_arrondi(ecran, x + 5, y - 11, 4, 7, 2, ARBRE[1])
rectangle(ecran, x - 9, y - 4, 6, 3, ARBRE[1])
rectangle(ecran, x + 3, y - 6, 6, 3, ARBRE[1])
sinon si region = 2 alors
// un sapin enneige
rectangle(ecran, x - 1.5, y - 2, 3, 5, #6B4F3A)
polygone(ecran, x, y - 18, x + 8, y - 2, x - 8, y - 2, ARBRE[2])
polygone(ecran, x, y - 18, x + 4, y - 10, x - 4, y - 10, #FFFFFF)
sinon
rectangle(ecran, x - 1.5, y - 3, 3, 6, #7C5A3A)
cercle(ecran, x, y - 8, 8, ARBRE[0])
cercle(ecran, x - 2, y - 10, 5, ARBRE2[0])
fin si
fin procédure
procédure dessinerDecor()
rectangle(ecran, 0, CARTE_Y, 560, CARTE_BAS - CARTE_Y, SOL[region])
// des taches d'herbe ou de sable
ellipse(ecran, 180, 160, 70, 30, SOL2[region])
ellipse(ecran, 420, 230, 80, 34, SOL2[region])
ellipse(ecran, 290, 330, 90, 20, SOL2[region])
ellipse(ecran, 470, 90, 50, 18, SOL2[region])
// le lac
ellipse(ecran, 62, 123, 34, 20, EAU[region])
ellipse(ecran, 56, 119, 20, 9, rgba(255, 255, 255, 0.25))
k est un nombre
pour k de 0 à 4
x est un nombre
x vaut MONT_X[k]
y est un nombre
y vaut MONT_Y[k]
polygone(ecran, x - 26, y + 8, x, y - 26, x + 26, y + 8, MONT[region])
polygone(ecran, x, y - 26, x + 26, y + 8, x + 8, y + 8, rgba(0, 0, 0, 0.12))
polygone(ecran, x - 8, y - 16, x, y - 26, x + 8, y - 16, x + 3, y - 13, x - 2, y - 17, #FFFFFF)
fin pour
pour k de 0 à 39
appelle dessinerArbre(ARB_X[k], ARB_Y[k])
fin pour
fin procédure
procédure dessinerRails()
k est un nombre
pour k de 0 à nbGares - 1
suivant est un nombre
suivant vaut (k + 1) mod nbGares
x1 est un nombre
x1 vaut VX[k]
y1 est un nombre
y1 vaut VY[k]
dx est un nombre
dx vaut (VX[suivant] - x1) / segL[k]
dy est un nombre
dy vaut (VY[suivant] - y1) / segL[k]
// les traverses
nb est un nombre
nb vaut arrondi_inferieur(segL[k] / 9)
t est un nombre
pour t de 0 à nb
cx est un nombre
cx vaut x1 + dx * t * 9
cy est un nombre
cy vaut y1 + dy * t * 9
ligne(ecran, cx - dy * 6, cy + dx * 6, cx + dy * 6, cy - dx * 6, #7A5530, 3)
fin pour
// les deux rails
ligne(ecran, x1 - dy * 3.5, y1 + dx * 3.5, VX[suivant] - dy * 3.5, VY[suivant] + dx * 3.5, #4B5563, 1.6)
ligne(ecran, x1 + dy * 3.5, y1 - dx * 3.5, VX[suivant] + dy * 3.5, VY[suivant] - dx * 3.5, #4B5563, 1.6)
fin pour
fin procédure
procédure dessinerGare(g)
x est un nombre
x vaut VX[g]
y est un nombre
y vaut VY[g]
rectangle_arrondi(ecran, x - 18, y - 6, 36, 12, 4, rgba(0, 0, 0, 0.15))
rectangle_arrondi(ecran, x - 16, y - 5, 32, 10, 3, #D6D3D1)
// le batiment grandit avec les grandes gares
lb est un nombre
lb vaut 18 + minimum(nivGrandes, 6) * 2
hb est un nombre
hb vaut 10 + minimum(nivGrandes, 6)
rectangle(ecran, x - lb / 2, y - 5 - hb, lb, hb, #FDE68A)
polygone(ecran, x - lb / 2 - 3, y - 5 - hb, x, y - 13 - hb, x + lb / 2 + 3, y - 5 - hb, #B91C1C)
rectangle(ecran, x - 3, y - 11, 6, 6, #78350F)
si nivGrandes >= 3 alors
rectangle(ecran, x - 3, y - 22 - hb, 6, 10, #FDE68A)
cercle(ecran, x, y - 17 - hb, 2.5, #FFFFFF)
fin si
appelle centrer(VILLES[g], x, y + 18, rgba(17, 24, 39, 0.85), 10)
fin procédure
procédure dessinerWagon(cx, cy, dx, dy, lg, larg, coul)
ptsWagon[0] vaut cx + dx * lg / 2 - dy * larg / 2
ptsWagon[1] vaut cy + dy * lg / 2 + dx * larg / 2
ptsWagon[2] vaut cx + dx * lg / 2 + dy * larg / 2
ptsWagon[3] vaut cy + dy * lg / 2 - dx * larg / 2
ptsWagon[4] vaut cx - dx * lg / 2 + dy * larg / 2
ptsWagon[5] vaut cy - dy * lg / 2 - dx * larg / 2
ptsWagon[6] vaut cx - dx * lg / 2 - dy * larg / 2
ptsWagon[7] vaut cy - dy * lg / 2 + dx * larg / 2
polygone(ecran, ptsWagon, coul)
fin procédure
procédure dessinerTrains()
k est un nombre
pour k de 0 à nbTrains - 1
coul est un texte
coul vaut COUL_TRAIN[k]
w est un nombre
pour w de 0 à nbWagons - 1
appelle pointA(trS[k] - (nbWagons - w) * 15)
appelle dessinerWagon(pX, pY, pDX, pDY, 13, 9, #374151)
appelle dessinerWagon(pX, pY, pDX, pDY, 11, 6, coul)
cercle(ecran, pX, pY, 1.4, #FFFFFF)
fin pour
appelle pointA(trS[k])
si trTurbo[k] > 0 alors
cercle(ecran, pX, pY, 13, rgba(253, 224, 71, 0.35 + (tic mod 4) * 0.08))
fin si
appelle dessinerWagon(pX, pY, pDX, pDY, 15, 10, #111827)
appelle dessinerWagon(pX - pDX * 2, pY - pDY * 2, pDX, pDY, 9, 7, coul)
cercle(ecran, pX + pDX * 6, pY + pDY * 6, 2, #FDE047)
fin pour
pour k de 0 à 29
si fuVie[k] > 0 alors
cercle(ecran, fuX[k], fuY[k], 2 + (1 - fuVie[k]) * 5, rgba(255, 255, 255, fuVie[k] * 0.55))
fin si
fin pour
fin procédure
procédure dessinerTicket()
si ticketVie > 0 alors
x est un nombre
x vaut VX[ticketGare]
y est un nombre
y vaut ticketY() + sinus(tic * 0.3) * 3
cercle(ecran, x, y, 18, rgba(253, 224, 71, 0.25 + (tic mod 6) * 0.05))
rectangle_arrondi(ecran, x - 13, y - 8, 26, 16, 3, #FACC15)
rectangle(ecran, x - 13, y - 8, 7, 16, #EAB308)
ligne(ecran, x - 2, y - 3, x + 9, y - 3, #A16207, 1.5)
ligne(ecran, x - 2, y + 2, x + 6, y + 2, #A16207, 1.5)
fin si
fin procédure
procédure dessinerCarte()
appelle dessinerDecor()
appelle dessinerRails()
k est un nombre
pour k de 0 à nbGares - 1
appelle dessinerGare(k)
fin pour
appelle dessinerTrains()
appelle dessinerTicket()
pour k de 0 à 13
si ftVie[k] > 0 alors
appelle centrer(ftTxt[k], ftX[k] + 1, ftY[k] + 1, rgba(17, 24, 39, 0.8 * limiter(ftVie[k], 0, 1)), 12)
appelle centrer(ftTxt[k], ftX[k], ftY[k], rgba(255, 255, 255, limiter(ftVie[k], 0, 1)), 12)
fin si
fin pour
si msgVie > 0 alors
rectangle_arrondi(ecran, 120, CARTE_BAS - 34, 320, 26, 13, rgba(17, 24, 39, 0.7 * limiter(msgVie, 0, 1)))
appelle centrer(msgTxt, 280, CARTE_BAS - 16, rgba(255, 255, 255, limiter(msgVie, 0, 1)), 12)
sinon si totalTout < 40 alors
rectangle_arrondi(ecran, 100, CARTE_BAS - 34, 360, 26, 13, rgba(17, 24, 39, 0.6))
appelle centrer("Clique une gare pour vendre des billets, un train pour le turbo", 280, CARTE_BAS - 16, #FFFFFF, 11)
fin si
fin procédure
@ DESSIN DE L'INTERFACE
procédure dessinerPiece(x, y, r)
cercle(ecran, x, y, r, #CA8A04)
cercle(ecran, x - r * 0.1, y - r * 0.1, r * 0.82, #FACC15)
cercle(ecran, x - r * 0.1, y - r * 0.1, r * 0.45, #FDE68A)
fin procédure
procédure dessinerMedaille(x, y)
polygone(ecran, x - 6, y - 14, x - 1, y - 14, x + 2, y - 4, x - 3, y - 4, #2563EB)
polygone(ecran, x + 6, y - 14, x + 1, y - 14, x - 2, y - 4, x + 3, y - 4, #DC2626)
cercle(ecran, x, y + 2, 7, #F59E0B)
cercle(ecran, x, y + 2, 4, #FDE68A)
fin procédure
procédure dessinerHaut()
rectangle(ecran, 0, 0, 560, CARTE_Y, #1F2937)
appelle dessinerPiece(24, 26, 13)
label(ecran, 44, 25, nombreTexte(pieces) + " pièces", #FFFFFF, 19)
coulR est un texte
coulR vaut #9CA3AF
si pointe > 0 alors
coulR vaut #FACC15
fin si
txtR est un texte
txtR vaut nombreProd(revenuSec()) + " par seconde"
si pointe > 0 alors
txtR vaut txtR + " · heure de pointe " + convertir_texte(arrondi_superieur(pointe)) + " s"
fin si
label(ecran, 44, 43, txtR, coulR, 11)
gainR est un nombre
gainR vaut regionsGagnables()
si gainR >= 1 alors
appelle bouton(386, 10, 166, 32, "Nouvelle région +" + convertir_texte(gainR), sialors(tic mod 16 < 8, #7C3AED, #6D28D9), #FFFFFF, 12)
sinon
appelle dessinerMedaille(400, 24)
label(ecran, 414, 25, convertir_texte(medailles) + " médaille" + sialors(medailles > 1, "s", ""), #E5E7EB, 13)
label(ecran, 414, 41, "revenus +" + convertir_texte(medailles * 20) + " %", #9CA3AF, 10)
fin si
fin procédure
procédure dessinerIconeAchat(k, cx, cy)
si k = 0 alors
rectangle_arrondi(ecran, cx - 16, cy - 8, 26, 14, 3, #DC2626)
rectangle(ecran, cx + 2, cy - 14, 8, 8, #111827)
rectangle(ecran, cx - 12, cy - 13, 5, 6, #374151)
cercle(ecran, cx - 10, cy + 8, 3.5, #111827)
cercle(ecran, cx + 4, cy + 8, 3.5, #111827)
polygone(ecran, cx + 10, cy - 8, cx + 16, cy + 6, cx + 10, cy + 6, #374151)
sinon si k = 1 alors
rectangle_arrondi(ecran, cx - 15, cy - 9, 30, 15, 3, #2563EB)
rectangle(ecran, cx - 11, cy - 6, 6, 5, #DBEAFE)
rectangle(ecran, cx - 3, cy - 6, 6, 5, #DBEAFE)
rectangle(ecran, cx + 5, cy - 6, 6, 5, #DBEAFE)
cercle(ecran, cx - 9, cy + 8, 3.5, #111827)
cercle(ecran, cx + 9, cy + 8, 3.5, #111827)
sinon si k = 2 alors
// un compteur de vitesse
cercle(ecran, cx, cy + 4, 15, #374151)
cercle(ecran, cx, cy + 4, 12, #F3F4F6)
rectangle(ecran, cx - 16, cy + 5, 32, 14, #FFFFFF)
ligne(ecran, cx, cy + 4, cx + 8, cy - 4, #DC2626, 2.5)
cercle(ecran, cx, cy + 4, 2.5, #111827)
sinon si k = 3 alors
rectangle(ecran, cx - 12, cy - 4, 24, 12, #FDE68A)
polygone(ecran, cx - 15, cy - 4, cx, cy - 14, cx + 15, cy - 4, #B91C1C)
rectangle(ecran, cx - 3, cy + 1, 6, 7, #78350F)
cercle(ecran, cx + 13, cy - 12, 6, #16A34A)
rectangle(ecran, cx + 12, cy - 15, 2, 6, #FFFFFF)
rectangle(ecran, cx + 10, cy - 13, 6, 2, #FFFFFF)
sinon si k = 4 alors
rectangle(ecran, cx - 16, cy - 2, 32, 12, #FDE68A)
polygone(ecran, cx - 18, cy - 2, cx, cy - 12, cx + 18, cy - 2, #B91C1C)
rectangle(ecran, cx - 3, cy - 20, 6, 10, #FDE68A)
cercle(ecran, cx, cy - 15, 2.5, #FFFFFF)
rectangle(ecran, cx - 11, cy + 2, 4, 8, #78350F)
rectangle(ecran, cx + 7, cy + 2, 4, 8, #78350F)
sinon
rectangle_arrondi(ecran, cx - 16, cy - 9, 32, 18, 3, #FACC15)
rectangle(ecran, cx - 16, cy - 9, 8, 18, #EAB308)
ligne(ecran, cx - 4, cy - 3, cx + 11, cy - 3, #A16207, 2)
ligne(ecran, cx - 4, cy + 3, cx + 7, cy + 3, #A16207, 2)
fin si
fin procédure
procédure dessinerBoutique()
rectangle(ecran, 0, CARTE_BAS, 560, 550 - CARTE_BAS, #111827)
k est un nombre
pour k de 0 à 5
x est un nombre
x vaut 8 + (k mod 3) * 184
y est un nombre
y vaut CARTE_BAS + 8 + arrondi_inferieur(k / 3) * 92
auMax est un booléen
auMax vaut achatAuMax(k)
cout est un nombre
cout vaut coutAchat(k)
assez est un booléen
assez vaut faux
si non auMax et cout < PLAFOND et pieces >= cout alors
assez vaut vrai
fin si
fond est un texte
fond vaut #1F2937
si assez alors
fond vaut #1E3A5F
fin si
rectangle_arrondi(ecran, x, y, 176, 84, 12, fond)
si assez alors
rectangle_arrondi(ecran, x, y, 176, 4, 2, #38BDF8)
fin si
rectangle_arrondi(ecran, x + 8, y + 10, 46, 46, 10, #F9FAFB)
appelle dessinerIconeAchat(k, x + 31, y + 33)
label(ecran, x + 62, y + 26, NOMS_ACHAT[k], #F9FAFB, 13)
label(ecran, x + 62, y + 44, texteNiveau(k), #9CA3AF, 11)
si auMax alors
appelle centrer("Maximum atteint", x + 88, y + 74, #6B7280, 12)
sinon si cout >= PLAFOND alors
appelle centrer("hors de portée", x + 88, y + 74, #6B7280, 12)
sinon
coulP est un texte
coulP vaut #F87171
si assez alors
coulP vaut #4ADE80
fin si
appelle dessinerPiece(x + 70, y + 69, 6)
label(ecran, x + 81, y + 74, nombreTexte(cout), coulP, 13)
fin si
fin pour
fin procédure
@ LES FENETRES
procédure voile()
rectangle(ecran, 0, 0, 560, 550, rgba(17, 24, 39, 0.72))
fin procédure
procédure fenetre(y, hf)
rectangle_arrondi(ecran, 50, y + 4, 460, hf, 20, rgba(0, 0, 0, 0.35))
rectangle_arrondi(ecran, 50, y, 460, hf, 20, #FFFBEB)
rectangle_arrondi(ecran, 50, y, 460, 8, 4, #DC2626)
fin procédure
procédure ecranAccueil()
appelle voile()
appelle fenetre(64, 420)
appelle dessinerIconeAchat(0, 140, 116)
appelle dessinerIconeAchat(1, 420, 116)
appelle centrer("Train Express", 280, 124, #1F2937, 32)
appelle centrer("Construis le plus grand réseau du pays", 280, 150, #B45309, 14)
label(ecran, 84, 196, "Tes trains roulent tout seuls : à chaque gare traversée,", #1F2937, 13)
label(ecran, 84, 214, "les passagers paient leur billet.", #1F2937, 13)
label(ecran, 84, 244, "Achète des trains, des wagons, des locomotives rapides", #1F2937, 13)
label(ecran, 84, 262, "et ouvre de nouvelles gares.", #1F2937, 13)
label(ecran, 84, 292, "Clique une gare pour vendre des billets,", #1F2937, 13)
label(ecran, 84, 310, "clique un train pour lui donner un coup de turbo.", #1F2937, 13)
label(ecran, 84, 340, "Attrape les tickets dorés pour un bonus !", #1F2937, 13)
label(ecran, 84, 370, "Une nouvelle région rapporte des médailles.", #1F2937, 13)
cercle(ecran, 70, 192, 3.5, #DC2626)
cercle(ecran, 70, 240, 3.5, #DC2626)
cercle(ecran, 70, 288, 3.5, #DC2626)
cercle(ecran, 70, 336, 3.5, #EAB308)
cercle(ecran, 70, 366, 3.5, #7C3AED)
appelle bouton(190, 404, 180, 50, "En voiture !", sialors(tic mod 16 < 8, #DC2626, #B91C1C), #FFFFFF, 18)
fin procédure
procédure ecranRetour()
appelle voile()
appelle fenetre(140, 270)
appelle centrer("Bon retour, chef de gare !", 280, 192, #1F2937, 24)
appelle centrer("Pendant ton absence (" + dureeTexte(dureeAbsence) + "),", 280, 226, #6B7280, 13)
appelle centrer("tes trains ont rapporté", 280, 246, #6B7280, 13)
appelle dessinerPiece(170, 284, 14)
appelle centrer("+" + nombreTexte(gainAbsence), 290, 294, #B45309, 30)
appelle bouton(200, 330, 160, 46, "Encaisser", #DC2626, #FFFFFF, 16)
fin procédure
procédure ecranRegion()
appelle voile()
appelle fenetre(110, 330)
appelle dessinerMedaille(280, 166)
appelle centrer("Partir vers une nouvelle région", 280, 214, #1F2937, 22)
gainR est un nombre
gainR vaut regionsGagnables()
appelle centrer("Prochaine région : " + NOMS_REGION[(region + 1) mod 3], 280, 244, #B45309, 14)
appelle centrer("Tu gagnes +" + convertir_texte(gainR) + " médaille" + sialors(gainR > 1, "s", "") + " : revenus +" + convertir_texte((medailles + gainR) * 20) + " %.", 280, 272, #1F2937, 13)
appelle centrer("Tes pièces, trains, wagons et gares", 280, 304, #B91C1C, 13)
appelle centrer("repartent à zéro.", 280, 322, #B91C1C, 13)
appelle bouton(110, 360, 160, 46, "Rester", #E5E7EB, #1F2937, 15)
appelle bouton(290, 360, 160, 46, "Partir !", #7C3AED, #FFFFFF, 15)
fin procédure
procédure ecranVoyage()
rectangle(ecran, 0, 0, 560, 550, #1F2937)
// le paysage defile derriere un train
avance est un nombre
avance vaut (2.5 - voyageAnim) * 300
rectangle(ecran, 0, 330, 560, 220, SOL[region])
k est un nombre
pour k de 0 à 7
mx est un nombre
mx vaut ((k * 140 - avance * 0.3 + 7000) mod 700) - 70
polygone(ecran, mx - 70, 330, mx, 250, mx + 70, 330, MONT[region])
fin pour
pour k de 0 à 13
ax est un nombre
ax vaut ((k * 50 - avance + 7000) mod 700) - 70
appelle dessinerArbre(ax, 370)
fin pour
rectangle(ecran, 0, 392, 560, 6, #4B5563)
pour k de 0 à 40
rectangle(ecran, ((k * 16 - avance + 6560) mod 656) - 16, 398, 8, 4, #7A5530)
fin pour
pour k de 0 à 3
rectangle_arrondi(ecran, 140 + k * 70, 352, 64, 36, 6, sialors(k = 3, #111827, COUL_TRAIN[k]))
cercle(ecran, 154 + k * 70, 390, 6, #111827)
cercle(ecran, 190 + k * 70, 390, 6, #111827)
fin pour
rectangle(ecran, 352, 338, 14, 16, #111827)
appelle centrer("En route vers " + NOMS_REGION[region], 280, 160, #FFFFFF, 26)
appelle dessinerMedaille(280, 210)
appelle centrer("+" + convertir_texte(medaillesGagnees) + " médaille" + sialors(medaillesGagnees > 1, "s", ""), 280, 250, #FDE68A, 18)
fin procédure
procédure dessiner()
effacer(ecran)
contour(ecran, #0)
si etat = 7 alors
appelle ecranVoyage()
sinon
appelle dessinerCarte()
appelle dessinerHaut()
appelle dessinerBoutique()
si etat = 6 alors
appelle ecranAccueil()
sinon si etat = 5 alors
appelle ecranRetour()
sinon si etat = 4 alors
appelle ecranRegion()
fin si
fin si
fin procédure
@ LES COMMANDES
procédure clicCarte(x, y)
surTicket est un booléen
surTicket vaut faux
si ticketVie > 0 alors
si hypotenuse(x - VX[ticketGare], y - ticketY()) < 22 alors
surTicket vaut vrai
fin si
fin si
// le ticket dore d'abord, sinon le train ou la gare le plus proche du clic
k est un nombre
meilleurT est un nombre
meilleurT vaut -1
distT est un nombre
distT vaut 9999
pour k de 0 à nbTrains - 1
w est un nombre
pour w de 0 à nbWagons
appelle pointA(trS[k] - w * 15)
d est un nombre
d vaut hypotenuse(x - pX, y - pY)
si d < distT alors
distT vaut d
meilleurT vaut k
fin si
fin pour
fin pour
meilleurG est un nombre
meilleurG vaut -1
distG est un nombre
distG vaut 9999
pour k de 0 à nbGares - 1
d est un nombre
d vaut hypotenuse(x - VX[k], y - (VY[k] - 8))
si d < distG alors
distG vaut d
meilleurG vaut k
fin si
fin pour
si surTicket alors
appelle attraperTicket()
sinon si distT < 12 et distT < distG alors
trTurbo[meilleurT] vaut 6
appelle annoncer("Coup de turbo !")
sinon si distG < 22 alors
appelle vendreBillets(meilleurG)
sinon si distT < 12 alors
trTurbo[meilleurT] vaut 6
appelle annoncer("Coup de turbo !")
fin si
fin procédure
procédure lireOrdre(act, x, y)
si act = 0 alors
si etat = 6 alors
si clique(x, y, 190, 404, 180, 50) alors
etat vaut 1
fin si
sinon si etat = 5 alors
si clique(x, y, 200, 330, 160, 46) alors
etat vaut 1
fin si
sinon si etat = 4 alors
si clique(x, y, 110, 360, 160, 46) alors
etat vaut 1
sinon si clique(x, y, 290, 360, 160, 46) alors
appelle changerRegion()
fin si
sinon si etat = 1 alors
si y < CARTE_Y alors
si clique(x, y, 386, 10, 166, 32) et regionsGagnables() >= 1 alors
etat vaut 4
fin si
sinon si y < CARTE_BAS alors
appelle clicCarte(x, y)
sinon
col est un nombre
col vaut arrondi_inferieur((x - 8) / 184)
rang est un nombre
rang vaut arrondi_inferieur((y - CARTE_BAS - 8) / 92)
si col >= 0 et col <= 2 et rang >= 0 et rang <= 1 alors
appelle acheter(rang * 3 + col)
fin si
fin si
fin si
fin si
fin procédure
@ LE PROCESSUS
processus Reseau()
derniereMesure vaut chrono()
tant que appActif
tic vaut tic + 1
nbLus est un nombre
nbLus vaut 0
tant que teteO <> queueO et nbLus < 8
appelle lireOrdre(ordres[teteO], ordX[teteO], ordY[teteO])
teteO vaut (teteO + 1) mod 32
nbLus vaut nbLus + 1
fin tant que
instant est un nombre
instant vaut chrono()
dt est un nombre
dt vaut limiter((instant - derniereMesure) / 1000, 0, 0.5)
derniereMesure vaut instant
si etat = 1 ou etat = 7 alors
appelle avancer(dt)
sauveAttente vaut sauveAttente - dt
si sauveAttente <= 0 alors
appelle sauverPartie()
sauveAttente vaut 15
fin si
fin si
appelle dessiner()
affiche ecran
pause 60
fin tant que
appelle sauverPartie()
effacer(ecran)
rectangle(ecran, 0, 0, 560, 550, #1F2937)
appelle centrer("Partie sauvegardée : tes trains continuent de rouler !", 280, 280, #FDE68A, 16)
affiche ecran
fin processus
@ DEMARRAGE
appelle charger()
appelle dessiner()
affiche ecran
Reseau()
tant que appActif
interagir ecran, ["x"] dans action, sourisX, sourisY
si action = 1 alors
appActif vaut faux
sinon si (queueO + 1) mod 32 <> teteO alors
ordres[queueO] vaut action
ordX[queueO] vaut sourisX
ordY[queueO] vaut sourisY
queueO vaut (queueO + 1) mod 32
fin si
fin tant que