Page 1 sur 2

Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 11:46
par falsam
Comment puis je trouver un full (3 nombres identiques + 2 autres identiques) dans un jeu de 6 des avec une expression régulière ?

J'ai une variable qui contient le contenu triés des six dés. Exemple :

Code : Tout sélectionner

Roll = "133355"
Merci de votre aide.

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 13:23
par falsam
On peut le faire sans expression réguliére mais je serais curieux de voir une solution avec expression réguliére

Code : Tout sélectionner

Procedure R0(Roll.s)
  Protected Result, n, p
  For n = 1 To 6
    If FindString(Roll, LSet(Str(n), 3, Str(n)))
      p =  n
      Break
    EndIf
  Next
  
  If p <> 0
    For n = 1 To 6
      If n <> p
        If FindString(Roll, LSet(Str(n), 2, Str(n)))
          Result = #True
        EndIf
      EndIf
    Next
  EndIf
    
  ProcedureReturn Result
EndProcedure

Debug R0("222456") ;#False
Debug R0("222446") ;#True

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 13:29
par Marc56
Pour que ta méthode fonctionne, il faut d'abord trier la chaine, car:

Debug R0("232321") est un full, mais n'est pas reconnu :?

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 13:32
par falsam
Je suis d'accord et c'est ce que j'ai spécifié dans mon premier message :)
falsam a écrit :J'ai une variable qui contient le contenu triés des six dés

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 13:39
par Marc56
Ooops, désolé :oops:
(mes (rares) neurones sont endormis par la digestion :mrgreen: )

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 15:16
par falsam
Marc56 a écrit :Ooops, désolé :oops:
Non non au contraire. Une petite procédure pour trier un string. J'en ai besoin pour mon jeu de des :)

Code : Tout sélectionner

