Bonsoir tous,
I° Rien de bien neuf, si ce n'est que je considère maintenant comme terminée
la partie FORTH du programme.
Je la donne à suivre avec des notes explicatives :
Vocabulaire:
Code : Tout sélectionner
(index ... adresse paramètres)
<index> BOID(N) : Met dans la pile de données l'adresse paramètres de l'index-ième BOID
(adresse paramètres ... X, Y)
<adresse paramètres> GETNNN : Met dans la pile de données les valeurs X et Y du champs NNNN de l'objet
<adresse paramètres> GETPOS : Champs position
<adresse paramètres> GETVELOCTY : Champs Velocity
<adresse paramètres> GETV1 : Champs V1
<adresse paramètres> GETV2 : Champs V2
<adresse paramètres> GETV3 : Champs V3
(X, Y, adresse paramètres...)
X Y <adresse paramètres> SETNNN : Sauvegarde dans le champs NNN les valeurs X et Y de l'objet
X Y <adresse paramètres> SETPOS : Champs position
X Y <adresse paramètres> SETVELOCTY : Champs Velocity
X Y <adresse paramètres> SETV1 : Champs V1
X Y <adresse paramètres> SETV2 : Champs V2
X Y <adresse paramètres> SETV3 : Champs V3
(X, Y, adresse paramètres...)
X Y <adresse paramètres> ADDVNN : Somme dans le champs NNN les valeurs X et Y de l'objet
X Y <adresse paramètres> ADDPOS : Champs position
X Y <adresse paramètres> ADDVELOCTY : Champs Velocity
X Y <adresse paramètres> ADDV1 : Champs V1
X Y <adresse paramètres> ADDV2 : Champs V2
X Y <adresse paramètres> ADDV3 : Champs V3
(a, b, c, d ... a-c, b-d)
SUBV :fait la différence de 2 vecteurs
(a, b, n ... a/n, b/n)
DIVV : Divise un vecteur a b par un scalaire n
(a, b, c, d ... flag'a<c' AND 'b<d')
V<V : Retourne flag 1 si a<c et b<d - sinon 0
(/Valeur absolue vecteur)
(a, b ... |a|, |b|)
ABSV : Fournit la valeur absolue d'un vecteur a b
les procédures principales :
Code : Tout sélectionner
: RULES123
18 1 DO ; Du Boid 1 à 18 (1° lecture)
I BOID(N) ; Adresse paramètre du Boid
DUP MAIN.OBJ ! ; Copie et sauvegarde dans variable MAIN.OBJ
CLEAR.VFIELD ; Mise à zéro de son V1 , V2 et V3
RULE.SEPARATION ; Applique loi 1
RULE.COHESION ; Applique Loi 2
RULE.ALIGNEMENT ; Applique Loi 3
LOOP ; Boid suivant
CLEAR.SIGMA ; ; Mise à zéro des deux SIGMA
(adressParam 1° lecture .....)
: RULE.ALIGNEMENT
>R ; Adresse objet dans pile R
SIGMA.V3 2@ ; Lit vecteur SIGMA V3 = Somme des 17 V3 des Boids
I GETVELCTY.M ; Lit vecteur Velocity de l'objet (de 1° lecture)
SUBV ; SIGMAV3 - VELOCTY de l'objet = somme des V3 des 16 voisins
V/16 ; (SIGMAV3 - VELOCTY)/16 -> moyenne des V3 des 16 voisins
I GETVELCTY.M ; Lit vecteur Velocity de l'objet (de 1° lecture)
SUBV ; (SIGMAV3 - VELOCTY)/16 - VELOCTY
ALIGNEMENT @ ; Lit facteur Alignement
DIVV ; ((SIGMAV3 - VELOCTY)/16 - VELOCTY)/FacteurAlignement
R> ; dés-empile Adresse objet
SETV3.M ; ; Sauvegarde ((SIGMAV3 - VELOCTY)/16 - VELOCTY)/FacteurAlignement dans V3 de l'objet
(adressParam 1° lecture .....adressParam 1° lecture)
: RULE.COHESION
>R ; Adresse objet dans pile R
SIGMA.V1 2@ ; Lit vecteur SIGMA V1 = Somme des 17 V1 des Boids
I GETPOS.M ; Lit vecteur Position de l'objet (de 1° lecture)
SUBV ; SIGMAV2 - Position de l'objet = somme des positions des 16 voisins
V/16 ; (SIGMAV2 - Position de l'objet)/16 -> moyenne des V3 des 16 voisins
LEADER 2@ ; Vecteur Position d'un LEADER manœuvré par utilisateur
ADDV ; moyenne des Positions des 16 voisins + position Leader
2 DIVV ; divisé par 2 -> Centre de gravité perçu par le Boid
I GETPOS.M ; Lit position du Boid (de 1° lecture)
SUBV ; Calcule sa distance au centre de gravité
COHESION @ ; Lit facteur cohésion
DIVV ; Distance au Centre Gravité / facteur cohésion
I SETV1.M ; dans V1 de l'objet
R> ; ; dés-empile Adresse objet
(adressParam 1° lecture .....adressParam 1° lecture)
: RULE.SEPARATION
18 1 DO ; Relit tous les BOIDS (2° lecture)
I BOID(N) ; Adresse paramètre du BOID (2° lecture)
DUP >R ; Copie dans pile R
MAIN.OBJ @ - ; Son adresse paramètre = Adr param BOID (1° lecture) ?
IF ; non 0 donc BOID différent
MAIN.OBJ @ GETPOS.M ; Lit position BOID (1° lecture)
I GETPOS.M ; Lit position BOID (2° lecture)
SUBV ; Distance entre eux
DDUP ABSV ; Fait copie et donne Valeur ABS
SEPARATION 2@ ; Lit distance SEPARATION mini pré-définie
V<V ; Compare |distance| avec distance séparation
IF ; si <
SCALE ; divise valeur relative distance par 2
MAIN.OBJ @ ADDV2.M ; et somme dans V2 du BOID (1° lecture)
ELSE ; Si distance >=
DROP DROP ; Retire distance de la pile données
ENDIF ; fin si
ENDIF ; fin si
R> DROP ; Retire sommet Pile R l'adressParam 2° lecture et jette
LOOP ; ; Prochain Boid (2° lecture)
(adressParam .....adressParam)
: UPDATE.VLCTY
>R ; Copie adresse paramètres dans pile R
I GETV1.M ; lit champs V1
I GETV2.M ; lit champs V2
ADDV ; V1 + V2
I GETV3.M ; lit champs V3
ADDV ; V1 + V2 + V3
I ADDVELCTY.M ; somme (V1 + V2 + V3) au champs Velocity
R> ; ; Retire sommet Pile R
et enfin le listing complet. Ce programme se trouve dans la K7
>>>
<<<
compiler par
lancer par
(Touche "Q" pour saisir les données)
LISTING COMPLET
Code : Tout sélectionner
( /Listing )
: TASK ;
HEX
( /Disable et Enable Interrupts)
CREATE DI 1A50 , 0EB6 , SMUDGE
CREATE EI 1CAF , 0EB6 , SMUDGE
( /Divise vecteur par 8)
( a, b, 8 ... a/8, b/8)
: V/8 8 DUP >R / SWAP R> / SWAP ;
( /Divise vecteur par 16)
( a, b, 16 ... a/16, b/16)
: V/16 16 DUP >R / SWAP R> / SWAP ;
( /Lit une variable double)
(adr ....a, b)
: 2@ DUP @ SWAP 2+ @ ;
( /Sauvegarde variable double)
( a, b, adr ...)
: 2! DUP >R 2+ ! R> ! ;
( /Additionne variable double)
( a, b , adr...)
: 2+! DUP >R 2+ +! R> +! ;
( /duplique TOS et DOS)
( a, b ...a, b, a, b)
: DDUP OVER OVER ;
( /Saisie au clavier de n 0<n<1000)
( ...n)
: #IN 0 0 PAD DUP 3 EXPECT 1- (NUMBER) DROP DROP ;
: /8 8 / ;
( /Valeur absolue vecteur)
( a, b ... |a|, |b|)
: ABSV >R ABS R> ABS ;
( /Lit le champs 'position')
( adrObjet ... a, b)
: GETPOS.M 2@ ;
( /Somme dans le champs 'position')
( a, b, adrObjet ...)
: ADDPOS.M 2+! ;
( /compare 2 vecteurs)
( a, b, c, d ... flag'a<c' AND 'b<d')
: V<V SWAP >R < SWAP R> < AND ;
( /Enregistre dans le champs 'position')
( a, b, adrObjet ...)
: SETPOS.M 2! ;
( a, b, c, d ... a-c, b-d)
: SUBV SWAP >R - SWAP R> - SWAP ;
( a, b, c, d ... a+c, b+d)
: ADDV SWAP >R + SWAP R> + SWAP ;
( Xpos, Ypos ... adresse-écran, Flag coté Gauche/Droit)
: TR-CELL >R 8 / DUP 1 AND SWAP 2 / R> 8 / A0 * + SWAP ;
( /Choix écran Forme du MO5)
( .....)
: FORME A7C0 DUP C@ 1 OR SWAP C! ;
( / AND n avec valeur adresse adr et sauvegarde dans adr)
( n, adr ...)
: AND.C! DUP C@ SWAP >R AND R> FORME C! ;
( / OR n avec valeur adresse adr et sauvegarde dans adr)
( n, adr ...)
: OR.C! DUP C@ SWAP >R OR R> FORME C! ;
( /Déclare variable double)
( .....)
: 2VARIABLE <BUILDS SWAP , , DOES> ;
( /Limite ordonnées écran)
18E CONSTANT YMAX
( /Limite absices écran)
27E CONSTANT XMAX
( /Variable et constante pour random)
65E8 CONSTANT RMULT
3 1 2VARIABLE RLOC
( /Variable adresse paramètres objet analysé)
0 VARIABLE MAIN.OBJ
( /Variable paramètre Cohésion)
2B VARIABLE COHESION
( /Variable paramètre Alignement)
2 VARIABLE ALIGNEMENT
(/Variable double paramètre Séparation)
14 14 2VARIABLE SEPARATION
( /Variable double coordonnées Leader)
15E D2 2VARIABLE LEADER
( /Variable double somme vecteur V1)
0 0 2VARIABLE SIGMA.V1
( /Variable double somme vecteur V2)
0 0 2VARIABLE SIGMA.V3
( /constructeur de Sprites 4 octets)
: PIC.BOID <BUILDS C, C, C, C, DOES> ;
( /constructeur de Boids _ 10 champs de 2 octets)
: BOIDS.OBJ <BUILDS , , , , , , , , , , DOES> ;
( /Table indexée adresse de Sprites - 8 sprites + 3 répétés - Index de 1 à 11)
: TABLE.PIC.BD <BUILDS , , , , , , , , , , , DOES> SWAP 1- 2 * + @ ;
( /Table indexée adresse de 17 Boids)
: TABLE.OBJ <BUILDS , , , , , , , , , , , , , , , , , DOES> SWAP 1- 2 * + @ ;
( /définition Sprites 'Gauche' et 'Droit')
60 60 F0 F0 PIC.BOID PIC.BD.GCH1
60 60 F0 F0 PIC.BOID PIC.BD.GCH2
F0 F0 60 60 PIC.BOID PIC.BD.GCH3
F0 F0 60 60 PIC.BOID PIC.BD.GCH4
30 F0 F0 30 PIC.BOID PIC.BD.GCH5
D0 F0 60 C0 PIC.BOID PIC.BD.GCH6
C0 60 F0 D0 PIC.BOID PIC.BD.GCH7
C0 60 F0 D0 PIC.BOID PIC.BD.GCH8
C0 F0 F0 C0 PIC.BOID PIC.BD.GCH9
B0 F0 60 30 PIC.BOID PIC.BD.GCH10
30 60 F0 B0 PIC.BOID PIC.BD.GCH11
6 6 F F PIC.BOID PIC.BD.DRT1
6 6 F F PIC.BOID PIC.BD.DRT2
F F 6 6 PIC.BOID PIC.BD.DRT3
F F 6 6 PIC.BOID PIC.BD.DRT4
3 F F 3 PIC.BOID PIC.BD.DRT5
D F 6 C PIC.BOID PIC.BD.DRT6
C 6 F D PIC.BOID PIC.BD.DRT7
C 6 F D PIC.BOID PIC.BD.DRT8
C F F C PIC.BOID PIC.BD.DRT9
B F 6 3 PIC.BOID PIC.BD.DRT10
3 6 F B PIC.BOID PIC.BD.DRT11
( a, b ... b)
: NIP SWAP DROP ;
( n ... r)
: RNDM RLOC 2@ RMULT U* ROT 0 D+ OVER RLOC 2! ;
( / 0<random<n)
( n ... r)
: RANDOM RNDM U* NIP ;
( /Crée tous les Boids)
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD1
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD2
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD3
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD4
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD5
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD6
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD7
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD8
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD9
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD10
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD11
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD12
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD13
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD14
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD15
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD16
0 0 0 0 0 0 0 0 YMAX RANDOM XMAX RANDOM BOIDS.OBJ BD17
( /Construction tables des Sprites gauche et droite)
( /adresse-écran, Index-Sprite + 1)
( /Sprites gauche)
PIC.BD.GCH11 PIC.BD.GCH10 PIC.BD.GCH9 PIC.BD.GCH8 PIC.BD.GCH7 PIC.BD.GCH6 PIC.BD.GCH5 PIC.BD.GCH4 PIC.BD.GCH3 PIC.BD.GCH2 PIC.BD.GCH1 TABLE.PIC.BD PIC.BOID.GAUCHE
( /Sprites droite)
PIC.BD.DRT11 PIC.BD.DRT10 PIC.BD.DRT9 PIC.BD.DRT8 PIC.BD.DRT7 PIC.BD.DRT6 PIC.BD.DRT5 PIC.BD.DRT4 PIC.BD.DRT3 PIC.BD.DRT2 PIC.BD.DRT1 TABLE.PIC.BD PIC.BOID.DROIT
( /Crée la table indexée des Boids)
BD17 BD16 BD15 BD14 BD13 BD12 BD11 BD10 BD9 BD8 BD7 BD6 BD5 BD4 BD3 BD2 BD1 TABLE.OBJ BOID(N)
( /Lit le champs 'Velocity')
( adrObjet ... a, b)
: GETVELCTY.M 4 + GETPOS.M ;
( adresse-écran, Masque... )
: (UNPL.PIC) SWAP DDUP AND.C! DDUP 28 + AND.C! DDUP 50 + AND.C! 78 + AND.C! ;
( Xpos, Ypos .......)
: UNPLOT.PIC.C TR-CELL 0= IF F ELSE F0 ENDIF (UNPL.PIC) ;
( adrObjet...)
: UNPLOT.PIC.M GETPOS.M UNPLOT.PIC.C ;
( /Calcule Masque sprite pour X Velocity)
( adrObjet, Xvelocity...adrObjet, Xindex)
: XINDEXOR DUP -3 < IF DROP 4 ELSE 3 > IF 8 ELSE 0 ENDIF ENDIF ;
( adrObjet, Yvelocity...adrObjet, Yindex)
: YINDEXOR DUP -3 < IF DROP 2 ELSE 3 > IF 1 ELSE 0 ENDIF ENDIF ;
( adrObjet... adrObjet, Index-Sprite + 1)
: CALCULE-INDEXOR DUP GETVELCTY.M >R XINDEXOR R> YINDEXOR + 1+ ;
( adresse-écran, adr'Pic.Boid'... )
: (PLOT.PIC) DDUP C@ SWAP OR.C! DDUP 1+ C@ SWAP 28 + OR.C! DDUP 2+ C@ SWAP 50 + OR.C! 3 + C@ SWAP 78 + OR.C! ;
( adrObjet...adresse-écran, Index-Sprite + 1)
: PLOT.PIC.C CALCULE-INDEXOR >R GETPOS.M TR-CELL R> SWAP 0= IF PIC.BOID.GAUCHE ELSE PIC.BOID.DROIT ENDIF ;
( adrObjet...)
: PLOT.PIC.M PLOT.PIC.C (PLOT.PIC) ;
DECIMAL
( /Lit le champs 'V1')
(adrObjet ... a, b)
: GETV1.M 8 + GETPOS.M ;
( /Lit le champs 'V2')
( adrObjet ... a, b)
: GETV2.M 12 + GETPOS.M ;
( /Lit le champs 'V3')
( adrObjet ... a, b)
: GETV3.M 16 + GETPOS.M ;
( /Sauvegarde dans le champs 'Velocity')
( a, b, adrObjet ...)
: SETVELCTY.M 4 + SETPOS.M ;
( /Sauvegarde dans le champs 'V1')
( a, b, adrObjet ...)
: SETV1.M 8 + SETPOS.M ;
( /Sauvegarde dans le champs 'V2')
( a, b, adrObjet ...)
: SETV2.M 12 + SETPOS.M ;
( /Sauvegarde dans le champs 'V3')
( a, b, adrObjet ...)
: SETV3.M 16 + SETPOS.M ;
( /Somme dans le champs 'velocity')
( a, b, adrObjet ...)
: ADDVELCTY.M 4 + ADDPOS.M ;
( /Somme dans le champs 'V1')
( a, b, adrObjet ...)
: ADDV1.M 8 + ADDPOS.M ;
( /Somme dans le champs 'V2')
( a, b, adrObjet ...)
: ADDV2.M 12 + ADDPOS.M ;
( /Somme dans le champs 'V3')
( a, b, adrObjet ...)
: ADDV3.M 16 + ADDPOS.M ;
( /Divise un vecteur par 2)
( a, b ...a/2, b/2)
: SCALE >R 2 / R> 2 / ;
( /Remet X et Y dans les limites écran)
( X, Y ... 0<X<XMAX, 0<Y<YMAX)
: LIMITPOS >R DUP 0< IF XMAX + ELSE DUP XMAX 2- > IF XMAX 2- - ENDIF ENDIF R> DUP 0< IF YMAX + ELSE DUP YMAX 2- > IF YMAX 2- - ENDIF ENDIF ;
( /Divise vecteur par scalaire)
( a, b, n ... a/n, b/n)
: DIVV DUP >R / SWAP R> / SWAP ;
( /Velocity=Velocity+ V1 + V2 + V3)
( adrObjet....adrObjet)
: UPDATE.VLCTY >R I GETV1.M I GETV2.M ADDV I GETV3.M ADDV I ADDVELCTY.M R> ;
( /Vecteur Position = Vecteur Position + Vecteur Velocity. Au passage fait la sommatoire des Velocity dans SIGMA.V3)
( adrObjet....adrObjet)
: UPDATE.POS >R I GETVELCTY.M DDUP SIGMA.V3 2+! I ADDPOS.M R> ;
( / Verifie que les coordonnées du BOID soient compatibles avec l'écran et fait la sommatoire des Positions dans SIGMA.V1)
( adrObjet....adrObjet)
: CHECK.POS >R I GETPOS.M LIMITPOS DDUP SIGMA.V1 2+! I SETPOS.M R> ;
( adrObjet....adrObjet)
: MOVE.M UPDATE.VLCTY UPDATE.POS CHECK.POS ;
( /Déplacement des Leaders)
(keyf...keyf)
: RIGHT DUP 32 = IF LEADER 2@ >R 20 + DUP XMAX < IF R> ELSE XMAX R> ENDIF LEADER 2! ENDIF ;
( keyf...keyf)
: LEFT DUP 16 = IF LEADER 2@ >R 20 - DUP -1 > IF R> LEADER 2! ELSE R> DROP DROP ENDIF ENDIF ;
( keyf...keyf)
: DOWN DUP 24 = IF LEADER 2@ 20 + DUP YMAX < IF LEADER 2! ELSE DROP DROP ENDIF ENDIF ;
( keyf...keyf)
: UP DUP 8 = IF LEADER 2@ 20 - DUP -1 > IF LEADER 2! ELSE DROP DROP ENDIF ENDIF ;
( /Lecture et affichage Boids )
: AFFI.BOID 18 1 DO I BOID(N) PLOT.PIC.M LOOP ;
( /Efface, effectue les calculs et affiche tous les Boids)
: DRAW.BOIDS 18 1 DO I BOID(N) DUP UNPLOT.PIC.M MOVE.M PLOT.PIC.M LOOP ;
( keyf...keyf)
: PARAM.LEADER CR LEADER 2@ SWAP ." VALEUR DU LEADER ...." CR ." X =" . CR ." Y =" . CR ." NLLE VALEUR X " #IN CR ." NLLE VALEUR Y " #IN LEADER 2! ;
( keyf...keyf)
: PARAM.SEPAR CR SEPARATION 2@ ." PARAMETRE SEPARATION ...." CR ." Y =" . CR ." X =" . CR ." NLLE VALEUR X SEPARATION " #IN CR ." NLLE VALEUR Y SEPARATION " #IN SEPARATION 2! ;
( keyf...keyf)
: PARAM.COHESION CR COHESION @ ." PARAMETRE COHESION ...." CR . CR ." NLLE VALEUR COHESION " #IN COHESION ! ;
( keyf...keyf)
: PARAM.ALIGN CR ALIGNEMENT @ ." PARAMETRE ALIGNEMENT ...." CR . CR ." NLLE VALEUR ALIGNEMENT " #IN ALIGNEMENT ! ;
( keyf...keyf)
: ?END CR ." Z POUR QUITTER" KEY 90 = IF EI QUIT ENDIF ;
( keyf...keyf)
: PARAM CLS PARAM.LEADER PARAM.SEPAR PARAM.COHESION PARAM.ALIGN ?END CLS AFFI.BOID ;
( /Saisie des touches flèches ou Q et appel des procedures)
( ...)
: ?INPUT KEYF DUP 58 < IF UP DOWN LEFT RIGHT 14 = IF PARAM ENDIF ELSE DROP ENDIF ;
( /Mise à zéro des champs V1 V2 et V3)
( adrObjet....adrObjet)
: CLEAR.VFIELD >R 0 0 DDUP DDUP I SETV2.M I SETV3.M I SETV1.M R> ;
( /Mise à zéro des Sigma)
( adrObjet....adrObjet)
: CLEAR.SIGMA 0 DUP DUP DUP SIGMA.V1 2! SIGMA.V3 2! ;
( /Applique loi séparation)
( Adresse objet ...Adresse objet )
: RULE.SEPARATION 18 1 DO I BOID(N) DUP >R MAIN.OBJ @ - IF MAIN.OBJ @ GETPOS.M I GETPOS.M SUBV DDUP ABSV SEPARATION 2@ V<V IF SCALE MAIN.OBJ @ ADDV2.M ELSE DROP DROP ENDIF ENDIF R> DROP LOOP ;
( /Applique loi cohésion)
( Adresse objet ...Adresse objet )
: RULE.COHESION >R SIGMA.V1 2@ I GETPOS.M SUBV V/16 LEADER 2@ ADDV 2 DIVV I GETPOS.M SUBV COHESION @ DIVV I SETV1.M R> ;
( /Applique loi alignement)
( Adresse objet ... )
: RULE.ALIGNEMENT >R SIGMA.V3 2@ I GETVELCTY.M SUBV V/16 I GETVELCTY.M SUBV ALIGNEMENT @ DIVV R> SETV3.M ;
( /Applique les 3 lois)
: RULES123 18 1 DO I BOID(N) DUP MAIN.OBJ ! CLEAR.VFIELD RULE.SEPARATION RULE.COHESION RULE.ALIGNEMENT LOOP CLEAR.SIGMA ;
( /Remise à zero des Boids)
: INIT 40 COHESION ! 2 ALIGNEMENT ! 20 20 SEPARATION 2! 290 130 LEADER 2! CLEAR.SIGMA 18 1 DO I BOID(N) DUP >R XMAX RANDOM YMAX RANDOM I SETPOS.M 0 0 DDUP DDUP DDUP I SETVELCTY.M I SETV1.M I SETV2.M R> SETV3.M DROP LOOP ;
( /Lance le programme)
: BOIDS DI CLS AFFI.BOID CLEAR.SIGMA BEGIN RULES123 DRAW.BOIDS ?INPUT AGAIN ;
QUIT QUIT
( FIN LISTING)
( // Lancement du programme : BOIDS )
Ce programme est presque 100 % Forth (presque à cause des DI et EI que je n'ai pu mettre en Forth)
Je ne le met que pour ceux qui voudraient l'adapter sur un micro ayant un Fig-Forth.
Il faudra bien entendu adapter la partie affichage, mais c'est tout à fait faisable.
II ASM
Je vais maintenant me concentrer sur la partie ASM.
Depuis longtemps je rêve de pouvoir faire cette transition du Forth -> ASM.
_sam_ l'a dit une fois :
__sam__ a écrit :C'est vraiment pratique qu'on puisse écraser le registre X. Franchement le forth sur thomson m'aurait super plu à l'époque car il permet de faire un mix très bien fichu entre le langage de haut niveau et l'assembleur.
et je suis tout à fait d'accord.
Forth possède tout pour passer progressivement du langage Haut niveau vers ASM si l'on utilise quelques trucs :
que je donne dans un autre message + tard dans la soirée.