Page 1 sur 1

Le plus ou moins

Publié : mer. 10/avr./2019 17:37
par venom
Bonjour,

Voici un petit "jeux", qui a la particularité d’être très facile a coder. Il s'agit simplement de retrouver un nombre (entier) aléatoire en un minimum de coups. Un classique très connu. Il y a 3 niveaux de difficulté.

Voici le code :

Code : Tout sélectionner

; ///////////////////////////////////////////////
; //      Autor :         Venom                //
; //      Project name :  Plus ou moins        //
; //      Version :       V 1.0                //
; //      Compilator :    PureBasic V5.70      //
; //      Date :          04/04/2019           //
; //      OS :            Windows 10           //
; ///////////////////////////////////////////////


;- Window Constants
Enumeration
  #Window_0
EndEnumeration

;- gadgets Constants
Enumeration
  #Fram_Fourchette
  #ComboBox_Fourchette
  
  #Fram_Button_Demarrer
  #Button_Demarrer
  
  #Fram_Valeur_Du_Joueur
  #String_Valeur_Du_Joueur
  #Button_Valeur_Du_Joueur
  
  #Fram_Affichage_Des_Resultats
  #ListIcon_Affichage_Des_Resultats
EndEnumeration



;- déclarations
Declare Notice()
Declare Fourchette()
Declare Button_Demarrer()
Declare Valeur_Du_Joueur()
Declare Affichage_Des_Resultats()
Declare Valeur_Trouver()
Declare Game()



