(Forth) BOIDS et la gestion des objets

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Répondre
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

(Forth) BOIDS et la gestion des objets

Message par Dominique »

Bonjour à tous
Je pense que certains d'entre vous ont déjà entendu parler des BOIDS, cet extraordinaire concept développé par Craig Reynolds en 1986 et qui reproduit de façon saisissante le comportement d'individus à l'intérieur d'une meute, d'un banc de poissons ou d'un vol d'étourneaux.
Sa page est assez explicite et google vous permettra de trouver une littérature abondante.

http://www.red3d.com/cwr/boids/

Je m'en tiendrais à la page qui donne un "Pseudo Code" qui me semble parfaitement exploitable par nos petites machines.

http://www.kfish.org/boids/pseudocode.html

Comme ce pseudocode fait appel à la notion d'objets j'ai pensé qu'il serait instructif de nous attaquer aux BOIDS en Forth avec notre vieux MO5.

Honnêtement je ne sais pas si j'arriverai au bout, ni en combien de temps; je ne sais même pas si la lenteur de la machine permettra une simulation exploitable, mais ça nous aura permis de passer un bon moment.

Je propose deux étapes :
- Une première qui sera de montrer ce que l'on peut faire dans la gestion d'objets simples,
depuis la création d'une famille d'objets, leurs paramètres et l'ensemble d'actions (genre méthodes) que nous pouvons effectuer.
- La deuxième étape sera la création du programme.

Comme je ne peux pas y passer tout le temps que je désirerai, ça risque d'être assez lent.

Je reviens aujourd'hui sur ce fil avec cette première étape

A+
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Mokona »

Bonjour,

je suis très intéressé par la démarche. Forth, j'en connais un peu le fonctionnement, mais pas la démarche de conception d'un programme avec ce langage.

Je suivrai donc ça avec intérêt (et probablement avec des questions).
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

***************
Pour notre étude je vais me servir :
- De l'émulateur DCMOTO de Daniel. Version 2015.06.04. Paramètre MO5 V1.1 , 64K , Processeur 100%
- De la cassette "Forth MO5" de J.C. Bandini, T. Schiex avec la Doc (onglet Programmes Software de la page de Daniel)
- Du Notepad++

Charger la K7 forth-mo5_mo5.k7 dans la cassette du support amovible DCMOTO. Depuis le Basic : RUN""

Charger l'éditeur depuis le Forth par :
1 3 CLOAD EDITOR
puis
1 LOAD
(Voir P28)

****************

A)

Les objets Forth se caractérisent par
- Leurs paramètres
- L'action ou les actions à effectuer sur les objets. Généralement ces actions s'effectuent
sur les paramètres de l'objet.

Le but du jeu ici est de construire une famille d'objets (les BOIDS) qui auront tous la
même structure (paramètres: X, Y, Vecteurs V V1 V2 V3 , COLOR) qui pourront effectuer les mêmes actions
- GETX GETY GETV etc.. pour lire les paramètres - PUTX PUTY etc... pour les changer - PLOT pour afficher l'objets -
etc...

Le Forth possède pour cela un couple de mots absolument fascinant et dont Charles Moore, l'auteur du Forth, était assez fier :
<BUILDS ... DOES> (Lire page 24 du manuel)
Grace à ces deux mots nous allons créer des constructeurs d'objets.
Dans la définition de ce constructeur <BUILDS se chargera de mettre le nom de l'objet créé dans le dictionnaire du Forth,
ensuite nous donnerons les instructions pour mettre dans la mémoire RAM les paramètres de l'objet créé. DOES> quant à lui
mettra dans la pile du Forth l'adresse du premier paramètre de l'objet et indiquera une successions d'actions à effectuer avec ces paramètres.

B)
Le plus souvent nous allons voir dans la littérature des exemples où DOES> n'effectue qu'une seule action comme ici :

Code : Tout sélectionner

: TASK ;
: BOIDS.OBJ <BUILDS C, C, DOES> DUP 1+ C@ SWAP C@ ;

1 2 BOIDS.OBJ BOID1
3 2 BOIDS.OBJ BOID2
4 4 BOIDS.OBJ BOID3
Voyons ce qui se passe : Dans le constructeur <BUILDS cherchera le mot qui vient après (il trouvera
BOID1 ou BOID2 etc.) Il mettra ce mot dans le dictionnaire puis effectuera les actions C, C, qui consistent
à mettre dans la RAM à la suite du mot les valeurs 1 et 2 contenues dans la pile; Ensuite sera créé un lien
avec la suite d'instruction DUP C@ etc.. qui vient après DOES>, sachant que l'adresse où se trouve 1 et 2 se trouvera dans la pile.
Cette suite d'instructions permettra de lire le premier et le second paramètre.