Procedure.s SortString(Buffer.s)
  Protected Dim ArrayBuffer.s(0)
  Protected l = Len(Buffer)-1
  Protected n
    
  ReDim ArrayBuffer(l)
  
  For n = 0 To l
    ArrayBuffer(n) = Mid(Buffer, n+1, 1)
  Next
  
  SortArray(ArrayBuffer(), #PB_Sort_Ascending)
  
  Buffer = ""
  For n = 0 To l
    Buffer + ArrayBuffer(n)
  Next
  
  ProcedureReturn Buffer
  
EndProcedure

Debug SortString("126215")

Re: Expression Réguliere : Trouver un full

Publié : jeu. 26/févr./2015 16:28
par Marc56
D’instinct, j'aurais fait ça avec une liste (en mettant une lettre dans chaque élément) et Sortlist(), mais c'est vrai que c'est plus court avec sortarray()
:D

Re: Expression Réguliere : Trouver un full

Publié : ven. 27/févr./2015 14:23
par Marc56
Rahhh, elle m'a donné du fil à retordre cette RegEx pour trouver un full,
pourtant c'était simple :P il suffisait d'utiliser les références arrières.

La référence arrière reprend le groupe précédent trouvé ()
Elle s'écrit \1 \2 \3 et car elle est dans l'expression elle-même
contrairement aux $1 $2 $3 etc qui s'utilisent en dehors de l'expression.

Donc pour le jeu de dés

([0-6])\1\1([0-6])\2

En clair (pour les lecteurs qui n'ont jamais fait d'expression régulière)
[0-6] = 1 chiffre entre 0 et 6
([0-6]) = conserver ce résultat
\1 = le résultat trouvé avant
\1\1 = utiliser le résultat 2 fois de suite (donc 3 avec le début)
puis ensuite on recommence
mais la référence arrière devient le résultat du deuxième groupe de parenthèses
(je sais pas si je m'explique bien :oops: )



Ça c'est si tu veux juste la version 3 puis 2

Code : Tout sélectionner

If CreateRegularExpression(0, "([0-6])\1\1([0-6])\2")
	Debug MatchRegularExpression(0, "133355")
Else
	Debug RegularExpressionError()
EndIf
Si tu veux traiter 3 puis 2 ou 2 puis 3

([0-6])\1\1([0-6])\2|([0-6])\3([0-6])\4\4

Là c'est pareil, sauf qu'on traite les deux cas avec un ou |
et on utilise les groupes 3 et 4

Le problème est que cette expr prend aussi un carré, donc le plus simple est de la faire précéder par une autre qui recherche ce carré

([0-6])\1\1\1

De plus, comme les RegEx ne font pas la différence entre chiffre ou lettre si on utilisait des cartes et non pas des dés on peut inclure les figures

[0-9VDR] (0 remplaçant 10) ou alors prendre les codes officiels [A1-9TVJDQRK]

:wink:

Re: Expression Réguliere : Trouver un full

Publié : ven. 27/févr./2015 19:19
par Kwai chang caine
Merci pour l'explication détaillée..
C'est vraiment un grand malade le mec qu'a inventé les regex :?

Re: Expression Réguliere : Trouver un full

Publié : ven. 27/févr./2015 23:02
par falsam
Merci Marc :)

J'ai adopté ce Regex "([0-6])\1\1([0-6])\2|([0-6])\3([0-6])\4\4" qui à toutes les positions du full à l'intérieur de la chaine.
Marc56 a écrit :Le problème est que cette expr prend aussi un carré, donc le plus simple est de la faire précéder par une autre qui recherche ce carré
Dans ma structure de test, le full est testé en premier avant de passé au carré, brelan, etc ...

Est ce un jeu de poker ? non ce n'est pas le cas d'autant plus que j'utilise des dés. Un Yams (Yahtzee) ? non plus :)

Re: Expression Réguliere : Trouver un full

Publié : ven. 10/juil./2015 17:30
par Ar-S
Sujet bien intéressant
Dans mon jeu qui comprend 5 dès je dois aussi detecter un Full.
Les regex testé ne marchent pas dans tous les sens. J'ai tenté ce regex

Code : Tout sélectionner

"([0-6])\1\1([0-6])\1|([0-6])\1([0-6])\1\1"
il est bien senser vouloir dire : 2 identiques 3 identiques OU 3 identiques 2 identiques non ?

Je suis passé par une liste pour trier (elle fonctionne)

Code : Tout sélectionner

Procedure.s SortString(Buffer.s)
  Protected NewList Buffer.s()
  
  ResetList( buffer() )
  
  For i = 0 To 4
    AddElement (buffer())
    buffer() = Mid(Buffer, i+1, 1)
  Next
 
  SortList(buffer(),#PB_Sort_Ascending)
 
  Buffer = ""
  ForEach Buffer()
    Buffer + Buffer()
  Next

  ProcedureReturn Buffer
 
EndProcedure

Debug SortString("13313")

Re: Expression Réguliere : Trouver un full

Publié : ven. 10/juil./2015 17:50
par falsam
J'ai renoncé au regex et comme toi je suis aussi passé au tri d'un string avant de détecter mon full

http://www.purebasic.fr/french/viewtopi ... 49#p170749

Re: Expression Réguliere : Trouver un full

Publié : ven. 10/juil./2015 17:53
par Ar-S
J'ai fait cette proce qui va bien pour mes 5 dés...
Roots mais fonctionnelle

Code : Tout sélectionner


Procedure.s SortString(Buffer.s)
  Protected NewList Buffer.s()
  
  ResetList( buffer() )
  
  For i = 0 To 4
    AddElement (buffer())
    buffer() = Mid(Buffer, i, 1)
  Next
 
  SortList(buffer(),#PB_Sort_Ascending)
 
  Buffer = ""
  ForEach Buffer()
    Buffer + Buffer()
  Next
  
  Debug "Buffer : " + buffer
  ProcedureReturn Buffer
 
EndProcedure


Procedure CheckFull(t.s)
  Protected.s a,b,c,d,e
  
  a.s = Left(t,1)
  b.s = Mid(t,2,1)
  c.s = Mid(t,3,1)
  d.s = Mid(t,4,1)
  e.s = Right(t,1)
  
  If a = b And a = c And d = e And a <> e
      ProcedureReturn 1
  ElseIf a = b And c = d And c = e And a <> e
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
 
EndProcedure

Re: Expression Réguliere : Trouver un full

Publié : ven. 10/juil./2015 17:54
par falsam
Les vacances commençant, j'espére que tu sortiras ton jeu rapidement :wink:

Au fait quel jeu ?

Re: Expression Réguliere : Trouver un full

Publié : ven. 10/juil./2015 18:11
par SPH
Kwai chang caine a écrit :C'est vraiment un grand malade le mec qu'a inventé les regex :?
Je suis daccord avec ce brave KCC 8)