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. #121
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Hello,

    Généralement dans ce type d'application, il existe un thread principal qui "écoute" les requêtes et qui est en fait une boucle quasiment infinie (jusqu'à ce qu'on arrive à la condition qui la casse, par exemple la fin du programme). Une fois la requête reçu, le thread principal crée un nouveau thread qui gère la communication avec le programme appelant (c'est ainsi pour les serveurs réseau, où le socket est passé au nouveau thread) et qui traite la requête et retourne le résultat au programme appelant. Le nouveau thread se termine ainsi automatiquement et se "supprime" automatiquement lorsqu'il est terminé, c'est-à-dire qu'il libère toutes ses ressources mémoire (dont le socket, si il s'agit de réseau).

    Ton approche était donc bonne !
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  2. #122
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Merci pour la réponse et pour les indications utiles qu'elle contient.

    Voici un premier essai qui répond partiellement au problème : le programme lance un thread qu'on arrête en tapant "stop" dans la console. Il manque, me semble-t-il, de pouvoir choisir la procédure ou la fonction, lui passer des arguments et récupérer la valeur de retour.

    Le programme paraît bien fonctionner, sauf que si je laisse le compteur aller jusqu'à la fin, la console ne se ferme pas.

    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
     
    program EtudeThread;
     
    {$APPTYPE CONSOLE}
     
    (* Compilation testée : Free Pascal 2.6.4, Delphi 7, Delphi XE2. *)
     
    uses
      Windows, Messages, SysUtils, Classes;
     
    type
      TMonThread = class(TThread)
      private
        i: integer;
      protected
        procedure Execute; override;
        procedure MaProcedure;
      end;
     
    procedure TMonThread.MaProcedure;
    begin
      SetConsoleTitle(PChar(IntToStr(i)));
      Sleep(10);
    end;
     
    procedure TMonThread.Execute;
    begin
      i := 0;
      while (i < 3000) and not Terminated do
      begin
         MaProcedure;
         Inc(i);
      end;
    end;
     
    var
      t: TMonThread;
      s: string;
     
    begin
      t := TMonThread.Create(True);
      t.FreeOnTerminate := True;
      t.Priority := tpNormal;
      {$IFDEF FPC}
      t.Start;
      {$ENDIF}
      {$IFDEF VER150}
      t.Resume;
      {$ENDIF}
      {$IFDEF VER230}
      t.Start;
      {$ENDIF}
     
      MessageBox(
        0,
        'Pour interrompre l''exécution du thread, tapez "stop" et appuyez sur la touche Entrée.',
        '',
        MB_OK
      );
     
      s := '';
     
      while (s <> 'stop') and not EOF do
      begin
        ReadLn(s);
        if (s = 'stop') then
        begin
          if Assigned(t) then
            t.Terminate;
        end else
          WriteLn(s);
      end;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  3. #123
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Hum je pense que la structure de ton programme n'est pas bonne. Si tu veux faire le même comportement que décrit précédemment, il faut que tu crées un thread à chaque fois que tu reçois une commande, c'est-à-dire après le Readln dans la boucle principale. Tu peux passer la variable récupérée par un paramètre d'un constructeur Create que tu aurais surchargé. Comme le thread est FreeOnTerminate, tu n'as pas à te soucier de libérer la mémoire.

    J'ai un peu modifié ton code, pas sûr qu'il marche du premier coup. De plus je ne gère pas ici le fait qu'il puisse y avoir plusieurs threads concurrent, car il n'y qu'un seule variable t. On passe généralement par un tableau, avec gestion des cases vides, etc....

    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
    type
      TMonThread = class(TThread)
      private
        s: String;
      protected
        constructor Create(CreateSuspended: Boolean; Command: String);
        procedure Execute; override;
      end;
     
    constructor TMonThreadCreate(CreateSuspended: Boolean; Command: String);
    begin
      inherited Create(CreateSuspended);
      s := Command;
    end;
     
    procedure TMonThread.Execute;
    begin
      SetConsoleTitle(PChar(s));
    end;
     
    var
      t: TMonThread;
      s: string;
     
    begin
      MessageBox(
        0,
        'Pour interrompre l''exécution du thread, tapez "stop" et appuyez sur la touche Entrée.',
        '',
        MB_OK
      );
     
      s := '';
     
      while (s <> 'stop') and not EOF do
      begin
        ReadLn(s);
        if (s = 'stop') then
          break;
        else begin
          t := TMonThread.Create(True, s);
          t.FreeOnTerminate := True;
          t.Priority := tpNormal;
          {$IFDEF FPC}
          t.Start;
          {$ENDIF}
          {$IFDEF VER150}
          t.Resume;
          {$ENDIF}
          {$IFDEF VER230}
          t.Start;
          {$ENDIF}
        end;
      end;
    end.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  4. #124
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Merci pour l'exemple et les explications.

    J'ai complété l'exemple sans y faire aucune modification essentielle. Je crois que tel qu'il est il contient déjà tout ce qu'il faut. Je ne pense avoir besoin de plusieurs threads à la fois : la seule fonction qui me semble mériter un thread, c'est la recherche du meilleur coup (commande 'go'); le reste (réglages des options, chargement de la position) est instantané.

    Peut-être il faudrait une fonction qui signale si la procédure qui s'exécute dans le thread est terminé. J'ai remarqué que la fonction Assigned renvoie toujours TRUE, même quand la procédure est terminée et le thread libéré (d'après moi).

    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
     
    program EtudeThread3;
     
    {$APPTYPE CONSOLE}
     
    (* Compilation testée : Free Pascal 2.6.4. *)
     
    uses
      Windows, Messages, SysUtils, Classes;
     
    function CaseOfString(s: string; a: array of string): integer;
    begin
      result := 0;
      while (result < Length(a)) and (Pos(a[result], s) <> 1) do
        Inc(result);
      if Pos(a[result], s) <> 1 then
        result := -1;
    end;
     
    type
      TMonThread = class(TThread)
        private
          fCommand: string;
          fResult: string;
        protected
          procedure Execute; override;
        public
          constructor Create(CreateSuspended: Boolean; Command: string);
      end;
     
    constructor TMonThread.Create(CreateSuspended: Boolean; Command: string);
    begin
      inherited Create(CreateSuspended);
      fCommand := Command;
      fResult := '';
    end;
     
    procedure TMonThread.Execute;
    var
      i: integer;
    begin
      i := 0;
      while (not Terminated) and (i < 10000) do
      begin
        fResult := IntToStr(i);
        Sleep(20);
        Inc(i);
      end;
    end;
     
    const
      UCI_COMMANDS: array[0..7] of string = (
        'go',
        'isready',
        'position',
        'quit',
        'setoption',
        'stop',
        'uci',
        'ucinewgame'
      );
     
    var
      t: TMonThread;
      s: string;
     
    begin
      while not EOF do
      begin
        ReadLn(s);
        case CaseOfString(s, UCI_COMMANDS) of
          0: // go
            begin
              t := TMonThread.Create(True, s);
              t.FreeOnTerminate := True;
              t.Priority := tpNormal;
              t.Start;
            end;
          1: // isready
            begin
              WriteLn('isready');
            end;
          2: // position
            begin
              WriteLn('position');
            end;
          3: // quit
            begin
              Break;
            end;
          4: // setoption
            begin
              WriteLn('setoption');
            end;
          5: // stop
            begin
              if Assigned(t) then
                t.Terminate;
              WriteLn(t.fResult);
            end;
          6: // uci
            begin
              WriteLn('uciok');
            end;
          7: // ucinewgame
            begin
              WriteLn('ucinewgame');
            end;
        end;
      end;
    end.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  5. #125
    Rédacteur/Modérateur
    Avatar de M.Dlb
    Inscrit en
    Avril 2002
    Messages
    2 464
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 464
    Points : 4 311
    Points
    4 311
    Par défaut
    Et si l'utilisateur entre 2 fois, de façon très rapprochée, la commande "go" ? Le premier thread risque de ne pas être terminé et la variable t va être écrasée. D'où la gestion des threads par un mécanisme complémentaire (tableau ou allocation dynamique). On peut vérifier si un thread est terminé, avec la propriété Terminated. Pas sûr que le FreeOnTerminate mette la variable à Nil, donc Assigned() renverra True tout le temps (à vérifier) - pas évident que FreeOnTerminate soit adéquat dans ton cas, surtout si tu veux faire des tests après la fin du thread.
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  6. #126
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    @M.Dlb

    Merci pour ces remarques judicieuses.

    Concernant la commande go, je crois que c'est à l'utilisateur d'utiliser les commandes isready ou stop, pour s'assurer que la recherche du meilleur coup est terminée ou pour l'interrompre. Donc il me semble qu'un seul thread suffit, avec les modifications suivantes :

    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
          0: // go
            begin
              if (not Assigned(t)) or t.Terminated then
              begin
                t := TMonThread.Create(True, s);
                t.FreeOnTerminate := True;
                t.Priority := tpNormal;
                t.Start;
              end;
            end;
          1: // isready
            begin
              if (not Assigned(t)) or t.Terminated then
                WriteLn('readyok');
            end;
    Effectivement, Assigned() renvoie toujours TRUE. Libération et valeur nil sont donc deux choses différentes : merci d'avoir attiré mon attention sur ce point.

    Maintenant pour compléter le programme il faudrait que je traite les paramètres des commandes go, position, et setoption. Après quoi j'aurai tout ce qu'il faut pour bricoler un moteur UCI.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  7. #127
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Bonjour ! J'aimerais vous présenter la dernière version de mon jeu d'échecs pour le compilateur Free Basic. Il est presque identique à celui que j'ai fait en Pascal, sauf l'interface qui est plus achevée. Je me suis engagé dans une impasse en utilisant l'unité WinGraph pour l'interface de mon jeu en Pascal. J'ai en tête de continuer le projet avec fpGUI (quitte à renoncer à la compilation Delphi), mais cela suppose que je refasse le code pour le mouvement des pièces, dont j'étais pourtant content.

    Eschecs
    Images attachées Images attachées  
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  8. #128
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    [...] l'interface qui est plus achevée. [...]
    Très jolie !
    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

  9. #129
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Merci pour ton appréciation, Jipété.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  10. #130
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    La dernière version du programme n'est plus disponible à l'adresse que j'ai donnée plus haut. L'administrateur du site (qui est un ami) a dû la supprimer suite à un signalement d'un antivirus (à cause, si mes déductions sont exactes, d'un méchant ShellExecute() que j'ai inclus dans mon programme). Donc, si vous souhaitez télécharger le jeu, merci d'aller sur mon site personnel : [lien supprimé]
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  11. #131
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    La dernière version du programme n'est plus disponible à l'adresse que j'ai donnée plus haut. L'administrateur du site (qui est un ami) a dû la supprimer suite à un signalement d'un antivirus (à cause, si mes déductions sont exactes, d'un méchant ShellExecute() que j'ai inclus dans mon programme).
    Bon ben tant mieux, c'est un mal pour un bien car j'avais téléchargé hier et l'exe ne fonctionnait pas : pas de messages, mais rien qui se passait en double-cliquant dans une machine XP SP2.

    Avec ce nouveau zip et en lançant start.exe c'est beaucoup mieux ! D'ailleurs le zip est plus lourd et il y a beaucoup plus de fichiers dedans.


    Bon, je l'ai mis minable en une vingtaine de coups, et pourtant je ne suis pas un cador, mais le moteur ne m'a pas vu venir et est resté en mode agressif et attaquant alors que j'avais un coup d'avance...

    Tiens, regarde : je venais de bouger mon cavalier de f2 en g5, il a enfermé sa reine en e4xc2 ? tout ce que j'ai eu à faire a été de remonter mon cavalier en f7++

    Nom : chess.jpg
Affichages : 231
Taille : 62,4 Ko

    Deux remarques :
    - au démarrage ça m'a écrit en bas "Trait au blanc", il me semble que ça se met au pluriel, "Trait aux blancs" non ?
    - un truc cool serait (si c'est possible) de rajouter la notation a,b,c... 1,2,3... sur les côtés.

    Merci pour le jeu, ça m'a fait passer 10 minutes, allez, j'ai un script Linux qui m'attend
    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

  12. #132
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Merci Jipété pour l'essai et le compte-rendu.

    Effectivement, le moteur n'est pas très fort. Comme tu l'as noté, son analyse manque de profondeur. C'est pourquoi il joue instantanément. L'exploration de l'arbre de jeu se fait au moyen d'une fonction récursive, de sorte qu'on ne peut pas trop augmenter la profondeur.

    Bien noté tes suggestions. Pour retrouver les coups joués, tu peux consulter le fichier eschecs-log.txt qui est créé à chaque exécution du programme. Pour le coup du cavalier, je pense que c'était plutôt f3g5.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  13. #133
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Citation Envoyé par Roland Chastain Voir le message
    Pour retrouver les coups joués, tu peux consulter le fichier eschecs-log.txt qui est créé à chaque exécution du programme.
    Vu, merci !
    Du coup c'est en 15 coups que je l'ai eu

    Citation Envoyé par Roland Chastain Voir le message
    Pour le coup du cavalier, je pense que c'était plutôt f3g5.
    Oopsss
    Et grâce à ton fichier de log, c'était même plutôt f3e5 !
    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

  14. #134
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut Essai BGRABitmap
    @Jipété

    Merci pour tes essais.

    J'ai fait une première tentative de mouvement d'une pièce sur un échiquier avec Lazarus et BGRABitmap. Mon programme explose en cours de route. Pourriez-vous me dire ce qui ne va pas ?
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  15. #135
    Membre confirmé

    Profil pro
    Inscrit en
    Juillet 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2009
    Messages : 140
    Points : 623
    Points
    623
    Par défaut
    Dans la procedure FormPaint, il y a trois choses:
    - GetPart alloue de la memoire, donc il faut remplacer l'objet precedent avec BGRAReplace
    - au cas ou la sauvegarde n'est pas definie, il faut tester Assigned() avant d'appeler Draw
    - rect() prend pour parametre (left,top,right,bottom), ce n'est pas la taille qui est en parametre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      if dame.x = 0 then
      begin
        damier.Draw(Canvas, 0, 0);
        BGRAReplace(dame.sauvegarde, damier.GetPart(rect(dame.x, 0, dame.x+40, 40)));
        dame.image.Draw(Canvas, dame.x, 0, FALSE);
      end else
      begin
        if Assigned(dame.sauvegarde) then dame.sauvegarde.Draw(Canvas, dame.x - STEP, 0);
        BGRAReplace(dame.Sauvegarde, damier.GetPart(rect(dame.x, 0, dame.x+40, 40)));
        dame.image.Draw(Canvas, dame.x, 0, FALSE);
      end;
    end;
    Cela dit, il est recommande d'allouer un ecran virtuel plutot que d'avoir une sauvegarde du dessous de la piece, et de redessiner tout l'echiquier (on peut acceler cela en faisant un Invalidate de la zone qui change).
    Par-delà nos conceptions du bien et du mal se trouve une prairie. Je te rencontrerai là-bas.

  16. #136
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    @circular17

    Merci beaucoup pour la réponse.

    Effectivement, comme ça, ça fonctionne, même si le résultat n'est pas très satisfaisant (même en augmentant la valeur du pas, et en diminuant la valeur de Timer1.Interval). Je vais tester la solution de l'écran virtuel.
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  17. #137
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Salut,
    Citation Envoyé par Roland Chastain Voir le message
    Effectivement, comme ça, ça fonctionne, même si le résultat n'est pas très satisfaisant (même en augmentant la valeur du pas, et en diminuant la valeur de Timer1.Interval). Je vais tester la solution de l'écran virtuel.
    Après avoir d'abord appliqué les corrections de circular17 sans me poser de questions, j'ai pu constater qu'il fallait modifier le début de Form.Create sous Linux, sinon gros pâté
    J'ai rajouté "chemin" et son utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    procedure TForm1.FormCreate(Sender: TObject);
    var
      chemin: string;
    begin
      chemin := ExtractFilePath(Application.ExeName);
      damier := TBGRABitmap.Create(chemin+'/board.bmp');
      dame.image := TBGRABitmap.Create(chemin+'/bq.bmp');
    Et après avoir passé l'interval du timer à seulement 10 ou 5, le déplacement est sympathique.

    Courage pour la suite...
    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

  18. #138
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Bonjour Jipété (et les autres) !

    Oui, tu as raison à propos du chemin.

    Citation Envoyé par Jipété Voir le message
    Et après avoir passé l'interval du timer à seulement 10 ou 5, le déplacement est sympathique.
    Au temps pour moi ! J'avais laissé la valeur 100 dans le code et je la changeais dans l'inspecteur d'objet. Forcément, je ne voyais pas la différence.

    Avec l'intervalle à 10 et le pas à 8, oui comme tu le dis ça donne un résultat correct. Mais j'ai quand même essayé la solution de l'écran virtuel. Je ne sais pas trop si je l'ai fait comme il faut mais ça fonctionne et il me semble que le résultat est effectivement meilleur.

    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
    unit Unit1;
     
    {$MODE objfpc}{$H+}
     
    interface
     
    uses
      Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
      BGRABitmap, BGRABitmapTypes;
     
    type
      TImageMobile = record
        image, sauvegarde: TBGRABitmap;
        x: integer;
      end;
     
    type
      { TForm1 }
      TForm1 = class(TForm)
        Timer1: TTimer;
        procedure FormCreate(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
        procedure FormPaint(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { private declarations }
        damier: TBGRABitmap;
        dame: TImageMobile;
        virtualscreen: TBitmap;
      public
        { public declarations }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.lfm}
     
    { TForm1 }
     
    const
      STEP = 8;
     
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      damier := TBGRABitmap.Create('board.bmp');
      dame.image := TBGRABitmap.Create('bq.bmp');
      dame.sauvegarde := TBGRABitmap.Create(40, 40);
      dame.x := 0;
     
      dame.image.ReplaceColor(CSSMidnightBlue, BGRAPixelTransparent);
     
      virtualscreen := TBitmap.Create;
      virtualscreen.Width := 8 * 40;
      virtualscreen.Height := 8 * 40;
     
      Timer1.Interval := 10;
      Timer1.Enabled := FALSE;
    end;
     
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      damier.Free;
      dame.image.Free;
      dame.sauvegarde.Free;
      virtualscreen.Free;
    end;
     
    procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    begin
      if (dame.x = 0) and not Timer1.Enabled then
        Timer1.Enabled := TRUE
      else
        Close;
    end;
     
    procedure TForm1.FormPaint(Sender: TObject);
    begin
      if dame.x = 0 then
      begin
        damier.Draw(virtualscreen.Canvas, 0, 0);
      end else
      begin
        if Assigned(dame.sauvegarde) then
          dame.sauvegarde.Draw(virtualscreen.Canvas, dame.x - STEP, 0);
      end;
      BGRAReplace(dame.Sauvegarde, damier.GetPart(rect(dame.x, 0, dame.x + 40, 40)));
      dame.image.Draw(virtualscreen.Canvas, dame.x, 0, FALSE);
      Canvas.Draw(0, 0, virtualscreen);
    end;
     
    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
      Inc(dame.x, STEP);
      if dame.x > 7 * 40 then
        Timer1.Enabled := FALSE
      else
        OnPaint(nil);
    end;
     
    end.
    Testé avec la nouvelle version de BGRABitmap (8.5).
    Mon site personnel consacré à MSEide+MSEgui : msegui.net

  19. #139
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 729
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 729
    Points : 15 133
    Points
    15 133
    Par défaut
    Salut Roland et les autres

    Citation Envoyé par Roland Chastain Voir le message
    Oui, tu as raison à propos du chemin.
    On peut même faire encore plus fort : compilation conditionnelle, et en plus j'économise une instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {$IFDEF FPC}
    procedure TForm1.FormCreate(Sender: TObject);
    var
      chemin: string;
    begin
      chemin := ExtractFilePath(Application.ExeName) + '/';
      damier := TBGRABitmap.Create(chemin+'board.bmp');
      dame.image := TBGRABitmap.Create(chemin+'bq.bmp');
    {$ELSE}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      damier := TBGRABitmap.Create('board.bmp');
      dame.image := TBGRABitmap.Create('bq.bmp');
    {$ENDIF}

    Citation Envoyé par Roland Chastain Voir le message
    Au temps pour moi ! J'avais laissé la valeur 100 dans le code et je la changeais dans l'inspecteur d'objet. Forcément, je ne voyais pas la différence.

    La crise de rire du petit matin !
    Ah, c'est bon de rire

    Citation Envoyé par Roland Chastain Voir le message
    Mais j'ai quand même essayé la solution de l'écran virtuel. Je ne sais pas trop si je l'ai fait comme il faut mais ça fonctionne et il me semble que le résultat est effectivement meilleur.
    Pas noté de différence. C'est censé amener quoi, cette solution de l'écran virtuel ?

    Citation Envoyé par Roland Chastain Voir le message
    Testé avec la nouvelle version de BGRABitmap (8.5).
    Fonctionne également avec ma "vieille" 7.2


    Citation Envoyé par Roland Chastain Voir le message
    A noter : j'ai compilé le projet ci-joint avec le paquet bgrabitmappack4fpgui.lpk, qui est inclus dans la nouvelle version de BGRABitmap.
    Un peu la flemme de mettre à jour ("on ne change pas une équipe qui gagne", et j'ai autre chose sur le gaz en ce moment), je ne vais pas suivre cette voie, pour le moment.

    Bon 1er mai,
    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

  20. #140
    Rédacteur/Modérateur

    Avatar de Roland Chastain
    Homme Profil pro
    Enseignant
    Inscrit en
    Décembre 2011
    Messages
    4 072
    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 072
    Points : 15 462
    Points
    15 462
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Pas noté de différence. C'est censé amener quoi, cette solution de l'écran virtuel ?
    J'ai eu l'impression que le rendu était plus net, mais c'était peut-être dans ma tête.

    Bonne fête à toi également !
    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