BOID1 . . <cr>

nous donnera dans la pile les valeurs 1 et 2
BOID2 . . <cr>

nous donnera dans la pile les valeurs 3 et 2

etc..
Listing1.jpeg
Listing1.jpeg (7.41 Kio) Consulté 8025 fois
C)

Si nous désirons avoir le choix sur les actions nous pouvons adopter après DOES> une démarche du type CASE comme on l'avait fait dans
http://forum.system-cfg.com/viewtopic.p ... =75#p70212

mais il y a mieux. Trouvé dans BYTE août 1980 p 184 le mot CASE: qui permet de choisir soit la première ou la deuxième ou autre fonction à exécuter.

https://archive.org/details/byte-magazine-1980-08

Dans le listing à suivre les paramètres X Y et Color de BOIDS.OBJ se mettent dans l'ordre suivant
(Color, Y, X .....)

J'ai modifié CASE: par rapport à la définition de BYTE de façon à ce que 1 METHODE nous donne la 1° méthode et non 0 METHODE pour la première méthode
Eliminer le listing précédent par FORGET TASK
puis
********************

Code : Tout sélectionner

: TASK ;
DECIMAL
: CASE: <BUILDS SMUDGE ] DOES> SWAP 1- 2 * + @ EXECUTE ;
: GETX.M C@ ;
: GETY.M 1+ C@ ;
: GETCOLOR.M 2+ C@ ;
: PLOT.M DUP GETCOLOR.M INKG DUP GETX.M SWAP GETY.M PSET ;

CASE: METHODE GETX.M GETY.M GETCOLOR.M PLOT.M ;

1 CONSTANT GETX
2 CONSTANT GETY
3 CONSTANT GETCOLOR
4 CONSTANT PLOT.OBJ


: BOIDS.OBJ <BUILDS C, C, C, DOES> SWAP METHODE ;

1 100 100  BOIDS.OBJ BOID1
2 100 150  BOIDS.OBJ BOID2
3 100 200  BOIDS.OBJ BOID3
******************

Je veux le Y de l'objet BOID2 la couleur de l'objet 1 ou afficher l'objet 3

GETY BOID2 .
GETCOLOR BOID1 .
PLOT.OBJ BOID3
PlotBoids.jpeg
PlotBoids.jpeg (3.31 Kio) Consulté 8025 fois
Le programme ci-dessus est dans la K7 List1Boids.
Pour la charger dans l'éditeur faire
1 1 CLOAD BOIDSA1

Pour compiler faire
1 LOAD
List1Boids.zip
(415 octets) Téléchargé 191 fois
D)

Dans le pseudocode que nous étudierons dans le deuxième partie
http://www.kfish.org/boids/pseudocode.html

Des procédures font appel à des objets indexés
FOR EACH BOID b
...
b.velocity
....


qui nous obligeront à indexer nos BOIDS.
Une solution simple sera :

Code : Tout sélectionner

CASE: BOID(N) BOID1 BOID2 BOID3 ;
3 BOID(N) correspondra à BOID3


Notre listing final deviendra donc

Code : Tout sélectionner

: TASK ;
DECIMAL
: CASE: <BUILDS SMUDGE ] DOES> SWAP 1- 2 * + @ EXECUTE ;
: GETX.M C@ ;
: GETY.M 1+ C@ ;
: GETCOLOR.M 2+ C@ ;
: PLOT.M DUP GETCOLOR.M INKG DUP GETX.M SWAP GETY.M PSET ;

CASE: METHODE GETX.M GETY.M GETCOLOR.M PLOT.M ;

1 CONSTANT GETX
2 CONSTANT GETY
3 CONSTANT GETCOLOR
4 CONSTANT PLOT.OBJ


: BOIDS.OBJ <BUILDS C, C, C, DOES> SWAP METHODE ;

1 100 100  BOIDS.OBJ BOID1
2 100 150  BOIDS.OBJ BOID2
3 100 200  BOIDS.OBJ BOID3

CASE: BOID(N) BOID1 BOID2 BOID3 ;
donc