;- on ouvre la fenetre
  If OpenWindow(#Window_0, 0, 0, 220, 600, "Plus ou moins ", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
   Notice()
   Fourchette()
   Button_Demarrer()
   Valeur_Du_Joueur()
   Affichage_Des_Resultats()
   
   ;- option pour valider avec la touche ENTREE
   AddKeyboardShortcut(#Window_0, #PB_Shortcut_Return, #Button_Valeur_Du_Joueur)
    BindEvent(#PB_Event_Menu,@Game(),#Window_0,#Button_Valeur_Du_Joueur)

  EndIf 
  
;- boucle infini
  Repeat
   EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()
          
        Case #Button_Demarrer
         DisableGadget(#ComboBox_Fourchette, #True) ; desactive le gadget
         DisableGadget(#Button_Demarrer, #True) ; desactive le gadget
         DisableGadget(#String_Valeur_Du_Joueur, #False) ; active le gadget
         DisableGadget(#Button_Valeur_Du_Joueur, #False) ; active le gadget
         
         ;- on regarde la difficulter choisi et on fait un random en fonction
          If GetGadgetState(#ComboBox_Fourchette) = 0
           Global Valeur_A_Trouver = Random(100, 1) ; random entre 1 et 100 
          ElseIf GetGadgetState(#ComboBox_Fourchette)  = 1
           Global Valeur_A_Trouver = Random(1000, 1) ; random entre 1 et 1000 
          ElseIf GetGadgetState(#ComboBox_Fourchette)  = 2
           Global Valeur_A_Trouver = Random(10000, 1) ; random entre 1 et 1000  
          ElseIf GetGadgetState(#ComboBox_Fourchette)  = 3
           Global Valeur_A_Trouver = Random(100000, 1) ; random entre 1 et 1000  
          EndIf 
          ;Debug Valeur_A_Trouver; debug le resultat a trouver

        Case #Button_Valeur_Du_Joueur
         Game() ; on lance la partie

      EndSelect
    EndIf
  Until EventID = #PB_Event_CloseWindow
  
  
  
  
  
Procedure Notice()
MessageRequester("Règles du jeux", "Vous devez retrouvez un nombre aléatoire en un minimum de coups. Bonne chance.", 0)
EndProcedure


Procedure Fourchette()
FrameGadget(#Fram_Fourchette, 10, 10, 200, 55, "Difficulter", 0)
 ComboBoxGadget(#ComboBox_Fourchette, 20, 30, 180, 20, 0) 
  AddGadgetItem(#ComboBox_Fourchette, 0, "Facile : Valeur entre 1 et 100", 0, 0)
  AddGadgetItem(#ComboBox_Fourchette, 1, "Moyen : Valeur entre 1 et 1000", 0, 0)
  AddGadgetItem(#ComboBox_Fourchette, 2, "Difficile : Valeur entre 1 et 10000", 0, 0)
  AddGadgetItem(#ComboBox_Fourchette, 3, "Extreme : Valeur entre 1 et 100000", 0, 0)
  
   SetGadgetState(#ComboBox_Fourchette, 0)
EndProcedure
 

Procedure Button_Demarrer()
FrameGadget(#Fram_Button_Demarrer, 10, 70, 200, 55, "", 0) 
 ButtonGadget(#Button_Demarrer, 20, 90, 180, 20, "Demarrer le jeu", 0)
EndProcedure 


Procedure Valeur_Du_Joueur()
FrameGadget(#Fram_Valeur_Du_Joueur, 10, 130, 200, 55, "Entrez votre valeur puis validez", 0) 
 StringGadget(#String_Valeur_Du_Joueur, 20, 150, 50, 20, "", #PB_String_Numeric)
  DisableGadget(#String_Valeur_Du_Joueur, #True)

ButtonGadget(#Button_Valeur_Du_Joueur, 80, 150, 120, 20, "Validez", 0)
 DisableGadget(#Button_Valeur_Du_Joueur, #True)
EndProcedure


Procedure Affichage_Des_Resultats()
FrameGadget(#Fram_Affichage_Des_Resultats, 10, 190, 200, 400, "Affichage des différentes réponses", 0)
 ListIconGadget(#ListIcon_Affichage_Des_Resultats, 20, 210, 180, 370, "Résultats", 176, #PB_ListIcon_GridLines|#PB_ListIcon_AlwaysShowSelection)
EndProcedure


;- procedure qui affiche un message quand nous avons trouver la bonne valeur
Procedure Valeur_Trouver()
Nb_De_Coups = CountGadgetItems(#ListIcon_Affichage_Des_Resultats)+1; recupere le nombres de coups

Choix = MessageRequester("Information", "Bravo, vous avez trouvez en : "+Nb_De_Coups+" coups. Souhaitez vous faire une nouvelle partie ?", #PB_MessageRequester_YesNo)
If Choix = 6; le bouton Oui a été choisi, on active et desactive les differants gadgets. Et on nettoie les gadgets
DisableGadget(#ComboBox_Fourchette, #False)
DisableGadget(#Button_Demarrer, #False)
DisableGadget(#String_Valeur_Du_Joueur, #True)
DisableGadget(#Button_Valeur_Du_Joueur, #True) 
 SetGadgetText(#String_Valeur_Du_Joueur, "")
 ClearGadgetItems(#ListIcon_Affichage_Des_Resultats)
  Nb_De_Coups = 0 ; met le nombre de coup au depart a 0
 
Else ; le bouton Non a été choisi
 End 
EndIf

EndProcedure


;- procedure principale qui gere les affichages, compare les resultats etc..
Procedure Game()
Valeur_Entree$ = GetGadgetText(#String_Valeur_Du_Joueur)

If Val(Valeur_Entree$) < Valeur_A_Trouver ; si la valeur entree est plus petite
AddGadgetItem(#ListIcon_Affichage_Des_Resultats, CountGadgetItems(#ListIcon_Affichage_Des_Resultats), "C'est plus grand que : "+Valeur_Entree$, 0, 0)

ElseIf Val(Valeur_Entree$) > Valeur_A_Trouver ; si la valeur entree est plus grande
AddGadgetItem(#ListIcon_Affichage_Des_Resultats, CountGadgetItems(#ListIcon_Affichage_Des_Resultats), "C'est plus petit que : "+Valeur_Entree$, 0, 0)

ElseIf Val(Valeur_Entree$) = Valeur_A_Trouver ; si la valeur est bonne
Valeur_Trouver()   
EndIf 

SetGadgetState(#ListIcon_Affichage_Des_Resultats, CountGadgetItems(#ListIcon_Affichage_Des_Resultats)-1)

SetGadgetText(#String_Valeur_Du_Joueur, ""); vide le stringgadget apres envoie de la valeur
EndProcedure
Rien de plus a ajouté. Le code contient des commentaires.

EDIT :
Ajout l'option de valider la valeur avec la touche Entrée (beaucoup plus pratique) :D





@++

Re: Le plus ou moins

Publié : jeu. 11/avr./2019 10:37
par PAPIPP
Bonjour Venon

Et merci pour ce prg.

La recherche dichotomique optimise le nombre de test de recherche.

Cette méthode consiste à tester le nombre compris à moitié chemin entre un mini et un max.
Ici au départ le mini est 0 et le max 100 donc on test 50
La suite dépend du résultat donné par le prg.
1) Si le prg me dit que le nombre est supérieur on prend comme min =50 et max=100 donc moyenne =75 ect.. jusqu’au résultat final.
2) Si le prg me dit que le nombre est inférieur on prend comme min =0 et max=50 donc moyenne =25 ect.. jusqu’au résultat final.

Le nombre de tests en recherche dichotomique N_test= Log2(de l’étendue) dans notre cas N_test=log2(100)=6.64.
On doit donc trouver le nombre cherché situé entre 0 est 100 en <=6,64 coups donc <=7.

Code : Tout sélectionner

;; la formule du nombre max de recherche avec la méthode dichotomique est Nmoy=Log2(100)
Procedure.d LOG2d(numb)
  Protected RESUL.D
EnableASM
FINIT
FLD1 
FILD  dword [p.v_numb]
FYL2X 
FST  qword [p.v_RESUL]
ProcedureReturn resul
DisableASM 
EndProcedure
Debug StrD(LOG2d(100),18)
A+

Re: Le plus ou moins

Publié : jeu. 11/avr./2019 11:12
par venom
Bonjour papipp,

Merci je ne connaissais pas le terme dichotomique :wink: Par contre j'avais la bonne façon de trouver le nombre :D (logique en même temps) :P







@++

Re: Le plus ou moins

Publié : jeu. 11/avr./2019 12:53
par Micoute
C'est le même principe qu'un fil électrique qui est coupé quelque part, mais dont on veut garder la plus grande longueur possible.

Re: Le plus ou moins

Publié : jeu. 11/avr./2019 13:38
par Kwai chang caine
C'est cool !!!
J'ai aussi utilisé cette méthode. (1 à 100 en 5 réponses)

Moi je la connaissais, parce qu'au boulot en 1990 on travaillait avec des HUNTER (petits ordinateurs portables) programmables en basic, qui étaient lents (Comme beaucoup de truc de l'époque)
Et la développeuse blonde, elle arrivait à trouver une référence parmi tant d'autres, en quelques secondes 8O

Je lui avait demandé comment elle faisait, et le splendide mot "Dichotomique" venu de nulle part, est sorti de sa jolie bouche
Dichotomique ça la pète déjà tout seul comme mot, faut déjà faire fort pour caser ça dans une phrase à table, mais alors dans la bouche d'une belle blonde....je vous dit pas comment ma recherche d'affection à moi personnelle, elle a été tout autant décuplée :mrgreen:
Du coups j'ai jamais oublié ce mot...comme quoi l'apprentissage passe beaucoup mieux quant on y met du cœur :lol:

Merci pour le partage 8)

Re: Le plus ou moins

Publié : ven. 12/avr./2019 7:43
par PAPIPP
Bonjour Venon

Comme on peut mesurer le nombre de coups max (voir ci-dessous le prg).

On pourrait émettre un message d’encouragement si le nombre de coups dépasse le max trouvé.

Prg du calcul de log2 avec en entrée et en sortie un flottant.

Code : Tout sélectionner

;; la formule du nombre max de recherche avec la méthode dichotomique est Nbtestmax=Log2(100)
Structure vald
  StructureUnion
    vd.d
    vq.q
  EndStructureUnion
 EndStructure 
Procedure.d LOG2dd(numb.d)
  Protected RESUL.D
EnableASM
FINIT
FLD1 
FLD  qword [p.v_numb]
FYL2X 
FST  qword [p.v_RESUL]
ProcedureReturn resul
DisableASM 
EndProcedure
i.vald\vd=10
ldd.d
While i\vd<=Pow(10,20)
  ldd=LOG2dd(i\vd)
  Debug "Nb_tests_Max=Log2("+StrD(i\vd)+")="+StrD(Ldd,18)+" donc <="+Round(ldd,#PB_Round_Up)+"      hexa="+Hex(i\vq,#PB_Quad)
  i\vd*10
Wend

Re: Le plus ou moins

Publié : ven. 12/avr./2019 20:43
par venom
Salut PAPIPP,

Merci pour ce sympathique code 8) Oui pourquoi pas l’intégré au jeu ça pourrait être sympa.






@++