Developpez.com

Une très vaste base de connaissances en informatique avec
plus de 100 FAQ et 10 000 réponses à vos questions

Puissance 4 basé sur l'API Windows et la bibliothèque Cairo

Présentation
"Puissance 4" pour Windows.

L'interface graphique est une application Windows faisant directement appel à l'API. La bibliothèque Cairo est utilisée pour le dessin des pions.

L'adversaire artificiel, qui n'est pas très fort, mais joue décemment, utilise les expressions régulières pour une évaluation immédiate de la position après son coup.

Un seul mode de jeu est disponible : humain contre ordinateur. L'humain joue le premier.
Téléchargement
Compatibilité
Windows
0  0 
Téléchargé 8 fois Voir les 3 commentaires
Détails
Catégories : Free Pascal
Avatar de Roland Chastain
Rédacteur / Modérateur
Voir tous les téléchargements de l'auteur
Licence : Autre
Date de mise en ligne : 6 avril 2017




Avatar de Alcatîz Alcatîz - Responsable Pascal, Delphi et Assembleur https://www.developpez.com
le 08/04/2017 à 16:32
Bonjour,

Bravo, le jeu a un niveau tout-à-fait correct et tourne très bien.
Et ça fait du bien (à moi, en tout cas) de revoir une structure de programme Windows "classique".

L'adversaire artificiel [...] utilise les expressions régulières pour une évaluation immédiate de la position après son coup
J'avoue avoir un peu de mal à comprendre l'utilisation des expressions régulières dans le cas présent, aurais-tu l'amabilité d'en expliquer le principe ?
Avatar de Roland Chastain Roland Chastain - Rédacteur/Modérateur https://www.developpez.com
le 08/04/2017 à 19:31
Citation Envoyé par Alcatîz Voir le message
Bravo, le jeu a un niveau tout-à-fait correct et tourne très bien.
Merci. Pour le niveau de jeu, je crois qu'il est encore un peu meilleur avec cette modification, que je ferai dans la prochaine mise à jour.

Citation Envoyé par Alcatîz Voir le message
J'avoue avoir un peu de mal à comprendre l'utilisation des expressions régulières dans le cas présent, aurais-tu l'amabilité d'en expliquer le principe ?
En fait, ça ne sert à rien.

J'avais eu l'idée d'extraire toutes les lignes intéressantes (c'est-à-dire longues d'au moins quatre caractères, car ma grille est un tableau de caractères) sous la forme de chaînes, pour pouvoir ensuite les évaluer à mon aise. J'ai écrit une fonction qui détecte dans ces chaînes des motifs et leur attribue un certain nombre de points :

Code : Sélectionner tout
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
function Evaluer1(const aGrille: TGrillePuissance4; const aJoueur: boolean): integer;
type
  TMotif = record
    motif: ansistring;
    valeur: integer;
  end;
const
  MOTIFS: array[1..10] of TMotif = (
    (motif: '....'; valeur: 10000),
    (motif: ' ...'; valeur:   100),
    (motif: '. ..'; valeur:   100),
    (motif: '.. .'; valeur:   100),
    (motif: '... '; valeur:   100),
    (motif: '  ..'; valeur:     1),
    (motif: ' . .'; valeur:     1),
    (motif: ' .. '; valeur:     1),
    (motif: '. . '; valeur:     1),
    (motif: '..  '; valeur:     1)
  );
var
  vExpressionReguliere: TExpressionReguliere;
  vExpression: ansistring;
  vLignes: TLignes;
  iMotif, iLigne: integer;
begin
  result := 0;
  vLignes := Lignes(aGrille);
  for iMotif := Low(MOTIFS) to High(MOTIFS) do
  begin
    vExpression := ansistring(StringReplace(MOTIFS[iMotif].motif, '.', PIONS[aJoueur], [rfReplaceAll]));
    vExpressionReguliere := TExpressionReguliere.Create(vExpression);
    for iLigne := Low(vLignes) to High(vLignes) do
      if vExpressionReguliere.Correspondance(vLignes[iLigne]) then
        Inc(result, MOTIFS[iMotif].valeur);
    vExpressionReguliere.Free;
  end;
end;
Les "." sont remplacés par le caractère correspondant ("X" ou "O") selon le joueur concerné, puis les expressions régulières sont utilisées pour la recherche du motif. C'est seulement hier que j'ai réalisé que la fonction Pos() aurait aussi bien fait l'affaire.

Le seul minuscule avantage (en cherchant bien) des expressions régulières, c'est dans le cas où il y aurait une ligne gagnante de cinq, six ou sept caractères. Les expressions régulières permettent de trouver toutes ces lignes en une seule recherche.

Code : Sélectionner tout
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 Gagnant(const aGrille: TGrillePuissance4; const aJoueur: boolean; out aX1, aY1, aX2, aY2: integer): boolean;
var
  vExpressionReguliere: TExpressionReguliere;
  vLignes: TLignes;
  iLigne: integer;
  vPosition, vLongueur: integer;
  vCoordonnees: TCoordonnees;
begin
  result := FALSE;
  vLignes := Lignes(aGrille);
  vExpressionReguliere := TExpressionReguliere.Create(PIONS[aJoueur] + ansistring('{4,}'));
  iLigne := Low(TLignes);
  while (iLigne <= High(TLignes)) and not result do
    if vExpressionReguliere.Correspondance(vLignes[iLigne], vPosition, vLongueur) then
    begin
      result := TRUE;
      vCoordonnees := Coordonnees(iLigne);
      aX1 := vCoordonnees.x1 + Pred(vPosition) * vCoordonnees.dx;
      aY1 := vCoordonnees.y1 + Pred(vPosition) * vCoordonnees.dy;
      aX2 := aX1 + Pred(vLongueur) * vCoordonnees.dx;
      aY2 := aY1 + Pred(vLongueur) * vCoordonnees.dy;
    end else
      Inc(iLigne);
  vExpressionReguliere.Free;
end;
La fonction renvoie les coordonnées de la ligne gagnante. Du coup, il serait possible de la dessiner mais je n'ai pas encore essayé : je ne suis pas sûr de savoir comment m'y prendre pour dessiner par dessus l'image.
Avatar de Alcatîz Alcatîz - Responsable Pascal, Delphi et Assembleur https://www.developpez.com
le 08/04/2017 à 20:01
Merci pour les explications !
Developpez.com décline toute responsabilité quant à l'utilisation des différents éléments téléchargés.
Responsables bénévoles de la rubrique Pascal : Gilles Vasseur - Alcatîz -