Code : Tout sélectionner

GETY 2 BOID(N) .
GETCOLOR 1 BOID(N) .
PLOT.OBJ 3 BOID(N)
on voit que 2 BOID(N) correspond à BOID2
1 BOID(N) à BOID1
etc.

J'espère ne pas avoir été trop confus. N'hésitez pas à me faire part de vos observations avant d'attaquer le programme
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Mokona »

Hello,

je me suis accroché (avec de la doc à côté) et j'ai tout compris (presque, voire ci-dessous). N'étant pas un habitué de Forth, ça ne m'est pas lisible du premier coup d'oeil, mais avec la référence à côté, ça va.

Sauf... l'implémentation de CASE, dont je comprends le principe via la partie exécution (après DOES>), mais pas la partie compilation. Je ne comprends pas le sens de "SMUDGE ]" dans ce contexte.
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Smudge est une trouvaille du Fig-Forth et n'est peut être pas des plus heureuses.
L'idée de départ était de n'inclure un nouveau mot dans le dictionnaire que si sa définition était complète.
On retrouve SMUDGE dans ; <point virgule>

Ainsi je crée un mot
: TASK DUPE ;
Avec les : <deux points> le Forth va comprendre que TASK est un nouveau mot. Il va le mettre dans le dictionnaire sous cette forme

Code : Tout sélectionner

A4		; Longueur du mot (avec bit SMUDGE non validé)
54 41 53 4B    ; ASCII TASK
Dès qu'il rencontre DUPE (Erreur typo avec DUP) il informe que ce mot n'appartient pas au Dico et ABORT
la compilation sans passer par ; <point virgule> donc sans SMUDGE(r)

Le mot TASK n'appartient toujours pas au dictionnaire.

dans CASE: METHODE GETX.M GETY.M GETCOLOR.M PLOT.M ;
CASE: est un mot qui marche un peu comme : <deux points>
- Il crée l'entête METHODE grace à <BUILDS et met le compilateur en mode COMPILATION grâce à ]

Mais comme CASE: n'est pas vraiment : <deux points> ; <point virgule> ne va pas SMUDGE(r) METHODE.
C'est pour cette raison que CASE: SMUDGE d'office METHODE.

SMUDGE(r) revient à faire un XOR 20h de la longueur du mot.
A4 - > 84
Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Mokona »

Ok merci.
Avatar de l’utilisateur
yo_fr
Messages : 1336
Inscription : 13 août 2009 18:24
Localisation : 78...
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par yo_fr »

