IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Pascal Discussion :

Projet d'un programme de jeu d'échecs


Sujet :

Contribuez Pascal

  1. #21
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par droggo Voir le message
    La faute est 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 Commande(trt:Boolean;var cmnd:String);
    	const nomProg:String='ESCHECS';
    	var couleur:String;OK:Boolean;lst:TListe;cp:TCoup;valab:Boolean;
    	begin
    		OK:=False;
    		while OK=False do
    		begin
    			GotoXY(2,23);
    			Write(nomProg,'>');
    			if trt=False then couleur:='BLANC' else couleur:='NOIR';
    			Write(couleur,'>'); ClrEol; ReadLn(cmnd);
    			Assign(lst,NomDossier+'LISTE3');
     
    			Reset(lst); { ICI, ouvert, et pas fermé }
     
    			valab:=False;
    			while not Eof(lst) do
    			begin
    				Read(lst,cp);
    				if cmnd=cp then valab:=True;
    			end;
    			OK:=valab;
    			if cmnd='exit'then OK:=True;
    		end;
    	end;
    Je suis bien content d'être débarrassé de cette erreur.

    Merci d'avoir pris le temps de regarder et de commenter.

    Je vais faire un effort sur la présentation.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  2. #22
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    Gie,
    Citation Envoyé par Roland Chastain Voir le message
    Je vais faire un effort sur la présentation.
    Je l'espère pour toi, c'est plus important qu'on ne le pense a priori.
    Si les cons volaient, il ferait nuit à midi.

  3. #23
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    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 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    CheminFichiers : String = 'c:\Atelier\PAS\TEMP\' ;
    {****************** A 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 ?
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  4. #24
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    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).

    Si les cons volaient, il ferait nuit à midi.

  5. #25
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par droggo Voir le message
    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).
    Merci pour ta réponse. J'ai remis mon ouvrage sur le métier.

    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  6. #26
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    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.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  7. #27
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    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.

    Si les cons volaient, il ferait nuit à midi.

  8. #28
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par droggo Voir le message
    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.
    Oui et oui !

    J'avais déjà fait la première modification. Merci de m'avoir fait penser à la seconde. Il me semble que c'est nettement mieux comme ça. Je garde !
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  9. #29
    Membre chevronné

    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2009
    Messages
    935
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2009
    Messages : 935
    Points : 1 765
    Points
    1 765
    Par défaut
    Salut

    Pour répondre à :
    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 ?
    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)

    Peut tu m'expliquer ton astuce du tableau de constantes ?
    Je me suis servi, entre autres choses, de tableaux de constantes pour indiquer à chaque pièce les "bonnes" cases :
    J'avous être intrigué par ta technique ^^.

    Bonne chance

  10. #30
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par mick605 Voir le message
    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)
    Merci pour ta réponse. Je vais essayer d'écrire avec Free Pascal et de repérer les différences en question.

    Citation Envoyé par mick605 Voir le message
    Peut tu m'expliquer ton astuce du tableau de constantes ?
    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 !
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  11. #31
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    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.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  12. #32
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut Erreur 202
    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;
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  13. #33
    Responsable Pascal, Lazarus et Assembleur


    Avatar de Alcatîz
    Homme Profil pro
    Ressources humaines
    Inscrit en
    Mars 2003
    Messages
    7 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ressources humaines
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2003
    Messages : 7 937
    Points : 59 416
    Points
    59 416
    Billets dans le blog
    2
    Par défaut
    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

    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]

  14. #34
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Merci pour ta réponse et pour le lien. Je vais creuser de ce côté-là.

    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  15. #35
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut Erreur 202 (suite)
    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 :

    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.
    Si je comprends bien : beaucoup de passages explicites, beaucoup de copies. Beaucoup de copies, débordement de la pile !

    Sur le passage d'un paramètre comme constante, j'ai cru comprendre que Turbo Pascal ne le permettait pas :

    Remarque : Turbo Pascal ne supporte que la transmission par valeur et par adresse.
    Comme je n'étais pas sûr d'avoir bien compris, j'ai quand même essayé cette écriture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Function Exemple (const a: byte): byte;
    Le compilateur l'accepte, mais je ne sais pas si cela change quelque chose.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  16. #36
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    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
    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;
    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.

    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.

    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;
    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
    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;
    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
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  17. #37
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut Erreur 202 (suite)
    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 !

    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  18. #38
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut Echiquier
    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 :

    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);
    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.
    Images attachées Images attachées  
    Fichiers attachés Fichiers attachés
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  19. #39
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    voici deux petites remarques rapides

    1) pour compiler le projet sous Delphi il suffit de faire ceci

    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}
    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
    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;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  20. #40
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 4 070
    Points : 15 454
    Points
    15 454
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    1) pour compiler le projet sous Delphi il suffit de faire ceci
    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 :

    [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'
    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"...

    Citation Envoyé par Paul TOTH Voir le message
    2) je pense que "fictif" correspond à ma remarque
    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.

    Mon site personnel consacré à MSEide+MSEgui : msegui.net

Discussions similaires

  1. [Flash Pascal] Projet d'un programme permettant de visualiser une position du jeu des échecs
    Par Roland Chastain dans le forum Flash Pascal
    Réponses: 11
    Dernier message: 21/06/2015, 09h05
  2. Projet Jeu d'échec
    Par Layla dans le forum Langage
    Réponses: 10
    Dernier message: 23/12/2010, 13h06
  3. Jeu d'échec borland soap
    Par rpoulin dans le forum Web & réseau
    Réponses: 2
    Dernier message: 20/10/2005, 05h02
  4. Help ! Programmer un jeu vidéo
    Par Jay Bee dans le forum DirectX
    Réponses: 7
    Dernier message: 18/03/2004, 18h38
  5. Help ! Programmer un jeu vidéo...
    Par Jay Bee dans le forum OpenGL
    Réponses: 3
    Dernier message: 05/03/2004, 15h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo