Mon site personnel consacré à MSEide+MSEgui : msegui.net
Ce ne devrait pas être très beau, car le petit programme n'a d'autre ambition que de montrer qu'avec un code compact on peut obtenir des applications plutôt performantes. D'ailleurs, l'unité chess.pas ne préjuge en rien de l'affichage des pièces : l'utilisateur est libre d'utiliser les outils d'affichage qu'il souhaite. Si j'avais un peu de temps, je séparerais aussi volontiers les déplacements des contrôles de ces déplacements, ou au moins les autorisations de déplacements qui ne tiennent qu'aux pièces prises individuellement et ceux qui relèvent de la situation globale du jeu (interaction des pièces).
NB : pour ajouter des pions, il suffirait d'un code minimal, si la classe n'était encore légèrement boguée .
Plus précisément, il faudrait :
ajouter deux constantes :
ajouter deux tableaux de pions dans la partie privée de TMainForm :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 C_Pawn = #$2659; C_BlackPawn = #$265F;
ajouter 7 lignes dans la méthode Init :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 fWPawns: array[1..8] of TPawn; fBPawns: array[1..8] of TPawn;
Et tout fonctionne... Ce n'est pas beau, la POO ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 // les pions for LI := 1 to 8 do begin fWPawns[LI] := TPawn.Create(LI, 2); Add(fWPawns[LI], C_Pawn); fBPawns[LI] := TPawn.Create(LI, 7, ccBlack); Add(fBPawns[LI], C_BlackPawn); end;
NB : j'ai aussi débogué chess.pas
en récrivant la méthode suivante, la seule que je n'avais pas testée () :
A présent, les pions ne peuvent plus reculer, ce qui n'est pas plus mal .
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 function TPawn.IsLegalMove(const AColumn, ARow: TChessLength): Boolean; begin Result := False; if (Column = AColumn) then begin if (Color = ccWhite) then begin if (Row = 2) then Result := (Byte(ARow - Row) in [1, 2]) else Result := ((ARow - Row) = 1); end else begin if (Row = 7) then Result := (Byte(Row - ARow) in [1, 2]) else Result := ((Row - ARow) = 1); end; end else begin if (Color = ccWhite) then Result := (Abs(Column - AColumn) = 1) and ((ARow - Row) = 1) else Result := (Abs(Column - AColumn) = 1) and ((Row - ARow) = 1) end; end;
Bonjour !
J'ai écrit une fonction qui génère une position de départ au jeu des échecs aléatoires de Fischer (Fischer Random Chess). La fonction utilise la méthode décrite dans ce document.
Les cinq paramètres de la fonction correspondent au résultat des cinq lancers du dé (abstraction faite des cas où l'on est obligé de relancer le dé parce que le nombre qui est sorti n'est pas utilisable).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 unit Fischerandom; interface function StartPosition(a, b, c, d, e: integer): string; overload; function StartPosition(): string; overload;
L'unité Fischerandom permet donc de générer une position au hasard,
ou les 960 positions possibles.
Code : Sélectionner tout - Visualiser dans une fenêtre à part WriteLn(StartPosition());
La position de départ conventionnelle des échecs ordinaires se trouve parmi les 960 positions :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 { Les 1920 ou 960 positions possibles. } positions := TStringList.Create; positions.Sorted := TRUE; positions.Duplicates := dupIgnore; for i := 1 to 4 do { Position du premier fou. } for j := 1 to 4 do { Position du second fou. } for k := 1 to 6 do { Position de la dame. } for l := 1 to 5 do { Position du premier cavalier. } for m := 1 to 4 do { Position du second cavalier. } positions.Append(StartPosition(i, j, k, l, m)); WriteLn(positions.Count); positions.SaveToFile('startpositions.fen'); positions.Free;
Mon implémentation de la fonction m'a paru un peu verbeuse, mais je n'ai pas trouvé mieux. Si vous êtes plus inspirés que moi, je lirai vos suggestions avec plaisir.
Code : Sélectionner tout - Visualiser dans une fenêtre à part WriteLn(StartPosition(2, 3, 3, 2, 3));
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Le sujet m'ayant passionné, j'ai continué à y travailler et j'ai écrit un article. J'aimerais savoir ce que vous en pensez.
Mon idée en écrivant l'article était, au départ, de présenter un problème dont on puisse faire un exercice de mathématique (de dénombrement) ou de programmation.
Chemin faisant, je suis tombé sur le problème des modifications à apporter à la notation FEN, et j'ai voulu faire le tour de la question, ne serait-ce que pour moi-même. Car j'aimerais bien modifier mon jeu d'échecs pour qu'il permette de jouer aux échecs aléatoires, mais ce n'est pas si facile que j'aurais cru d'abord.
Merci d'avance pour votre lecture que je souhaiterais la plus sévère possible.
Envoyé par lisezmoi.txt
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Salut Roland,
mes grains de sel concernant le fichier html :
Dans les règles :
Pas sûr que cette phrase soit vraiment utile (à part pour embrouiller) : "On est libre de considérer que les pions sont intervertis comme les autres pièces."
Dans la méthode pour placer les pièces, je n'ai rien compris aux points 3, 4 et 5.
Reprenons le point 3 : "Lancer le dé et placer la dame sur la première des six cases vides."
Est-il vraiment besoin de lancer le dé pour placer la dame sur la première des six cases vides, puisque le résultat du lancer de dé n'est pas utilisé ?
Idem pour les deux points suivants.
Problème du roque :
"quelle que soit la position du roi et celle de la tour" --> "quelle que soit la position du roi et celles des tours", non ?, ou alors "celle de la tour choisie pour le roque".
+ un poil d'accord et de conjugaison, in fine : "quelle que soit ..." --> "quelles que soient les positions du roi et des tours" et ça fonctionne aussi avec la variante "les positions du roi et de la tour choisie pour le roque".
Je précise qu'avant d'ouvrir ton fichier zip, je n'avais jamais entendu parler d'échecs aléatoires, c'est donc un pur novice en la matière qui a lu ton texte.
Je n'ai absolument pas regardé le code.
Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peut–être qu'il peut être sûr, etc.
Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
Mes 2 cts,
--
jp
Bonne idée ce petit article. Je ne connaissais pas non plus cette variante des échecs. Mais alors, il n'existe plus de livre d'ouvertures utilisable ?
Même remarque que Jipété sur les points 3, 4 et 5 : il faut regarder le code pour comprendre.
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 Jipété ! Merci pour ta lecture.
C'est vrai. Je vais supprimer cette phrase et revoir tout le paragraphe. Le problème c'est que ça m'embête de dire que les pions ne bougent pas après avoir avoir dit que les pièces restent sur leur ligne... Je vais voir si je trouve une manière plus satisfaisante d'expliquer tout ça.
Oui alors là effectivement je ne sais pas où j'avais la tête. Merci de m'avoir signalé cette bourde.
En effet, c'est ce que je voulais dire : la tour choisie pour le roque. Je vais corriger cela.
Bien pris note aussi de ta remarque sur l'accord du verbe être.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour Alcatîz !
Merci.
Justement, c'est l'intérêt de la chose. Fischer (je me suis un peu intéressé au personnage en écrivant l'article) prétendait que la domination des soviétiques sur le monde des échecs tenait à leur connaissance encyclopédique des ouvertures, et il jugeait pour cette raison que les "vieux échecs étaient morts". Non, que je sache il n'y a pas de livre d'ouvertures utilisable.
Oui j'étais distrait en écrivant ce passage. Je vais le corriger.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Voilà, j'ai appliqué les corrections que vous m'avez indiquées. Chemin faisant j'ai ajouté pas mal de choses.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Effectivement c'est beaucoup plus clair.
J'ai vu que dans la méthode de placement de Northam, on plaçait dans l'ordre :
- le fou noir (4 possibilités) ;
- le fou blanc (4 possibilités) ;
- le roi, en excluant la première et la dernière case vide (4 possibilités) ;
- les tours, de chaque côté du roi (nombre de possibilités dépendant des tirages précédents) ;
- la dame (3 possibilités) ;
- les cavaliers, sur les deux dernières cases.
Tiens, un peu hors sujet, une question au spécialiste des échecs que tu es : lors de la promotion d'un pion, peut-on obtenir deux fous de la même couleur, ou bien est-ce interdit ?
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]
Tant mieux. Merci pour ta relecture.
Si je comprends bien, cette méthode aurait l'avantage de ne pas produire de doublons ? Ce qui m'ennuie, c'est que je ne retrouve pas le nombre 960 dans cette méthode. J'ai failli me faire une entorse au cerveau après avoir lu ton message. Il y a certainement quelque chose qui ne va pas dans mon raisonnement mais je ne trouve pas ce que c'est.
Je ne m'étais jamais posé la question mais après avoir consulté les règles officielles de la FIDE, je peux confirmer qu'on a bien le droit d'avoir deux fous sur des cases de même couleur. En fait les règles officielles n'en parlent pas : elles disent seulement qu'on n'est pas tenu de faire son choix parmi les pièces capturées. On peut donc avoir trois fous, et il y en aura nécessairement deux qui seront sur la même couleur de case.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Salut,
EDIT : grillé à une minute,
ne sachant pas quand Roland va répondre,j'ai fouillé dans mon vieux Seneca et y ai trouvé la note suivante :
Et tu conviendras avec moi que si l'on peut avoir trois cavaliers, il y en aura donc obligatoirement deux de la même couleur.Envoyé par Camil Seneca -- Les échecs
Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peut–être qu'il peut être sûr, etc.
Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
Mes 2 cts,
--
jp
Mon site personnel consacré à MSEide+MSEgui : msegui.net
J'ai continué à creuser la question de la notation FEN modifiée, autour de laquelle règne une certaine confusion. Je vous passe les détails, ce n'est pas très intéressant. Toujours est-il qu'il semblerait que la notation Shredder-FEN l'ait emporté dans la pratique. J'ai constaté que trois logiciels commerciaux (Aquarium, Fritz et Shredder) l'utilisent. Le fait qu'elle ne soit pas compatible avec l'ancienne notation peut aussi bien être vu comme un avantage que comme un inconvénient.
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]
Oui, ça y est, je vois.
Voici un essai d'implémentation de la méthode Northam.
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 uses SysUtils, Math; function StartPosition(): string; type TIntegerArray = array of integer; function EmptySquares(const aRow: string; const iStart, iEnd: integer): TIntegerArray; var i: integer; begin SetLength(result, 0); for i := iStart to iEnd do if aRow[i] = '.' then begin SetLength(result, Succ(Length(result))); result[High(result)] := i; end; end; function CastlingRights(const iRook1, iRook2: integer): string; begin result := Concat( Chr(Ord('A') + Pred(iRook1)), Chr(Ord('A') + Pred(iRook2)), Chr(Ord('a') + Pred(iRook1)), Chr(Ord('a') + Pred(iRook2)) ); end; var i, iRook1, iRook2: integer; arr: TIntegerArray; blackpieces: string; begin result := StringOfChar('.', 8); result[2 * Random(4) + 1] := 'B'; result[2 * Random(4) + 2] := 'B'; arr := EmptySquares(result, 1, 8); i := arr[Random(4) + 1]; result[i] := 'K'; iRook1 := RandomFrom(EmptySquares(result, 1, Pred(i))); result[iRook1] := 'R'; iRook2 := RandomFrom(EmptySquares(result, Succ(i), 8)); result[iRook2] := 'R'; result[RandomFrom(EmptySquares(result, 1, 8))] := 'Q'; for i := 1 to 8 do if result[i] = '.' then result[i] := 'N'; blackpieces := LowerCase(result); result := Concat(blackpieces, '/pppppppp/8/8/8/8/PPPPPPPP/', result, ' w ', CastlingRights(iRook1, iRook2), ' - 0 1'); end; begin Randomize; WriteLn(StartPosition()); end.
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour !
Pour la prochaine version de mon jeu, j'ai fait en sorte que la ligne blanche qui entoure les pièces n'apparaisse pas lorsque l'échiquier de marbre est utilisé. C'est plus joli comme ça mais du coup les pièces noires se voient moins bien sur les cases sombres.
J'ai essayé d'éclaircir les cases sombres mais apparemment je n'ai pas compris comment le code fonctionne.
Johann, si tu passes par là, est-ce que tu pourrais m'expliquer comment faire cela et pourquoi pas, par la même occasion, me dire comment je pourrais faire du marbre gris, bleu...
Soit dit en passant, je n'arrête pas de recevoir des compliments sur cet échiquier de marbre.
Tu pourrais aussi en faire un en bois. Ce serait une bonne publicité pour ta bibliothèque.
Autrement, tant que je suis sur le sujet, j'ai trouvé de très belles pièces que je pense utiliser un de ces jours :
https://dilena.de/chess-artwork-piec...ard-art-assets
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Je me suis en train de me demander si je ne me suis pas cassé la tête pour rien. Tout compte fait, est-ce que ça n'était pas mieux avec le trait blanc autour des pièces ?
Mon site personnel consacré à MSEide+MSEgui : msegui.net
Bonjour Roland,
Pour changer la couleur du marbre, je t'invite à rajouter un paramètre à la procédure CreateMarbleTexture :
Il ne faut bien entendu pas appeler Negative ou Grayscale comme dans le code original, qui étaient là pour transformer la texture claire en texture sombre, puisque là on indique directement la couleur souhaitée.
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 function CreateMarbleTexture(tx,ty: integer; c1, c2: TBGRAPixel): TBGRABitmap; var colorOscillation: integer; p: PBGRAPixel; i: Integer; begin result := CreateCyclicPerlinNoiseMap(tx,ty,1,1,1); p := result.Data; for i := 0 to result.NbPixels-1 do begin colorOscillation := round(power((sin(p^.red*Pi/80)+1)/2,0.2)*256); p^ := Interp256(c1,c2,colorOscillation); inc(p); end; end; function CreateLightMarbleTexture(tx,ty: integer): TBGRABitmap; begin result := CreateMarbleTexture(tx,ty,BGRA(181,157,105),BGRA(228,227,180)); end; function CreateDarkMarbleTexture(tx,ty: integer): TBGRABitmap; begin result := CreateMarbleTexture(tx,ty,BGRA(211,187,135),BGRA(168,167,120)); end;
Sinon au sujet du redimensionnement des pièces, changer leur contour etc., il peut être intéressant de passer par le vectoriel. Par exemple le SVG que tu peux dessiner à différentes échelles (TBGRASVG), ou bien les chemins directement. Par exemple, dans un fichier SVG, une forme complexe est représentée par un objet chemin et sa forme est décrite par une chaine de caractère. Tu peux affecter cette chaine de caractère à une objet TBGRAPath via sa propriété SvgString. Ensuite tu peux dessiner ce chemin avec TBGRABitmap.DrawPath ou bien via le Canvas2d et choisir sa couleur et l'épaisseur de trait, voire utiliser un dégradé de couleur ou une texture pour le remplissage.
Exemple Canvas2d et SVG: https://github.com/bgrabitmap/bgrabi...t/testcanvas2d
Si tu veux par du code directement, tu peux utiliser une courbe EasyBezier (dispo dans la dernière version de BGRABitmap):
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 var pawn: TEasyBezierCurve; Img: TBGRABitmap; begin Img := TBGRABitmap.Create(87,164, BGRAWhite); pawn := EasyBezierCurve([PointF(0,10),PointF(10,0),PointF(30,0),PointF(40,10),PointF(40,20),PointF(30,30), PointF(40,40),PointF(40,70),PointF(0,70),PointF(0,40),PointF(10,30),PointF(0,20)], true, cmAuto); with Img.Canvas2D do begin lineJoinLCL:= pjsBevel; resetTransform; translate(4,4); fillStyle(CSSBrown); strokeStyle(CSSDarkOrange); lineWidth:= 2; beginPath; pawn.CopyToPath(Img.Canvas2d); translate(50,0); scale(0.5,0.5); pawn.CopyToPath(Img.Canvas2d); strokeOverFill; resetTransform; translate(4,84); fillStyle(CSSGold); strokeStyle(CSSDarkOrange); lineWidth:= 3; beginPath; pawn.CopyToPath(Img.Canvas2d); translate(50,0); scale(0.5,0.5); pawn.CopyToPath(Img.Canvas2d); strokeOverFill; end; Img.SaveToFile('bezier.png'); Img.Free; end;
Par-delà nos conceptions du bien et du mal se trouve une prairie. Je te rencontrerai là-bas.
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