L’intérêt du SMUDGE est surtout de pouvoir appeler en récurrence un mot par lui même, il me semble !
(en plus d'oublier un mot dont on a foiré la définition !)
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Bien vu yo_fr. Je crois qu'il y a un sujet sur Recurse en Forth dans le forum.
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Rappelons rapidement ce que notre programme est censé représenter.
Chaque BOIDS représente un oiseau à l'intérieur d'un essaim.
A chaque cycle chacun des oiseaux modifie sa vitesse en direction et grandeur (donc son comportement) en fonction de trois facteurs :

1 - Le facteur cohésion : sa vitesse de cohésion - Vcohesion - l'incitera à voler vers le centre de gravité de l’essaim
2 - Le facteur séparation : sa vitesse de séparation - Vseparation - l'incitera à se maintenir à une distance minimum des BOIDS qui l'entourent
3 - Le facteur alignement : sa vitesse d'alignement - Valignement - l'incitera à aligner sa vitesse en grandeur et direction sur celle des BOIDS qui l'entourent.

Nous définirons la position initiale de chaque BOIDS de façon aléatoire en X et Y (Xpos Ypos)
Nous définirons les vecteurs vitesse par leurs composantes en X et en Y.
Nous assumons qu'ils sont tous posés au sol; ils ont donc une vitesse réelle Vreelle = 0 (Xvrelle yvreelle )

Nous allons nous occuper de la première loi : Cohésion.

Pour cela il nous faut calculer le centre de gravité perçu par chacun des BOIDS.
On va définir ce centre de gravité par la somme des Xpos Ypos de chacun d'eux sauf de celui dont on s'occupe / par le nombre de (BOIDS -1)
Pour chaque BOIDS La vitesse actualisée à chaque cycle sera proportionnelle à la distance qui le sépare de ce centre de gravité.
Si on les laisse partir avec cette seule loi de cohésion, il est certain qu'ils vont se concentrer en un seul point.
Mais c'est juste pour tester.

Le résultat est lent mais comme mon seul souci était de faire un programme 'académique'
pour montrer comment gérer une syntaxe objet, on gagnera de précieuses secondes en optimisant les routines
et en faisant appel au Langage Machine
Boids1.gif
Boids1.gif (12.8 Kio) Consulté 7953 fois
La K7 RULE1 vient avec le programme ci-dessous.
Depuis le Forth faire 1 4 CLOAD RULE1 pour charger dans l'éditeur
puis 1 LOAD pour compiler le programme
et RULE1 pour lancer le programme.
Obs : La touche "Q" arrête le programme.
Rule1.zip
(1.16 Kio) Téléchargé 188 fois

Code : Tout sélectionner


: TASK ;
HEX
: NIP SWAP DROP ;
65E8 CONSTANT RMULT

: 2VARIABLE <BUILDS SWAP , , DOES> ;
: 2@ DUP @ SWAP 2+ @ ;
: 2! DUP >R 2+ ! R> ! ; 
3 1 2VARIABLE RLOC
: RNDM RLOC 2@ RMULT U* ROT 0 D+ OVER RLOC 2! ;

(N . . .  0<Aléatoire<N)
: RANDOM RNDM U* NIP ;

( /Disable Interrupt)
CREATE DI 1A50 , 0EB6 , SMUDGE

( /Enable Interrupt)
CREATE EI 1CAF , 0EB6 , SMUDGE

7F CONSTANT C7F
BF CONSTANT CBF
DF CONSTANT CDF
EF CONSTANT CEF
F7 CONSTANT CF7
FB CONSTANT CFB
FD CONSTANT CFD
FE CONSTANT CFE
80 CONSTANT C80
40 CONSTANT C40
20 CONSTANT C20
10 CONSTANT C10
20 CONSTANT C20
8 CONSTANT C08
4 CONSTANT C04

: FORME A7C0 DUP C@ 1 OR SWAP C! ;

( a....a/8,reste)
CREATE /8 ECC1 , 4756 , 4756 , 4756 , 0EB4 , SMUDGE  

: CASE: <BUILDS SMUDGE ] DOES> SWAP 1- 2 * + @ EXECUTE ;

( reste /8 .... masque)
CASE: MASK-PLOT C80 C40 C20 C10 C08 C04 2 1 ;

( reste /8 .... masque)
CASE: MASK-UNPLOT C7F CBF CDF CEF CF7 CFB CFD CFE ;

( X,Y....adresse, reste/8) 
: TROUVE-CELL 28 * OVER /8 + SWAP 7 AND  ; 

( adresse, reste/8....)
: (PLOT) 1+ MASK-PLOT OVER FORME C@ OR SWAP FORME C! ; 
: (UNPLOT) 1+ MASK-UNPLOT OVER FORME C@ AND SWAP FORME C! ;

( X,Y...)
: UNPLOT.M TROUVE-CELL  (UNPLOT) ; 

( X,Y...)
: PLOT.M TROUVE-CELL  (PLOT) ;

DECIMAL
- Somme vectorielle :
(Y1 X1 Y2 X2 .... Y1+Y2 X1+X2)
: ADDV SWAP >R + SWAP R> + SWAP ;

- Différence vectorielle :
(Y1 X1 Y2 X2 .... Y1-Y2 X1-X2)
: SUBV SWAP >R - SWAP R> - SWAP ;

- Division par un scalaire N :
(Y1 X1 N .... Y1/N X1/N)
: DIVV DUP >R / SWAP R> / SWAP ;

(adresseObjet... Xpos Ypos)
: GETPOS.M DUP  @ SWAP 2+ @ ;

(Xpos Ypos adresseObjet ....)
: SETPOS.M DUP >R 2+ ! R> ! ;

(adresseObjet... adresseObjet+4 ....Xvelcty Yvelcty)
: GETVELCTY.M 4 + GETPOS.M ;

(Xvelcty Yvelcty adresseObjet ....Xvelcty Yvelcty adresseObjet+4)
: SETVELCTY.M 4 + SETPOS.M ;

(adresseObjet....)
: PLOT.C GETPOS.M PLOT.M ;

(adresseObjet....)
: UNPLOT.C GETPOS.M UNPLOT.M ;

(adresseObjet...)
: MOVE.M DUP >R GETPOS.M I GETVELCTY.M ADDV R> SETPOS.M ;

