Mon site personnel consacré à MSEide+MSEgui : msegui.net
Je viens de voir ça dans la doc de VP:
Apparemment, il fonctionne (pour les "objects") comme TP. Pour les class, le comportement est similaire à Delphi/FreePascal. Ce qui est du coup assez logique et moins confusingThe declaration of an object or class type creates a unique type of which instances can be allocated. All instances of an object or class type share a single copy of every method (i.e. executable code), but have their own copies of the fields (i.e. data).
Instances of object types can be either static or dynamic. A static object variable is declared in the same way as variables of any other type, whereas a dynamic object is allocated at run time. As for other dynamic variables, the dynamic allocation is performed by a call to the New standard procedure, which should be passed a variable of type pointer to the object as the parameter. If the object type has a constructor method, it should be passed to New as a second parameter. Dynamic objects are disposed of by calling the Dispose standard procedure. If a destructor method is defined for the object type, it should be specified as the second parameter to Dispose. Note, that although object types without constructor or destructor methods are allowed they rarely occur, since constructors are used to initialize the object and destructors are used to perform any cleanup actions required.
Example
type
POldStyleObject = ^TOldStyleObject;
TOldStyleObject = object
SomeField: Integer;
constructor Init;
destructor Done; virtual;
...
end;
M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal
D'accord, donc voici ce que ça donnerait. Apparemment ça fonctionne.
Je pense que je vais conserver cette formule, si c'est correct.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 program TPosition5; {$IFDEF VPASCAL} {&PMTYPE VIO} {&USE32+} {$H+} {$ELSE} {$APPTYPE CONSOLE} {$IFDEF FPC}{$MODE DELPHI}{$H+}{$ENDIF} {$ENDIF} uses Classes; type tPosition = object liste: tStringList; constructor Init; destructor Done; virtual; procedure Saisie; end; tPositionTemps = object actuelle, suivante: tPosition; constructor Init; destructor Done; virtual; end; constructor tPosition.Init; begin liste := tStringList.Create; end; destructor tPosition.Done; begin liste.Free; end; procedure tPosition.Saisie; var chaine: string; begin ReadLn(chaine); liste.Add(chaine); end; constructor tPositionTemps.Init; begin actuelle.Init; suivante.Init; end; destructor tPositionTemps.Done; begin actuelle.Done; suivante.Done; end; var positionTemps: tPositionTemps; begin positionTemps.Init; positionTemps.actuelle.Saisie; positionTemps.Done; end.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Oui ca a l'air OK. Pour moi la différence entre classe et object est le déréférencement automatique que certains compilateurs apportent (notamment Delphi).
Pour la gestion de la mémoire avec les objects, elle n'est pas masquée ! Il faut donc bien comprendre l'utilisation des pointeurs et l'allocation mémoire, mais une fois qu'on maitrise bien cela, il est parfois plus clair d'utiliser les objects
M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal
Voilà, j'ai fini mon unité !
Pour une position donnée, le programme génère la liste des coups légaux et évalue l'état du jeu. La position peut être initialisée à partir d'une chaîne au format FEN, et peut également être exportée au même format. La compilation a été testée avec Delphi 7, Free Pascal et Virtual Pascal.
Maintenant je vais reprendre mon interface graphique, en y apportant peut-être quelques petites améliorations. Je m'interroge sur la possibilité de remplacer ma police True Type par des bitmaps, entre autres pour éviter à l'utilisateur d'avoir à installer la police. Mais il y a surtout une chose que j'aimerais faire, c'est de pouvoir faire glisser les pièces avec la souris, si ce n'est pas trop compliqué à réaliser.
Dans un premier temps je vais déjà essayer de faire fonctionner mes nouvelles unités avec l'interface dans son état actuel. Je verrai ensuite si j'ai encore du courage.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour ! Voici le premier état de mon interface (pièce jointe). Seule l'unité Echecs est incluse, donc l'ordinateur ne joue pas.
Pour jouer, cliquez sur une pièce puis sur la case d'arrivée.
Attention ! Il faut avoir la police Chess Alpha installée sur votre machine.
J'ai trouvé un petit outil qui convertit une police True Type en bitmap. L'outil est donné avec un exemple de code (FreeBASIC) pour l'utilisation du bitmap.
J'ai fait un essai avec la police Chess Alpha. Si je peux, j'en ferai une version en Pascal.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour !
Après en avoir longtemps rêvé, j'ai mis au point une application qui communique avec un moteur de jeu d'échecs en utilisant le protocole UCI.
Le plus difficile n'était pas d'apprendre le protocole, mais de réaliser la communication entre les deux processus. J'y suis finalement parvenu grâce au composant TConsoleIO pour Delphi 7. Je n'ai eu qu'à modifier l'exemple fourni avec le composant.
Vous pouvez télécharger l'application sur cette page. Le moteur de jeu d'échecs Pharaon est inclus, avec l'aimable autorisation de l'auteur, Frank Zibi (qui est aussi l'auteur de HPChess).
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bravo !
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
Lai,
Belle progression.
C'est typiquement le genre de projet qui ne se termine jamais.
Si les cons volaient, il ferait nuit à midi.
Merci pour vos encouragements.
Oui, il y a encore du pain sur la planche, comme on dit.
Pour faire un moteur UCI, il faudrait que j'apprenne les threads (vu que le moteur doit pouvoir recevoir des commandes pendant qu'il est en train de travailler).
Côté interface, il faudrait que j'apprenne à faire glisser les pièces, soit en les attrapant avec la souris et en les déposant, soit qu'on clique sur la case de départ puis sur la case d'arrivée et que la pièce se déplace toute seule.
J'aimerais bien aussi pouvoir utiliser le composant TConsoleIO avec Delphi XE2, puisqu'au final c'est pour ce compilateur que je voudrais écrire un programme complet, quand j'aurai fini d'acquérir les connaissances nécessaires. Or, l'unité ConsoleIO se compile bien avec XE2, mais à l'exécution ça ne fonctionne pas.
J'ai aussi un petit projet pour FlashPascal (j'aimerais refaire ça, je pense que c'est dans mes cordes), et enfin je compte bien retoucher le programme que j'avais fait pour FreePascal et l'unité Wingraph.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour tout le monde ! En 2014, je voudrais avoir des pièces qui se meuvent au lieu de se téléporter.
J'ai essayé quelque chose, avec les pièces de Fritz. Mon idée était de stocker seulement les pièces, sans les rayures (qui ne bougent pas), mais avec leur contour. Avant de déplacer la pièce, je restaure les rayures, puis je redessine la pièce à son nouvel emplacement. Au début j'ai été content de voir que ça fonctionnait (quoique ce soit un peu lent), mais je réalise que cela ne peut marcher que dans un échiquier vide, car je n'ai rien prévu pour redessiner les pièces survolées.
Je vous montre quand même ce que j'ai fait (FreePascal et WinGraph). Si vous avez des idées sur la question, je vous écouterai volontiers.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 (* FreePascal 2.6.2 *) program Etude; {$APPTYPE GUI} uses WinCrt, WinGraph, WinMouse; (* http://math.ubbcluj.ro/~sberinde/wingraph/ *) {$R WINGRAPH.RES} type tGraphChessBoard = class xo, yo: integer; figure: array[0..39, 0..39]of char; constructor Create(aXo, aYo: integer); procedure LoadFigure(const aFilename: string); procedure DrawEmpty; procedure DrawFigure(const aXo, aYo: integer); procedure DrawBackground(const aXo, aYo: integer); end; constructor tGraphChessBoard.Create(aXo, aYo: integer); begin xo := aXo; yo := aYo; end; procedure tGraphChessBoard.LoadFigure(const aFilename:string); var t: text; x, y: integer; s: string; begin Assign(t, aFilename); Reset(t); y := 0; while not EOF(t) do begin ReadLn(t, s); for x := 0 to 39 do figure[x, y] := s[x + 1]; Inc(y); end; Close(t); end; procedure tGraphChessBoard.DrawEmpty; var v, w, x, y: integer; begin for v := 0 to 7 do for w := 0 to 7 do if (v + w) mod 2 = 1 then for x := 0 to 39 do for y := 0 to 39 do if (x + y mod 5) mod 5 = 4 then PutPixel(40 * v + x + xo, 40 * w + y + yo, Black); end; procedure tGraphChessBoard.DrawFigure(const aXo, aYo: integer); var x, y: integer; begin for x := 0 to 39 do for y := 0 to 39 do case figure[x, y] of '1': PutPixel(x + aXo + xo, y + aYo + yo, Black); '2': PutPixel(x + aXo + xo, y + aYo + yo, White); end; end; procedure tGraphChessBoard.DrawBackground(const aXo, aYo: integer); var v, w, x, y: integer; begin for x := 0 to 39 do for y := 0 to 39 do begin v := (x + aXo) div 40; w := (y + aYo) div 40; if ((v + w) mod 2 = 1) and ((x + aXo + y + aYo) mod 5 = 4) then PutPixel(x + aXo + xo, y + aYo + yo, Black) else PutPixel(x + aXo + xo, y + aYo + yo, White); end; end; function GraphMode(const aWidth, aHeight: word; const aTitle: string): boolean; var gd, gm: smallInt; w: word; begin gd := d8bit; gm := mCustom; SetWindowSize(aWidth, aHeight); InitGraph(gd, gm, aTitle); result := (GraphResult = grOk); end; procedure Sleep; begin while not(KeyPressed or CloseGraphRequest) do Delay(20); CloseGraph; end; var chessBoard: tGraphChessBoard; x, y: integer; begin if GraphMode(320, 320, 'Etude') then begin; UpdateGraph(UpdateOff); SetBkColor(White); ClearViewPort; chessBoard := tGraphChessBoard.Create(0, 0); chessBoard.DrawEmpty; chessBoard.LoadFigure('42a.txt'); x := 40; y := 0; chessboard.DrawFigure(x, y); UpdateGraph(UpdateNow); Delay(1000); while y < 160 do begin chessBoard.DrawBackground(x, y); chessboard.DrawFigure(x, y); UpdateGraph(UpdateNow); Inc(y); end; Sleep; end; end.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Sans répondre particulièrement à ta question, c'est typiquement le genre de situations, où on veut faire de jolies choses et où les outils de basent ne suffisent plus (sauf si on se lance dans du code parfois compliqué et suffisamment bas-niveau pour être optimisé pour les performances).
Ce genre de problèmes (dessin au dessus d'une zone puis effacement du dessin) se gère très simplement avec des "surfaces", c'est-à-dire des images en mémoire, que l'on dessine ou pas (avec des fonctions comme BitBlt pour Windows GDI). Pour FreePascal, il existe la bibliothèque SDL, relative facile à utiliser (j'avais fait un tetris pour le défi 2012 avec cette bibliothèque, sans la connaitre plus que ça).
M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal
Merci pour ta réponse. Je vais prendre le temps d'explorer toutes ces pistes. Quant à ton Tetris, il y a longtemps que je me suis promis de l'étudier, mais à l'époque il m'avait paru un peu trop costaud pour moi. (Au fait, c'était le défi 2011.)
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Voici une solution utilisant le type animatType de l'unité WinGraph, dont j'ai enfin compris le fonctionnement.
C'est un peu lent, mais si on supprime la ligne Delay(1), c'est trop rapide. Il faudrait peut-être décaler l'image de deux pixels à la fois, mais j'ai préféré laisser les choses telles quelles pour qu'on voie bien le résultat (les rayures qui apparaissent entre les branches de la couronne).
Mon site personnel consacré à MSEide+MSEgui : msegui.net
J'ai bien avancé. Je crois que je tiens une bonne formule. Il me reste à organiser correctement le code. Que pensez-vous du départ que j'ai pris dans l'essai ci-joint ?
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Mon échiquier animé est pratiquement fini. Il semble fonctionner correctement. Je pense retravailler la présentation du code, peut-être rajouter quelques fonctions pour une utilisation plus aisée.
Il y a quelque chose qui ne me plaît pas trop, mais que je n'ai pas su faire autrement : pour transformer le pion en dame, je recharge l'image depuis le fichier, ce qui m'oblige à avoir quelque part dans ma fenêtre un carré réservé que j'utilise pour mettre l'image et la charger dans ma variable de type animatType.
J'ai mis un peu le nez dans l'unité WinGraph pour voir s'il n'y avait pas mieux à faire, mais sans succès pour le moment. J'ai quand même pu constater au passage que les animations sont bâties sur la fonction BitBlt mentionnée précédemment.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 procedure tWinGraphChessBoard.LoadAnim(var a: animatType; aFilename: string); begin LoadBitmap(400, 0, aFilename); GetAnim(400, 0, 439, 39, midnightBlue, a); SetFillStyle(solidFill, white); Bar(400, 0, 439, 39); end;
N'hésitez pas à me faire part de vos observations ! Au fait, je rappelle que les pièces que j'utilise sont celles du programme Fritz 1.0, qu'on peut avoir gratuitement ici, et qui fonctionne parfaitement avec DOSBox. (Au même endroit, on peut aussi avoir la version 5.32, avec un magnifique échiquier en trois dimensions.)
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Règles du forum
Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
Mes tutoriels et sources Pascal
Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]
La tolérance atteindra un tel niveau que les personnes intelligentes seront interdites de toute réflexion afin de ne pas offenser les imbéciles. [Fiodor Mikhaïlovitch Dostoïevski]
Bonjour Jean-Luc ! Après avoir lu ton message, j'ai essayé une autre possibilité qui m'avait paru un peu lourde mais qui fonctionne très bien. Maintenant je peux charger mes images n'importe tout : le fond est restauré, sans que l'utilisateur ne s'aperçoive de rien.
Je remplace la pièce jointe de mon message précédent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 procedure tChessBoard.LoadAnim(var aAnim: animatType; aFilename: string); var p: pointer; size: longint; begin size := ImageSize(0, 0, 39, 39); GetMem(p, size); GetImage(0, 0, 39, 39, p^); LoadBitmap(0, 0, aFilename); GetAnim(0, 0, 39, 39, midnightBlue, aAnim); PutImage(0, 0, p^, normalPut); FreeMem(p); end;
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour ! J'ai l'occasion de ranimer cette discussion en cette rentrée, et cela me fait bien plaisir.
Grâce à une unité découverte sur le forum Lazarus anglophone, j'ai fait un programme de démonstration du protocole UCI. On y voit comment on peut communiquer avec un moteur de jeu d'échecs (en l'occurrence Pharaon de Frank Zibi, inclus dans l'archive avec l'aimable autorisation de l'auteur).
J'avais fait il y a quelque temps une version Delphi 7.
Maintenant je me demande à quoi pourrait ressembler le code du moteur, en Pascal. Une fois le processus lancé, il attend les commandes de l'interface graphique et y répond. Si vous êtes d'humeur à proposer un petit exemple de code sur le sujet, je suis preneur.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Parce que, par exemple, si je fais la chose suivante :
ça fonctionne parfaitement. Mais le protocole exige que le processus soit "joignable" sans interruption, donc avec une procédure longue à la place de WriteLn ça n'irait pas. Donc il faudrait que les procédures s'exécutent dans un thread, n'est-ce pas ? J'ai commencé à me documenter sur le sujet mais je n'ai pas encore trouvé un code que je comprenne et qui réponde exactement au problème.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 program Processus; var s: string; begin while not Eof do begin ReadLn(s); WriteLn(s); end; end.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager