Bonjour !
Je voudrais vous présenter le dernier état de mon programme.
Désormais vous jouez contre l'ordinateur. Pour le moment, son "intelligence articielle" se limite à cette idée que prendre une pièce vaut mieux que de ne pas la prendre, et que plus la prise est importante mieux c'est ! Quand cette règle n'est pas applicable, il joue au hasard (le dernier coup évalué).
Attention, pour que le programme fonctionne il y a toujours cette ligne à modifier :
Enfin, j'aimerais avoir votre conseil sur la question suivante : serait-il possible de faire un échiquier graphique sous la forme d'un exécutable séparé que le programme principal appellerait ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 CheminFichiers : String = 'c:\Atelier\PAS\TEMP\' ; {****************** A MODIFIER ******************}
Qua,
Petite suggestion pour la présentation :
Au lieu d'utiliser des minuscules/majuscules pour différencier les 2 joueurs, 2 couleurs seraient plus aisément distinguables au coup d'œil.
De même pour l'échiquier, tu pourrais jouer du BackGround pour dessiner les cases avec 2 couleurs (sans oublier de gérer correctement l'affichage avec les lettres des pièces selon le joueur).
C'est en tout cas le genre de truc que j'aurais fait (avec un principe : profiter des possibilités quand elles permettent d'améliorer l'ergonomie).
![]()
J'ai complété la fonction d'évaluation. Pour les premiers coups de la partie, cela donne un jeu acceptable. Il faudrait que j'ajoute une détection défensive et offensive du mat, au moins au coup suivant.
Luo,
Je préfère la version montrée dans le message #27, sauf pour la bordure avec les indices ligne/colonne, plus clair dans la nouvelle version.
Pour les pièces, j'aurais utilisé p au lieu de P pour les pions, ça se distingue plus aisément des majuscules pour les autres pièces.
![]()
Salut
Pour répondre à :
Je pense que c'est se prendre la tête pour rien. Normalement, c'est du Pascal, donc un simple portage de ton code sous Lazarus devrait fonctionner (moyennant quelques modifs minimes)Voici ce que j'ai en tête : j'aimerais bien continuer mon moteur avec TP7 et le joindre (je ne sais trop comment) à un échiquier fait avec Lazarus ou Virtual Pascal par exemple. A votre avis est-ce possible et est-ce une bonne idée ?
Peut tu m'expliquer ton astuce du tableau de constantes ?
J'avous être intrigué par ta technique ^^.Je me suis servi, entre autres choses, de tableaux de constantes pour indiquer à chaque pièce les "bonnes" cases :
Bonne chance
Merci pour ta réponse. Je vais essayer d'écrire avec Free Pascal et de repérer les différences en question.
C'est bête comme tout, et je crains que tu ne sois déçu par mon explication !
A chaque pièce est associé un tableau qui donne tant de points pour telle case. Les points sont ajoutés automatiquement (avec un faible coefficient toutefois) à la note des coups : coup de telle pièce à destination de telle case, tant de points. Par exemple le cavalier a trois façons de sortir de sa position initiale. Une "bonne" et deux mauvaises. J'ajoute un point sur la bonne case ; il joue le coup que je veux. Comme tu vois, cela ne peut servir que pour les coups d'ouverture, parce qu'ensuite on ne peut plus savoir à l'avance quelles sont les "bonnes" cases.
Merci pour tes encouragements !
Bonjour !
Maintenant que je sais un peu mieux programmer en Pascal, j'ai commencé à réécrire mon jeu d'échecs, en essayant de garder ce qu'il y avait de bon dans mes précédents essais.
Je posterai au fur et à mesure les parties du programme. Je ferai en sorte que le code soit toujours exécutable même sans les parties manquantes. De cette façon, en attendant un programme d'échecs complet, ce travail pourra éventuellement être utile comme suite d'exemples de code autour de la programmation d'un jeu d'échecs.
Voici la première partie refaite, qui contient :
- La déclaration des constantes, types et variables
- La procédure qui affiche un échiquier en mode texte
- Une fonction qui convertit les valeurs courantes dans une chaîne au format standard FEN
- Plus diverses petites fonctions utiles
Avis et conseils toujours bienvenus !
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 program Eschecs; uses Crt, Dos; type TCoord = 1..8; TPiece = -6..6; TCouleur = -1..1; TEchiquier = array[TCoord, TCoord] of TPiece; TTableauBooleen = array[0..3] of Boolean; TCoup = record x1, y1, x2, y2: TCoord; notation: string[4]; end; TNomCoup = string[4]; TNomCarreau = string[2]; TLettres = array[TPiece] of Char; var Occupant: TEchiquier; Trait: TCouleur; RoquePrimo: TTableauBooleen; CarreauPassant: string[2]; Echec: Boolean; RoqueSecundo: TTableauBooleen; NombreDemiCoups: Integer; NombreCoups: Integer; NombrePossibles: Byte; const Blanc = 1; Noir = -1; Vide = 0; Pion = 1; Cavalier = 2; Fou = 3; Tour = 4; Dame = 5; Roi = 6; e8c8 = 0; e8g8 = 1; e1c1 = 2; e1g1 = 3; Vrai = True; Faux = False; Cava = Cavalier; Initiale: TEchiquier = ( (Tour, Pion, Vide, Vide, Vide, Vide, -Pion, -Tour), (Cava, Pion, Vide, Vide, Vide, Vide, -Pion, -Cava), (Fou, Pion, Vide, Vide, Vide, Vide, -Pion, -Fou), (Dame, Pion, Vide, Vide, Vide, Vide, -Pion, -Dame), (Roi, Pion, Vide, Vide, Vide, Vide, -Pion, -Roi), (Fou, Pion, Vide, Vide, Vide, Vide, -Pion, -Fou), (Cava, Pion, Vide, Vide, Vide, Vide, -Pion, -Cava), (Tour, Pion, Vide, Vide, Vide, Vide, -Pion, -Tour)); LettresAFF: TLettres = ('R', 'D', 'T', 'F', 'C', 'p', #32, 'p', 'C', 'F', 'T', 'D', 'R'); LettresFEN: TLettres = ('k', 'q', 'r', 'b', 'n', 'p', #32, 'P', 'N', 'B', 'R', 'Q', 'K'); procedure Initialise; var x, y: TCoord; begin for x := 1 to 8 do begin for y := 1 to 8 do begin Occupant[x, y] := Initiale[x, y]; end; end; Trait := Blanc; RoquePrimo[e8c8] := Vrai; RoquePrimo[e8g8] := Vrai; RoquePrimo[e1c1] := Vrai; RoquePrimo[e1g1] := Vrai; CarreauPassant := '-'; NombreDemiCoups := 0; NombreCoups := 1; end; {Initialise} function Carreau(x, y: TCoord): Boolean; begin Carreau := (x in [1..8]) and (y in [1..8]); end; {Carreau} function CarreauBlanc(x, y: TCoord): Boolean; begin CarreauBlanc := not ((x + y) mod 2 = 0); end; {CarreauBlanc} function IntToStr(i: Longint): string; var s: string[11]; begin Str(i, s); IntToStr := s; end; {IntToStr} function NomCarreau(x, y: TCoord): TNomCarreau; begin NomCarreau := chr(x + 96) + chr(y + 48); end; {NomCarreau} function Signe(p: TPiece): TCouleur; begin case p of -6.. - 1: Signe := -1; 0: Signe := 0; 1..7: Signe := 1; end; end; {Signe} function FEN( PP: TEchiquier; AC: TCouleur; CA: TTableauBooleen; TS: TNomCarreau; HC: Integer; FN: Integer): string; var x, y, n: Byte; a: Boolean; s: string; procedure ESPACE; begin s := Concat(s, chr(32)); end; begin s := ''; for y := 8 downto 1 do begin x := 1; n := 1; repeat if (Abs(PP[x, y]) > 0) then begin s := Concat(s, LettresFEN[PP[x, y]]); Inc(x); end else begin if (x = 8) then begin s := Concat(s, IntToStr(n)); Inc(x); end else begin if (Abs(PP[x + 1, y]) > 0) then begin s := Concat(s, IntToStr(n)); Inc(x); end else begin Inc(n); Inc(x); end; end; end; until (x = 9); if not (y = 1) then s := Concat(s, '/') else ESPACE; end; if (AC = Blanc) then s := Concat(s, 'w') else s := Concat(s, 'b'); ESPACE; a := False; if CA[e1g1] then begin s := Concat(s, 'K'); a := True; end; if CA[e1c1] then begin s := Concat(s, 'Q'); a := True; end; if CA[e8g8] then begin s := Concat(s, 'k'); a := True; end; if CA[e1g1] then begin s := Concat(s, 'q'); a := True; end; if not a then s := Concat(s, '-'); ESPACE; s := Concat(s, TS); ESPACE; s := Concat(s, IntToStr(HC)); ESPACE; s := Concat(s, IntToStr(FN)); FEN := s; end; { FEN } procedure AfficheTablier(occup: TEchiquier; c1, c2, c3, c4, c5, c6: Byte); var x, y: TCoord; begin for y := 8 downto 1 do begin TextBackground(c5); TextColor(c6); GotoXY(1, -3 * y + 25); Write(' '); GotoXY(1, -3 * y + 26); Write(IntToStr(y)); GotoXY(1, -3 * y + 27); Write(' '); for x := 1 to 8 do begin if CarreauBlanc(x, y) then TextBackground(c3) else TextBackground(c4); if (occup[x, y] > 0) then TextColor(c1) else TextColor(c2); GotoXY(5 * x - 3, -3 * y + 25); Write(' '); GotoXY(5 * x - 3, -3 * y + 26); Write(' ' + LettresAFF[occup[x, y]] + ' '); GotoXY(5 * x - 3, -3 * y + 27); Write(' '); end; end; TextBackground(c5); TextColor(c6); GotoXY(1, 25); Write(' a b c d e f g h '); end; {AfficheTablier} begin Initialise; AfficheTablier(Occupant, White, Yellow, Green, Brown, LightGray, Black); ReadKey; ClrScr; Write(FEN(Occupant, Trait, RoquePrimo, CarreauPassant, NombreDemiCoups, NombreCoups)); ReadKey; end.
Bonjour !
Je cherche à améliorer la partie de mon programme qui calcule les coups possibles. J'ai voulu écrire une fonction qui pour une position donnée renvoie la liste des coups. Cette fonction fait appel à deux autres : une qui vérifie que le mouvement est conforme à la nature de la pièce, l'autre qui vérifie que le mouvement en question ne met pas le roi en échec.
J'ai testé les deux premières fonctions séparément. Mais quand j'appelle la troisième, j'obtiens un "error 202 stack overflow".
Qu'est-ce qui ne va pas au juste dans ma façon de procéder ?
Quelle serait à votre avis la bonne façon de faire ?
Voici le code :
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 Function MouvementNaturel (x1,y1,x2,y2:TCoord; E:TEchiquier): Boolean; Var dx,dy: ShortInt; Function Passage: Boolean; Var vx,vy,x,y: ShortInt; Obstacle: Boolean; Begin Passage:=Faux; Obstacle:=Faux; vx:=Signe(dx); vy:=Signe(dy); x:=x1; y:=y1; Repeat Inc(x,vx); Inc(y,vy); If (x=x2) And (y=y2) Then Passage:=Vrai; If (Passage=Faux) And (E[x,y]<>Vide) Then Obstacle:=Vrai; Until (Passage or Obstacle); End; Begin If Signe(E[x2,y2])=Signe(E[x1,y1]) Then Begin MouvementNaturel:=Faux; Exit; End; dx:=x2-x1; dy:=y2-y1; If (dx=0) and (dy=0) Then Begin MouvementNaturel:=Faux; Exit; End; Case Abs(E[x1,y1]) Of Pion: Begin If Signe(dy)=E[x1,y1] Then Begin If (Abs(dx*dy)=1) And (E[x2,y2]<>Vide) Then Begin MouvementNaturel:=Vrai; Exit; End; If (dx=0) And (E[x1,y1+E[x1,y1]]=Vide) Then Begin If Abs(dy)=1 Then Begin MouvementNaturel:=Vrai; Exit; End; If (Abs(dy)=2) And (E[x1,y1+dy]=Vide) Then Begin If ((E[x1,y1]=Blanc) And (y1=2)) Or ((E[x1,y1]=Noir) And (y1=7)) Then Begin MouvementNaturel:=Vrai; Exit; End; End; End; End; End; Cavalier: Begin If dx*dx+dy*dy=5 Then Begin MouvementNaturel:=Vrai; Exit; End; End; Fou: Begin If Abs(dx)=Abs(dy) Then Begin If Passage Then Begin MouvementNaturel:=Vrai; Exit; End; End; End; Tour: Begin If dx*dy=0 Then Begin If Passage Then Begin MouvementNaturel:=Vrai; Exit; End; End; End; Dame: Begin If Abs(dx)=Abs(dy) Then Begin If Passage Then Begin MouvementNaturel:=Vrai; Exit; End; End; If dx*dy=0 Then Begin If Passage Then Begin MouvementNaturel:=Vrai; Exit; End; End; End; Roi: Begin If dx*dx+dy*dy<=2 Then Begin MouvementNaturel:=Vrai; Exit; End; End; End; MouvementNaturel:=Faux; End; Function EchecAuRoi( tablier:TEchiquier; couleur:TCouleur): Boolean; Var x1,y1,x2,y2: TCoord; Begin For x2:=1 To 8 Do Begin For y2:=1 To 8 Do Begin If tablier[x2,y2]=Roi*couleur Then Begin For x1:=1 To 8 Do Begin For y1:=1 To 8 Do Begin If Signe(tablier[x1,y1])=-1*couleur Then Begin If MouvementNaturel(x1,y1,x2,y2,tablier) Then Begin If not ((abs(tablier[x1,y1])=Pion) And (x2=x1)) Then Begin EchecAuRoi:=Vrai; Exit; End; End; End; End; End; End; End; End; EchecAuRoi:=Faux; End; Function CoupsPossibles( tablier: TEchiquier; couleur: TCouleur; roque: TTableauBooleen; passant: TNomCarreau): String; Var x1,y1,x2,y2: TCoord; s:String; fictif: TEchiquier; Begin s:=''; For x1:=1 To 8 Do Begin For y1:=1 To 8 Do Begin If Signe(tablier[x1,y1])=couleur Then Begin For x2:=1 To 8 Do Begin For y2:=1 To 8 Do Begin If MouvementNaturel(x1,y1,x2,y2,tablier) Then Begin fictif:=tablier; fictif[x2,y2]:=fictif[x1,y1]; fictif[x1,y1]:=Vide; If Not EchecAuRoi(fictif,couleur) Then Begin s:=Concat(s,NomCarreau(x1,y1)); s:=Concat(s,NomCarreau(x2,y2)); End; End; End; End; End; End; End; CoupsPossibles:=s; End;
Je n'ai malheureusement pas le temps de regarder attentivement ton code mais une remarque me vient immédiatement à l'esprit : il vaut mieux transmettre un paramètre qui ne doit pas être modifié comme constante plutôt que par valeur, pour éviter une copie inutile sur la pile et, par corollaire, pour économiser de l'espace sur la pile :
FAQ Pascal
![]()
Merci pour ta réponse et pour le lien. Je vais creuser de ce côté-là.
![]()
J'ai appris beaucoup de choses en parcourant la FAQ Pascal. Excellente qualité de documentation !
Pour revenir au débordement de pile ou "stack overflow", je me souviens que dans mes premiers essais de programmation d'un jeu d'échecs, je n'avais que des variables globales et des procédures sans paramètres. On m'a dit et j'ai constaté par moi-même que ce n'était la meilleure façon de faire.
Mais à présent je m'aperçois que le passage explicite des paramètres a aussi ses inconvénients :
Si je comprends bien : beaucoup de passages explicites, beaucoup de copies. Beaucoup de copies, débordement de la pile !Il est à noter que, dans le cas de la transmission par valeur, lorsque c'est l'adresse du paramètre qui est déposée sur la pile, une copie locale de la variable est réalisée au début de la procédure ou fonction.
Sur le passage d'un paramètre comme constante, j'ai cru comprendre que Turbo Pascal ne le permettait pas :
Comme je n'étais pas sûr d'avoir bien compris, j'ai quand même essayé cette écriture :Remarque : Turbo Pascal ne supporte que la transmission par valeur et par adresse.
Le compilateur l'accepte, mais je ne sais pas si cela change quelque chose.
Code : Sélectionner tout - Visualiser dans une fenêtre à part Function Exemple (const a: byte): byte;
l'ajout de "const" a deux conséquences
1) la variable n'est plus modifiable
2) si c'est une structure ou une chaîne, elle est passée par adresse et non par valeur (aucune incidence sur un BYTE donc).
si elle est déclarée "var" c'est la même chose mais modifiable (et dans le cas d'un BYTE c'est un pointeur vers un BYTE et non plus un BYTE qui est passé en paramètre).
voici un exemple avec une variable globale
lors d'un appel à proc1, une copie de E est placée sur la pile, si E est gros tu arrives vite à saturation de la pile avec un appel récursif.
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 var E:TEchiquier; procedure proc1(E:TEchiquier); begin end; procedure proc2(const E:TEchiquier); begin end; procedure proc3(var E:TEchiquier); begin end; procedure proc4; begin end; begin proc1(E); proc2(E); proc3(E); proc4(); end;
dans les trois autres cas, c'est la variable globale E qui est utilisée, alors quelle différence entre proc2, proc3 et proc4 ?
proc2 interdit de modifier E, c'est ce qui la distingue de proc3
quand à proc3 il n'y a aucune différence avec proc4, MAIS il devient possible de l'utiliser dans un contexte différent qui donne tout son sens à la présence du paramètre.
Et pour la récursivité sur de grosses structures, il est intéressant de ne conserver que les modifications et non la structure entière, exemple:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 var E1, E2: TEchiquier; begin proc3(E1); proc3(E2); end;
cet appel récursif ne conserve à chaque itération que 6 octets au lieu de la totalité de l'échiquier...bon en fait il faudrait aussi conserver la pièce mangée s'il y en a une, mais c'est le principe qui est montré ici
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 procedure JouerUnCoup(var E: TEchiquier; Profondeur: Integer); var x1, y1: Byte; x2, y2: Byte; avant : Byte; piece : Byte; begin // déterminer le coup à jouer : piece de x1, y1 vers x2, y2 ... // déplacer la pièce E[x1, y1] := vide; avant := E[x2,y2]; E[x2, y2] := piece; // coup suivant if Profondeur > 0 then JouerUnCoup(E, Profondeur - 1); // fin de procédure on annule le coup pour en tester un autre E[x1,y1] := piece; E[x2,y2] := avant; end;![]()
Merci pour ces explications. Cette fois (mis à part certaines connaissances qui me manquent) je crois que j'ai compris.
Autrement après une journée de recherches j'ai fini par trouver mon erreur : car c'était bien une vilaine erreur de ma part, à savoir une fonction qui s'appelait elle-même. C'était un essai involontaire de fonction récursive !
Joyeuses Pâques !
![]()
Bonjour !
J'ai réécrit la partie du programme qui calcule les coups possibles. J'ai essayé de tirer profit des conseils donnés par Alcatîz et par Paul TOTH concernant les paramètres. Voici l'en-tête de la fonction :
Cela donne un échiquier sur lequel je joue contre moi-même, vu qu'il n'y a pas d'évaluation. L'ordinateur vérifie que le coup saisi est sur la liste. Il détecte l'échec, le mat, les coups spéciaux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Procedure Possibles (Const T:TTablier; Const C:TCouleur; Const Prim:T4Bool; Const Pass: TCarreau; F: String; Var N: Byte);
voici deux petites remarques rapides
1) pour compiler le projet sous Delphi il suffit de faire ceci
2) je pense que "fictif" correspond à ma remarque
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 {$IFDEF WIN32} {$APPTYPE CONSOLE} uses Crt; // http://sourceforge.net/projects/delphicrt/ {$ELSE} Uses Crt, Dos; {$ENDIF}
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 // en paramètre : var T: TTablier; // en variable : fictif: TPiece ... //fictif:=T; //fictif[x2,y2]:=fictif[x1,y1]; //fictif[x1,y1]:=0; // sauver le coup fictif := T[x2,y2]; T[x2,y2] := T[x1,y1]; T[x1,y1] := 0; If Not EchecAuRoi({fictif} T,C) Then Begin cp:=Concat(NomCarreau(x1,y1),NomCarreau(x2,y2)); Write(lst,cp); Inc(Ntemp); End; // restituer le coup T[x1,y1] := T[x2,y2]; T[x2,y2] := fictif;
Je peux donc compiler mon code Turbo Pascal sous Delphi ? Bon à savoir !
Mais je n'ai pas encore vraiment pris en main Delphi, mis à part me servir de l'éditeur pour taper mon code.
J'ai téléchargé l'unité Delphi Crt, mais je n'ai réussi à compiler aucune des deux unités contenues dans le dossier. Dans les deux cas j'obtiens un message d'erreur :
C'est avec Delphi XE2. Peut-être il faudrait que j'essaie avec Delphi 6 ou 7, mais je ne veux pas perdre ma journée là-dessus. De toute façon, si je me lance dans un projet Delphi, je ne pense pas que j'utiliserai l'unité Crt. Sinon autant rester à Turbo Pascal, non ? J'ai fait un essai de compilation d'une application console, en ajoutant juste une instruction "write" au modèle. Résultat, un exécutable de ... 1047 ko ! Ça n'est pas très intéressant, un programme d'une tonne qui dit "bonjour"...[DCC Erreur] crt.pas(1222): E2010 Types incompatibles : 'AnsiChar' et 'Char'
[DCC Erreur] crt.pas(1244): E2010 Types incompatibles : 'AnsiChar' et 'Char'
[DCC Avertissement] crt.pas(1253): W1061 La réduction de la constante WideChar donnée (#$FFFF) en AnsiChar génère une perte d'information
[DCC Erreur fatale] Project1.dpr(6): F2063 Impossible de compiler l'unité utilisée 'Crt.pas'
J'ai bien compris l'idée de ne restaurer que les valeurs qui ont changé. C'est même comme ça que je faisais dans mes premiers programmes, mais j'y ai renoncé. S'il n'y avait que des mouvements ordinaires, cette solution irait très bien, mais le coup simulé peut être aussi : un pion se changeant en dame, un roque, une prise en passant. Il faut donc détecter ces coups spéciaux, et enregistrer les valeurs qui ont changé mais qui ne sont pas les mêmes dans chaque cas. C'est très faisable, mais c'est un peu casse-tête et ça complique le code. Ce sera peut-être plus rapide à l'exécution, mais je me pose la question, vu les tests qu'il faut ajouter.
![]()
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