1 CONSTANT GETPOS
2 CONSTANT SETPOS
3 CONSTANT GETVELCTY
4 CONSTANT SETVELCTY
5 CONSTANT PLOT
6 CONSTANT UNPLOT
7 CONSTANT MOVE

CASE: METHODE GETPOS.M SETPOS.M GETVELCTY.M SETVELCTY.M PLOT.C UNPLOT.C MOVE.M ;

: BOIDS.OBJ <BUILDS , , , , DOES> SWAP METHODE ;

(  Yvelcty Xvelcty Ypos Xpos ....)
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD1
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD2
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD3
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD4
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD5
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD6
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD7
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD8
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD9
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD10
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD11
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD12
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD13
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD14
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD15
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD16
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD17
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD18
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD19
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD20
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD21
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD22
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD23
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD24
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD25
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD26
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD27
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD28
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD29
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD30
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD31
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD32
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD33
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD34
0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD35

CASE: BOID(N) BD1 BD2 BD3 BD4 BD5 BD6 BD7 BD8 BD9 BD10 BD11 BD12 BD13 BD14 BD15 BD16 BD17 BD18 BD19 BD20 BD21 BD22 BD23 BD24 
BD25 BD26 BD27 BD28 BD29 BD30 BD31 BD32 BD33 BD34 BD35 ;



: COHESION 
            34 1 DO 					
                    0 0                                    // Centre Gravité 0 0 
                    34 1 DO                                // Début boucle de 1 à 33 BOIDS
                                I J - IF                   // Le propre BOID ne rentre pas dans le calcul 
                                GETPOS I BOID(N)           // Prend vecteur Position 
                                ADDV                       // Additionne au cumul
                                      ENDIF                //
                         LOOP
                                32 DIVV                    // divise par 32 BOIDS pour moyenne
                                GETPOS I BOID(N)           // Position du BOIDS
				SUBV                                           // Calcule distance du BOIDS au Centre Gravité 
                                10 DIVV                    // Vitesse = 10 % de la distance
                                SETVELCTY I BOID(N)        // Mise en mémoire
         LOOP ;

: DRAW.BOIDS 34 1 DO                                       // 33 BOIDS
                UNPLOT I BOID(N)                           // Efface le BOIDS
                MOVE I BOID(N)                             // Calcule Nlle POS
                PLOT I BOID(N)                             // Affiche
                LOOP ;

: RULE1 
                CLS                                        // Efface Ecran
                   34 1 DO                                 // 33 BOIDS
                           PLOT I BOID(N)                  // Affiche les BOIDS
                        LOOP 
                   BEGIN
                           COHESION                        // Applique Loi Cohésion
                           DRAW.BOIDS                      // Mouvement
                           KEYF 14 =                       // Jusqu'à la touche "Q"
                   UNTIL ;

Avatar de l’utilisateur
Mokona
Messages : 1040
Inscription : 17 déc. 2016 22:01
Localisation : Nord Est des Yvelines
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Mokona »

Hello,

plusieurs questions.

1 - Quelle est l'intérêt de la définition des constantes C7F et suivantes ? Est-ce que c'est juste un jeu d'écriture pour une formatage plus cohérent ?

2 - Sur la création de Boids et leur sélection via un Case. Est-ce qu'il n'y aurait pas moyen, en Forth, de faire une structure de liste chaînée ou de tableau ? Cela simplifierait pas mal l'écriture j'imagine.

3 - Dans DRAW.BOID, il y a 3 accès à BOID(N) pour en prendre le Iième élément. Comme ces trois accès ramènent le même résultat, est-ce qu'il ne vaudrait pas mieux conserver ce résultat ?
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Salut !

Je tiens à te remercier pour tes questions, et te dire je suis ravi de voir ton intérêt pour ce projet.

1 - Oui c'est le format du mot CASE: et également le mot EXECUTE qui m'obligent à traiter 7F et les autres
comme des mots exécutables C7F et non pas comme des valeurs.
2 et 1 sont écrits tels quels parce que ce sont déjà des constantes dans le Forth (0 aussi)

2 - Tu as tout à fait raison, lors de l'optimisation nous détruirons les tableaux CASES: et particulièrement celui-ci.
In fine nous n'avons pas besoin d'appeler l'objet N BOID(N), nous n'avons besoin que de l'adresse de ses paramètres.
C'est pour ça que je ne m'inquiète pas trop de la lenteur actuelle, et que je maintiens la logique de la syntaxe que j'ai définie.

3 - Idem : Mille fois raison. Il suffit de mettre l'adresse des paramètres de l'objet de la première boucle dans une variable.
ça rentrera dans l'optimisation - ou peut être avant :)
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Le Forth a la réputation d'être un langage déroutant et peu lisible.
C'est vrai.
Pour clarifier ce qui a été fait et mieux expliquer ce que je vais faire, voici un récapitulatif :

Objets :
- On a défini 33 objets BOID(1-> 33) ainsi structurés

Un champs de données position de 32 bits (16 bits Xposition + 16 bits Yposition)
Un champs de données Velocity de 32 bits (16 bits Xvelcty + 16 bits Yvelcty)

Syntaxe :
- on a défini la syntaxe suivante sur les Objets

<commande> <Index> BOID(N)

L'index de 1 à 33 permet de selectionner l'objet BOID(<Index>) sur laquelle la commande va s'appliquer
Les <commande> s disponibles sont actuellement les suivantes :

GETPOS Lit le champs de données position en mettant (Xposition Yposition ..) dans la pile du Forth
GETVELCTY Lit le champs de données Velocity en mettant (Xvelcty Yvelcty ..) dans la pile du Forth
SETPOS Met les deux valeurs (Xposition Yposition ..) de la pile du Forth dans le champs de données position
SETVELCTY Met les deux valeurs (Xvelcty Yvelcty ..) de la pile du Forth dans le champs de données Velocity
PLOT Affiche l'objet
UNPLOT Efface l'objet
MOVE Met à jour les coordonnées (données position) en fonction de la vitesse (données Velocity)

- On a défini des commandes utilitaires qui ne s'appliquent pas sur les objets

ADDV Fait la somme de deux vecteurs dans la pile du Forth
SUBV Fait la différence de deux vecteurs dans la pile du Forth
DIVV Divise les composantes X Y d'un Vecteur par un scalaire


Le but maintenant est d'ajouter des champs aux objets (vitesse V1 V2 V3), et d'enrichir le vocabulaire de <commandes> sur les objets et d'utilitaires pour attaquer la 2° partie
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Voici donc la phase II du programme qui prend en compte les 3 lois (cohésion, séparation et alignement)

Il s'agissait pour moi de maintenir la syntaxe <commande> <Index> BOID(N) même si elle ralentit énormément le programme
dans son état actuel. Elle me convient avant de procéder à l'optimisation.

Quelques observations :
V1 = Vecteur Vitesse cohésion
V2 = Vecteur Vitesse séparation
V3 = Vecteur Vitesse alignement

Chaque vecteur POS VELCTY V1 V2 et V3 possède sa commande GET , SET SUB et ADD

J'ai créé un oiseau fictif ( LIDER - Variable double) dont je peux modifier les coordonnées et qui modifie le centre de
gravité de l'ensemble suivant la formule ( Centre-Gravité de l'ensemble + Coordonnées LIDER )/2
ce qui dirige lentement le groupe vers le LIDER.

La touche Q (assez rebelle car il faut attendre la fin des calculs ) permet de modifier les coordonnées du LIDER.

Le mot Z (CREATE Z 0EB6 , SMUDGE ) me permet de positionner un point d’arrêt sur l'émulateur. Il suffit de mettre
le mot Z dans n'importe quelle définition.

Le mot INIT permet de remettre les BOIDS à ZERO.

La phase III commence avec l'optimisation qui va largement modifier le programme et surtout (j'espère) le rendre fluide.

Code : Tout sélectionner

: TASK ; 
HEX 
CREATE Z 0EB6 , SMUDGE 
: NIP SWAP DROP ; 
65E8 CONSTANT RMULT 
: 2VARIABLE <BUILDS SWAP , , DOES> ; 
: 2@ DUP @ SWAP 2+ @ ; 
: 2! DUP >R 2+ ! R> ! ; 
3 1 2VARIABLE RLOC 
: RNDM RLOC 2@ RMULT U* ROT 0 D+ OVER RLOC 2! ; 
: RANDOM RNDM U* NIP ; 
CREATE DI 1A50 , 0EB6 , SMUDGE 
CREATE EI 1CAF , 0EB6 , SMUDGE 
7F CONSTANT C7F 
BF CONSTANT CBF 
DF CONSTANT CDF 
EF CONSTANT CEF 
F7 CONSTANT CF7 
FB CONSTANT CFB 
FD CONSTANT CFD 
FE CONSTANT CFE 
80 CONSTANT C80 
40 CONSTANT C40 
20 CONSTANT C20 
10 CONSTANT C10 
8 CONSTANT C08 
4 CONSTANT C04 
0 VARIABLE CURRENT.OBJ 
0 VARIABLE COMPTV1 
0 VARIABLE COMPTV2 
0 VARIABLE COMPTV3 
: FORME A7C0 DUP C@ 1 OR SWAP C! ; 
CREATE /8 ECC1 , 4756 , 4756 , 4756 , 0EB4 , SMUDGE 
: CASE: <BUILDS SMUDGE ] DOES> SWAP 1- 2 * + @ EXECUTE ; 
CASE: MASK-PLOT C80 C40 C20 C10 C08 C04 2 1 ; 
CASE: MASK-UNPLOT C7F CBF CDF CEF CF7 CFB CFD CFE ; 
: TROUVE-CELL 28 * OVER /8 + SWAP 7 AND  ; 
: (PLOT) 1+ MASK-PLOT OVER FORME C@ OR SWAP FORME C! ; 
: (UNPLOT) 1+ MASK-UNPLOT OVER FORME C@ AND SWAP FORME C! ; 
: UNPLOT.M TROUVE-CELL  (UNPLOT) ; 
: PLOT.M TROUVE-CELL  (PLOT) ; 
DECIMAL 
: ADDV SWAP >R + SWAP R> + SWAP ; 
: SUBV SWAP >R - SWAP R> - SWAP ; 
: DIVV DUP >R / SWAP R> / SWAP ; 
: GETCUROBJ CURRENT.OBJ @ ; 
: DDUP OVER OVER ; 
: V<V SWAP >R < SWAP R> < AND ; 
: ABSV >R ABS R> ABS ; 
: GETPOS.M DUP  @ SWAP 2+ @ ; 
: SETPOS.M DUP >R 2+ ! R> ! ; 
: GETVELCTY.M 4 + GETPOS.M ; 
: SETVELCTY.M 4 + SETPOS.M ; 
: PLOT.C GETPOS.M PLOT.M ; 
: UNPLOT.C GETPOS.M UNPLOT.M ; 
: SETCUR.OBJ.M CURRENT.OBJ ! ; 
: ADDPOS.M DUP >R 2+ +! R> +! ; 
: ADDVELCTY.M 4 + ADDPOS.M ; 
: GETV1.M 8 + GETPOS.M ; 
: SETV1.M 8 + SETPOS.M ; 
: ADDV1.M 8 + ADDPOS.M ; 
: SETV2.M 12 + SETPOS.M ; 
: GETV2.M 12 + GETPOS.M ; 
: ADDV2.M 12 + ADDPOS.M ; 
: SETV3.M 16 + SETPOS.M ; 
: GETV3.M 16 + GETPOS.M ; 
: ADDV3.M 16 + ADDPOS.M ; 
: MOVE.M DUP >R GETV1.M I GETV2.M ADDV I GETV3.M ADDV I ADDVELCTY.M I GETVELCTY.M R> ADDPOS.M ; 
1 CONSTANT GETPOS 
2 CONSTANT SETPOS 
3 CONSTANT GETVELCTY 
4 CONSTANT SETVELCTY 
5 CONSTANT PLOT 
6 CONSTANT UNPLOT 
7 CONSTANT MOVE 
8 CONSTANT SETCUR.OBJ 
9 CONSTANT ADDPOS 
10 CONSTANT ADDVELCTY 
11 CONSTANT GETV1 
12 CONSTANT SETV1 
13 CONSTANT ADDV1 
14 CONSTANT SETV2 
15 CONSTANT GETV2 
16 CONSTANT ADDV2 
17 CONSTANT SETV3 
18 CONSTANT GETV3 
19 CONSTANT ADDV3 
CASE: METHODE GETPOS.M SETPOS.M GETVELCTY.M SETVELCTY.M PLOT.C UNPLOT.C MOVE.M SETCUR.OBJ.M ADDPOS.M ADDVELCTY.M GETV1.M SETV1.M ADDV1.M SETV2.M GETV2.M ADDV2.M SETV3.M GETV3.M ADDV3.M ; 
: BOIDS.OBJ <BUILDS , , , , , , , , , , DOES> SWAP METHODE ; 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD1 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD2 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD3 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD4 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD5 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD6 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD7 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD8 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD9 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD10 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD11 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD12 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD13 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD14 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD15 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD16 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD17 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD18 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD19 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD20 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD21 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD22 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD23 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD24 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD25 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD26 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD27 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD28 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD29 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD30 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD31 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD32 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD33 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD34 
0 0 0 0 0 0 0 0 200 RANDOM 320 RANDOM BOIDS.OBJ BD35 
CASE: BOID(N) BD1 BD2 BD3 BD4 BD5 BD6 BD7 BD8 BD9 BD10 BD11 BD12 BD13 BD14 BD15 BD16 BD17 BD18 BD19 BD20 BD21 BD22 BD23 BD24 BD25 BD26 BD27 BD28 BD29 BD30 BD31 BD32 BD33 BD34 BD35 ; 
: TASK2 ; 
: AFFI.BOID  34 1 DO PLOT I BOID(N)  LOOP ; 
0 0 2VARIABLE LEADER 
: RULES123 34 1 DO  0 COMPTV2 ! 0 0 DDUP  DDUP DDUP SETVELCTY I BOID(N)  SETV2 I BOID(N) SETV3 I BOID(N) SETV1 I BOID(N) 34 1 DO I J - IF  GETPOS I BOID(N) ADDV1 J BOID(N) GETPOS J BOID(N) GETPOS I BOID(N) SUBV DDUP ABSV 10 10 V<V IF ADDV2 J BOID(N) GETVELCTY I BOID(N) ADDV3 J BOID(N) 1 COMPTV2 +! ELSE DROP DROP ENDIF  ENDIF  LOOP GETV1 I BOID(N) 32 DIVV LEADER 2@ ADDV 2 DIVV GETPOS I BOID(N) SUBV 10 DIVV SETV1 I BOID(N) GETV3 I BOID(N) COMPTV2 @ DUP IF DIVV GETVELCTY I BOID(N) SUBV 8 DIVV SETV3 I BOID(N) ELSE DROP DROP DROP ENDIF  LOOP ; 
: DRAW.BOIDS 34 1 DO UNPLOT I BOID(N) MOVE I BOID(N) PLOT I BOID(N) LOOP ; 
: #IN 0 0 PAD DUP 3 EXPECT 1- (NUMBER) DROP DROP ; 
: PARAM CLS LEADER 2@ ." VALEUR DU LEADER .... Y =" . CR ." X =" . CR ." NLLE VALEUR X (DE 0 A 319)  " #IN CR ." NLLE VALEUR Y (DE 0 A 199)  " #IN LEADER 2! CR ." Z POUR QUITTER" KEY 90 = IF LEAVE ENDIF CLS DRAW.BOIDS ; 
: RULES   CLS   AFFI.BOID BEGIN RULES123    DRAW.BOIDS   KEYF 14 = IF PARAM  ENDIF AGAIN ; 
: INIT 34 1 DO 320 RANDOM 200 RANDOM SETPOS I BOID(N) 0 0 SETVELCTY I BOID(N) 0 0 SETV1 I BOID(N) 0 0 SETV2 I BOID(N) 0 0 SETV3 I BOID(N) LOOP ; 
QUIT QUIT
Pour Charger le programme depuis le Forth :
1 6 CLOAD BOIDSV1

Compiler par 1 LOAD

Lancer par RULES

Modifier le LIDER par touche Q
après les valeurs du LIDER, la touche Z sort du programme, toute autre
continue l'évolution des BOIDS avec le nouveau LIDER.
BoidsV1.zip
(1.75 Kio) Téléchargé 187 fois
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: (Forth) BOIDS et la gestion des objets

Message par __sam__ »

Quand ce sera optimisé et fluide, il sera intéréssant de pouvoir modifier dynamiquement la position du LIDER avec le joystick plutot que d'entrer les coordonnées numériquement.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Avatar de l’utilisateur
Dominique
Messages : 828
Inscription : 09 mars 2010 13:37
Localisation : Limoges
Contact :

Re: (Forth) BOIDS et la gestion des objets

Message par Dominique »

Exact ! Si la vitesse le permet je veux aussi tester les paramètres par l'appui successif des touches. La distance minimum entre les Boids ainsi que la distance qui détermine le voisinage modifient terriblement leur comportement.
Répondre