Forum Liberty Basic France

Jeux » Mikado Comme un vrai, mais en faux
Le 12/12/2017 à 18h25

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Au Mikado, il faut prendre les baguettes sans faire bouger, en gros prendre la dernière tombée.
C'est le but de ce jeu; il y a un énorme bug à la fin; qui fait que ça ne marche qu'une fois; il faut relancer à chaque partie.
Le score est fantaisiste.
Les couleurs étant aléatoires, si une barre est de la couleur du fond, la partie est morte.
Code VB :
 
   NOMAINWIN
    WindowWidth = 600
    WindowHeight = 400
    UpperLeftX = (DisplayWidth-WindowWidth)-200
    UpperLeftY = 20 ' (DisplayHeight-WindowHeight)
    TEXTBOX #w.c, 10 , 20, 40, 20
    BUTTON #w.go, "Go !", [go], UL, 60, 20, 40, 20
    TEXTBOX #w.n, 200 , 335, 100, 25
    GRAPHICBOX #w.m 5, 5, 585, 360
    OPEN "Mikado" FOR window_nf AS #w
    #w, "TRAPCLOSE [close]"
    #w.m , "down"
    #w.m, "fill lightgray"
    #w.m, "when leftButtonDown [Segment]"
    #w.m, "when rightButtonDown [rightbutton]"
    #w.n, "!font comic 12 italic bold"
    #w.n, "Score: ";Score
    nseg = 10: #w.c, str$(nseg)
    dim seg.x(nseg), seg.y(nseg)
    dim seg.x1(nseg), seg.y1(nseg)
    dim seg.x2(nseg), seg.y2(nseg)
  wait'---------------------
    [go]
    #w.c, "!contents? var$": nseg=val(var$)
    siz=6: score=0: #w.n, "score: ";score
    #w.m, "fill lightgray"
    dim seg.x(nseg), seg.y(nseg)
    dim seg.x1(nseg), seg.y1(nseg)
    dim seg.x2(nseg), seg.y2(nseg)
   for a=1 to nseg
     #w.m, "up"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     seg.x1(a)=x: seg.y1(a)=y
     #w.m, "place ";x;" ";y
     [ret]
     r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1
     r$=str$(r): g$=str$(g): b$=str$(b)
     col$=r$+" "+g$+" "+b$: #w.m, "color ";col$
     'if col$="lightgray" then [ret]
     if col$="192 192 192" then [ret]
    ' siz=int(rnd(1)*2)+1
     #w.m, "size ";siz
     #w.m, "down"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     seg.x2(a)=x: seg.y2(a)=y
     #w.m, "goto ";x;" ";y
     #w.m, "segment a": aa=a-1
     #w.m, "Flush ";a
   next a
   wait
[Segment]
    Mx = MouseX
    My = MouseY
    for n = 1 to nseg
        if Mx > min(seg.x1(n),seg.x2(n)) and Mx < max(seg.x1(n),seg.x2(n))_
       and My > min(seg.y1(n),seg.y2(n)) and My < max(seg.y1(n),seg.y2(n)) then
           if n=aa then
                #w.m, "delsegment ";n ' no
                aa=aa-1: score=score+1: #w.n, "score: ";score
                exit for
           else
              score=score-1: #w.n, "score: ";score
            end if
        end if
    next
   #w.m, "redraw"
  wait
function min(a, b)
    min = a
    if b < a then min = b
end function
function max(a, b)
    max = a
    if b > a then max = b
end function
  [close]
    CLOSE  #w
    END
 
 
____________________
Roro

   
Le 13/12/2017 à 15h16

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
euh, le bouton droit de la souris ne fonctionne pas (je taquine^^)

C'est une bonne initiation aux mécanismes du segment et delsegment. je n'ai pas encore osé aborder le problème pour mes propres programmes (si j'en conçois encore), mais à ce que j'ai lu, il faut savoir gérer ce qu'on affiche à l'écran dès qu'on utilise des lignes et des cercles en pagaille, pour ne pas saturer la mémoire et si on veut les retrouver après avoir minimisé la fenêtre ou l'avoir caché par une autre.

Il y a en effet quelques bugs, mais ils seront probablement éradiqués sous peu ;)
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 13/12/2017 à 22h19

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Bah les segments ça sert juste à identifier chaque graphisme pour opérer avec nominalement; je pense que si on ne mets pas du "flush" où il faut on doit perdre l'image au recouvrement tout pareil.
Ce mikado pourrait bien dériver vers un "Jeu des Allumettes" (le fameux jeu où on perd à tous les coups.)
____________________
Roro

   
Le 15/12/2017 à 18h13

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
Hello !

Etait-ce juste comme ça, pour voir, ou as-tu envie d'aller plus loin ?

De mon coté, l'éditeur tique quand il voit le point à l'intérieur du nom des tableaux, et le programme fonctionne malgré tout :
Code VB :
 
    dim seg.x(nseg), seg.y(nseg)
    dim seg.x1(nseg), seg.y1(nseg)
    dim seg.x2(nseg), seg.y2(nseg)
 

Se pourrait-il que ce soit justement la cause du bug ? Même en cours de partie, on a parfois l'impression que le programme ne répond pas comme il le devrait, il ne retire pas toujours la baguette qu'on veut retirer et qui semble libre, ou il en retire une autre...

A cette heure je n'ai pas touché au nom des tableaux, mais comme leur dimension peut varier à volonté selon les désirs du joueur, j'ai mis leur déclaration en sous-programme.

J'ai aussi modififié
Code VB :
r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1

en
Code VB :
r=int(rnd(1)*255/40)*40: g=int(rnd(1)*255/40)*40: b=int(rnd(1)*255/40)*40

Cela donne des intensités lumineuses allant de 0 à 240 par pas de 40, ce qui évite de tomber sur le gris 192 192 192 du fond, et donc d'avoir à faire un nouveau tirage. Mais ce n'est pas forcément joli, et une même couleur peut facilement se voir attribuée à deux lignes distinctes : si elles se croisent on ne sait pas laquelle est au dessus...

Je ne me suis pas encore penché sur la logique du fonctionnement. je publierai à ce moment-là, si d'ici là tu n'as pas déjà modifié ton programme initial.

A+
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 15/12/2017 à 20h57

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Je ne toucherai pas au code initial. c'est possible que les noms de tableaux soient critiques
Sur un autre pc j'étais obligé de faire des if then...end if pour mettre plusieurs instructions dans le même test; sur la même ligne ça ne passait pas. Pour savoir il faut tester.
Envoie des idées...
____________________
Roro

   
Le 15/12/2017 à 23h47

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
J'ai modifié les noms des tableaux et le bug est toujours là.

Il est dans la gestion de la variable aa : dans [go], elle prend la valeur a-1, soit l'avant dernier élément. J'ai déplacé son initialisation après la boucle a, et je l'ai initialisé en aa=nseg.

Mais c'est pas top. Dans le jeu du mikado, on enlève le bâtonnet qu'on veut, là on est obligé d'enlever le dernier qui a été dessiné, c'est peut-être le jeu sur l'ordinateur, mais ne c'est pas le mikado. Il faudrait perdre seulement si on enlève un bâtonnet recouvert par un autre

Et comment faire lorsqu'une coordonnée de souris est commune à deux bâtonnets qui se croisent, lequel effacer ?
bâtonnet n°5 (50,60)-(120,150)
bâtonnet n°8 (80,120)-(100,80)
clic souris (90,100)

Le n°5 a été dessiné avant le n°8, les deux font réagir la condition, il faut donc supprimer le n°8, et c'est là que aa devrait intervenir, mais rien ne dit que le n°8 est le dernier bâtonnet dessiné, et il faudrait pouvoir supprimer le segment qui a le numéro le plus grand, plutôt que le dernier de la liste.

Dans
Code VB :
 
[Segment]
    Mx = MouseX
    My = MouseY
    for n = 1 to nseg
        if Mx > min(seg.x1(n),seg.x2(n)) and Mx < max(seg.x1(n),seg.x2(n))_
       and My > min(seg.y1(n),seg.y2(n)) and My < max(seg.y1(n),seg.y2(n)) then
           if n=aa then
                #w.m, "delsegment ";n ' no
                aa=aa-1: score=score+1: #w.n, "score: ";score
                exit for
           else
              score=score-1: #w.n, "score: ";score
            end if
        end if
    next
   #w.m, "redraw"
  wait
 

Il faudrait :
déplacer le delsegment après la boucle n
supprimer le if n=aa (tant pis pour le score, c'est du provisoire)
remplacer le if n=aa par une variable qui conserve le dernier numéro de bâtonnet a avoir fait réagir la condition if Mx>....

Un peu tard ce soir pour que je tente l'essai, parce qu'il y a une complication en vue : un bâtonnet peut être contenu dans le rectangle défini par un autre bâtonnet, sans pour autant le croiser, et si on clique au bon endroit, les deux vont déclencher le if Mx>... et on ne saura pas lequel effacer :
bâtonnet n°12 (20,20)-(40,80)
bâtonnet n°25 (28,30)-(35,45)
clic souris (30,40)

On devrait s'en sortir en travaillant sur les équations des droites portant les segments, plutôt que sur les segments eux-mêmes. Il devrait être assez facile de savoir si le clic de souris a eu lieu sur le segment d'une droite dont on connait l'équation (reste à voir le problème de l'épaisseur du trait).

Bonne nuit tout le monde, à demain.
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 16/12/2017 à 18h17

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Pour tout dire, je suis parti d'un code Cassiope pour faire ce pseudo Mikado
http://libertybasic.fr/forum/topic-496+dr-nim.php

Il ne faut pas cliquer pile sur le croisement, le pc ne peut pas discriminer, vu que les données sont communes.
____________________
Roro

   
Le 16/12/2017 à 19h50

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
Oki,

Mais c'est pas forcément pile sur le croisement : si tu cliques dans une zone commune à deux bâtonnets (un bâtonnet étant toujours une diagonale d'une zone rectangulaire), le programme détectera ces deux bâtonnets et ne saura pas lequel effacer.

Possible aussi qu'un bâtonnet strictement vertical ou horizontal ne sera pas détecté

J'ai modifié un peu plus que ce que j'aurais cru devoir faire, mais ça marche mieux... Là on travaille toujours à partir de segments de droite, je n'ai pas intégré d'équation de droites dans le programme.

J'ai aussi essayé de remanier le programme pour pouvoir démarrer un nouveau jeu dès que l'actuel est terminé mais ça ne marche pas, et cela rejoint le "gros" bug dont tu parlais dans ton premier post. Pour être plus explicite, j'ai mis quelques "print" et mis en commentaire le nomainwin. Tu verra ainsi, quand le premier jeu sera terminé, et que l'ordi préparera le second, que dans la même boucle "a", le "a" de la boucle n'a pas la même valeur que le "a" de "segment a". C'est probablement un fonctionnement spécifique de "segment"

Voici :

Code VB :
 
   'NOMAINWIN
    WindowWidth = 600
    WindowHeight = 400
    UpperLeftX = (DisplayWidth-WindowWidth)-200
    UpperLeftY = 20 ' (DisplayHeight-WindowHeight)
    TEXTBOX #w.c, 10 , 20, 40, 20
    BUTTON #w.go, "Go !", [go], UL, 60, 20, 40, 20
    TEXTBOX #w.n, 200 , 335, 100, 25
    GRAPHICBOX #w.m 5, 5, 585, 360
    OPEN "Mikado" FOR window_nf AS #w
    #w, "TRAPCLOSE [close]"
    #w.m , "down"
    #w.m, "fill lightgray"
    #w.m, "when leftButtonDown [Segment]"
    #w.m, "when rightButtonDown [rightbutton]"
    #w.n, "!font comic 12 italic bold"
    #w.n, "score: ";score
    nseg = 10: #w.c, str$(nseg):gosub [dim_tableau]
 
  wait'---------------------

[go]
    print "sp [go]"
    gosub [nouveau_jeu]
    wait
 
[nouveau_jeu]
    print "sp [nouveau_jeu]"
    #w.c, "!contents? var$": nseg=val(var$):gosub [dim_tableau]
    siz=6: score=0: #w.n, "score: ";score
    #w.m, "fill lightgray"
print "nombre de segments : ";nseg
   for a=1 to nseg
   print "boucle a, tour ";a
     #w.m, "up"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx1(a)=x: segy1(a)=y
     #w.m, "place ";x;" ";y
 
     'r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1
     r=int(rnd(1)*255/40)*40: g=int(rnd(1)*255/40)*40: b=int(rnd(1)*255/40)*40
 
     r$=str$(r): g$=str$(g): b$=str$(b)
     col$=r$+" "+g$+" "+b$: #w.m, "color ";col$
 
    ' siz=int(rnd(1)*2)+1
     #w.m, "size ";siz
     #w.m, "down"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx2(a)=x: segy2(a)=y
     #w.m, "goto ";x;" ";y
     #w.m, "segment a"
     #w.m, "flush ";a
    print "batonnet ";a;", couleur=";col$
   next a
 
   aa=nseg
   return
 
[Segment]
    Mx = MouseX
    My = MouseY
    effacer=0
    reste=nseg
 
    for n = 1 to nseg
 
       minix=min(segx1(n),segx2(n))
       maxix=max(segx1(n),segx2(n))
       miny=min(segy1(n),segy2(n))
       maxy=max(segy1(n),segy2(n))
 
       if Mx > minix and Mx < maxix and My > miny and My < maxy then
           effacer=1
           aa=n
       end if
 
    next
 
    if effacer then
        'clic sur batonnet
        score=score+1
 
        'effacement graphique
        #w.m, "delsegment ";aa
        #w.m, "redraw"
        effacer=0
 
        'effacement dans le tableau
        segx1(aa)=-1:segx2(aa)=-1
        segy1(aa)=-1:segy2(aa)=-1
 
        'batonnets restants
        reste=reste-1
 
    else
        'clic à côté
        score=score-1
    end if
 
    #w.n, "score: ";score   'actualise l'affichage du score

    if reste=0 then gosub [nouveau_jeu]
    wait
 
 
function min(a, b)
    min = a
    if b < a then min = b
end function
 
 
function max(a, b)
    max = a
    if b > a then max = b
end function
 
[close]
    CLOSE  #w
    END
 
'sous-programmes
[dim_tableau]
    dim segx(nseg), segy(nseg)
    dim segx1(nseg), segy1(nseg)
    dim segx2(nseg), segy2(nseg)
    return
 
'et fin
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 16/12/2017 à 22h26

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Hey...! C'est pas bon, tu triche! On peut enlever les bâtons de dessous!
Bah la zone commune c'est le croisement.
Je ne pense pas que la position verticale du bâtonnet soit critique.
Il doit manquer une réinitialisation quelque part pour une nouvelle partie en plus du bug de fin qui dans ta version vient plus tôt que dans la mienne. les segments, c'est pas évident.
Comme j'ai pas mal transpiré pour en arriver là en partant de là-bas, je souffle un peu.
J'ai dans l'idée d'exploiter l'autre partie du code Cassiope (les balles), pour en faire un match de foot autonome; mais ça fait pas mal de sprites à créer si je veux que les joueurs courent dans le bon sens.
Avec les paramètres des joueurs (angle et force de frappe) en option; le tout assaisonné d'aléatoire pour le fun.
Le blème c'est que les vues de dessus de match de foot sont rares (pour faire les sprites).
____________________
Roro

   
Le 17/12/2017 à 10h01

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
Joueur de foot vu de dessus : un rectangle pour les épaules, un rond pour la tête, et un nez rouge pour différentier l'avant de l'arrière ;) Et pour les sprites, on aimerait bien pouvoir les faire pivoter au degré près, pour éviter de générer 360 bitmaps. Malheureusement c'est par quart de tour...

Pour le bâtonnet qui est effacé alors qu'il y a d'autres bâtonnets au dessus, alors là, parole ! c'est à l'insu de mon plein gré ;)

En fait mon esprit me dit que ça ne devrait pas se produire mais il est bien obligé de se rendre à l'évidence. Les équations de droite devraient lever le doute, je m'y penche dès que j'ai deux minutes heures jours devant moi.

Autre effet inattendu : le fond passe parfois en blanc alors que le programme tourne normalement.

Pour le programme qui se bloque au redémarrage, l'erreur est une compréhension erronée de l'instruction "segment drawSegment". Dans
Code VB :
 
   for a=1 to nseg
   print "boucle a, tour ";a
     #w.m, "up"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx1(a)=x: segy1(a)=y
     #w.m, "place ";x;" ";y
 
     'r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1
     r=int(rnd(1)*255/40)*40: g=int(rnd(1)*255/40)*40: b=int(rnd(1)*255/40)*40
 
     r$=str$(r): g$=str$(g): b$=str$(b)
     col$=r$+" "+g$+" "+b$: #w.m, "color ";col$
 
    ' siz=int(rnd(1)*2)+1
     #w.m, "size ";siz
     #w.m, "down"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx2(a)=x: segy2(a)=y
     #w.m, "goto ";x;" ";y
     #w.m, "segment a"
     #w.m, "flush ";a
    print "batonnet ";a;", couleur=";col$
   next a
 

l'instruction #w.m, "segment a" donne à a le numéro du segment actuel, qui vaut 11 quand on a fini le jeu précédent. Donc dans la boucle a, si on fait #w.m, "segment a", le a de la boucle devient 11, supérieur à nseg, et la boucle s'arrête.

Il ne semble pas possible de remettre à zéro le compteur de segments : il compte tant que le programme tourne (on ne risque pas un dépassement de quelque chose, avec un compteur qui compte à l'infini ? Je capte sans doute de travers, car c'est précisément pour éviter de saturer la mémoire qu'on doit recourir à cette gestion en segments)

J'ai donc dissocié les boucles de création/affichage et la gestion des segments.

Le tout est confus et mériterait d'être réécrit, mais ça fonctionne, on peut repartir sur une nouvelle partie sans relancer le programme :

Code VB :
 
'NOMAINWIN
    WindowWidth = 600
    WindowHeight = 400
    UpperLeftX = (DisplayWidth-WindowWidth)-200
    UpperLeftY = 20 ' (DisplayHeight-WindowHeight)
    TEXTBOX #w.c, 10 , 20, 40, 20
    BUTTON #w.go, "Go !", [go], UL, 60, 20, 40, 20
    TEXTBOX #w.n, 200 , 335, 100, 25
    GRAPHICBOX #w.m 5, 5, 585, 360
    OPEN "Mikado" FOR window_nf AS #w
    #w, "TRAPCLOSE [close]"
    #w.m , "down"
    #w.m, "fill lightgray"
    #w.m, "when leftButtonDown [Segment]"
    #w.m, "when rightButtonDown [rightbutton]"
    #w.n, "!font comic 12 italic bold"
    #w.n, "score: ";score
    nseg = 10: #w.c, str$(nseg):gosub [dim_tableau]
 
  wait'---------------------

[go]
    print "sp [go]"
    gosub [nouveau_jeu]
    wait
 
[nouveau_jeu]
    print "sp [nouveau_jeu]"
    #w.c, "!contents? var$": nseg=val(var$):gosub [dim_tableau]
    siz=6: score=0: #w.n, "score: ";score
    #w.m, "fill lightgray"
    #w.m, "segment segdep"
print "nombre de segments : ";nseg
print "segment de départ : ";segdep
   for a=1 to nseg
   print "boucle a, tour ";a
     #w.m, "up"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx1(a)=x: segy1(a)=y
     #w.m, "place ";x;" ";y
 
     'r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1
     r=int(rnd(1)*255/40)*40: g=int(rnd(1)*255/40)*40: b=int(rnd(1)*255/40)*40
 
     r$=str$(r): g$=str$(g): b$=str$(b)
     col$=r$+" "+g$+" "+b$: #w.m, "color ";col$
 
    ' siz=int(rnd(1)*2)+1
     #w.m, "size ";siz
     #w.m, "down"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx2(a)=x: segy2(a)=y
     #w.m, "goto ";x;" ";y
     #w.m, "segment numseg"
     print "numéro de segment : ";numseg
     #w.m, "flush ";numseg
    print "batonnet ";numseg;", couleur=";col$
   next a
 
   aa=nseg
   return
 
[Segment]
    Mx = MouseX
    My = MouseY
    effacer=0
    reste=nseg
 
    for n = 1 to nseg
 
       minix=min(segx1(n),segx2(n))
       maxix=max(segx1(n),segx2(n))
       miny=min(segy1(n),segy2(n))
       maxy=max(segy1(n),segy2(n))
 
       if Mx > minix and Mx < maxix and My > miny and My < maxy then
           effacer=1
           aa=segdep-1+n:print "segment actuel : ";aa
           ab=n
       end if
 
    next
 
    if effacer then
        'clic sur batonnet
        score=score+1
 
        'effacement graphique
        #w.m, "delsegment ";aa
        #w.m, "redraw"
        effacer=0
 
        'effacement dans le tableau
        segx1(ab)=-1:segx2(ab)=-1
        segy1(ab)=-1:segy2(ab)=-1
 
        'batonnets restants
        reste=reste-1
 
    else
        'clic à côté
        score=score-1
    end if
 
    #w.n, "score: ";score   'actualise l'affichage du score

    if reste=0 then gosub [nouveau_jeu]
 
    wait
 
 
function min(a, b)
    min = a
    if b < a then min = b
end function
 
 
function max(a, b)
    max = a
    if b > a then max = b
end function
 
[close]
    CLOSE  #w
    END
 
'sous-programmes
[dim_tableau]
    dim segx(nseg), segy(nseg)
    dim segx1(nseg), segy1(nseg)
    dim segx2(nseg), segy2(nseg)
    return
 
'et fin

 


A noter que le segment, en termes de JB/LB, n'est pas forcément une ligne, si j'en crois l'aide, mais un ensemble de graphismes dessinés entre deux instructions flush.
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 17/12/2017 à 10h59

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Il semble qu'avec ton dernier code c'est systématiquement le bâton sélectionné qui est supprimé, et non le dernier posé.

L'écran blanc c'est ce que j'appelle le bug de fin; qui dans ma version n'arrive toujours qu'à l'avant dernier bâton.

Je ne pense pas que la gestion par fonction (mathématique) soit judicieuse car alors il n'y aura qu'une ligne au lieu d'un quadrilatère pour la sélection en coordonnées.
____________________
Roro

   
Le 17/12/2017 à 20h50

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
Citation:
Il semble qu'avec ton dernier code c'est systématiquement le bâton sélectionné qui est supprimé, et non le dernier posé

Normalement, ça ne devrait pas être systématique. Dans [segment] c'est la variable aa qui porte le numéro du bâtonnet à effacer. Comme on explore tous les bâtonnets par ordre de création, la dernière fois que aa est mis à jour est celle du dernier bâtonnet installé dans la zone où on a cliqué. Mais on peut effectivement retirer les bâtonnets solitaires dans l'ordre qu'on veut.

Je confirme que le clic sur une ligne horizontale n'est pas détectée.

Citation:
L'écran blanc c'est ce que j'appelle le bug de fin; qui dans ma version n'arrive toujours qu'à l'avant dernier bâton

Ma version l'affiche quand ça lui chante. Aurait-il une signification d'anomalie ?

Quant au bug de fin, je pensais à l'impossibilité de relancer une nouvelle partie.

Citation:
Je ne pense pas que la gestion par fonction (mathématique) soit judicieuse car alors il n'y aura qu'une ligne au lieu d'un quadrilatère pour la sélection en coordonnées.


C'est fondamentalement de la recherche ;)

J'ai voulu savoir si on pouvait détecter un clic sur un bâtonnet en utilisant les proportions, ainsi pour notre bâtonnet ab, nous aurions dû obtenir une égalité entre (xb-xa)/(yb-ya) et (xb-Mx)/(yb-My) si le clic se fait sur le bâtonnet, mais j'ai dû me prendre les pieds dans le tapis quelque part, car j'obtenais des résultats incohérents. je verrais plus tard.

Si la ligne est trop fine on peut mettre une erreur artificielle de 1 ou 2 pour mille, et considérer que le clic est valable s'il est entre égalité moins erreur et égalité plus erreur.

La version purement géométrique, avec les équations, me semble en effet assez complexe à mettre en œuvre, du moins en regard de la simplicité du "dernier affiché premier effacé", mais ça ne semble pas inabordable.

En tout cas, ce qui est concret, c'est que j'arrête pour ce soir ;)

Bises à tout le monde, a+



Edité par Christophe Le 17/12/2017 à 20h54
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 17/12/2017 à 21h56

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Citation:
Ma version l'affiche quand ça lui chante

ça doit être un bug "quantique" en même temps mort et vivant comme le chat de Schrödinger.

Citation:
C'est fondamentalement de la recherche ;)

Ah bon, tu me rassure avec ta marge d'erreur car pour cliquer sur une ligne de un pixel ça doit être coton

Citation:
le clic sur une ligne horizontale n'est pas détectée

y a pas de raison pour ça, c'est un quadrilatère comme les autres.
____________________
Roro

   
Le 06/01/2018 à 17h25

Modérateur

Groupe: Modérateur

Inscrit le: 09/02/2015
Messages: 525
Certes, mais la réalité démontre le contraire ;)

C'est peut être qu'une histoire de condition "<" ou ">" au lieu de "<=" ou ">=", je n'ai pas cherché.

Par contre, maintenant on détecte le clic de souris sur un bâtonnet grâce aux équations de droite.

En l'état actuel, deux effets à supprimer :
  • le bâtonnet est effacé même s'il y en a trente-six dessus
  • les bâtonnets les plus verticaux sont difficiles à cliquer


La modification a eu lieu dans le sous-programme [segment]

Voici :
Code VB :
 
'prog Roland modifié - 6 janvier 2018

   'NOMAINWIN
    WindowWidth = 600
    WindowHeight = 400
    UpperLeftX = (DisplayWidth-WindowWidth)-200
    UpperLeftY = 20 ' (DisplayHeight-WindowHeight)
    TEXTBOX #w.c, 10 , 20, 40, 20
    BUTTON #w.go, "Go !", [go], UL, 60, 20, 40, 20
    TEXTBOX #w.n, 200 , 335, 100, 25
    GRAPHICBOX #w.m 5, 5, 585, 360
    OPEN "Mikado" FOR window_nf AS #w
    #w, "TRAPCLOSE [close]"
    #w.m , "down"
    #w.m, "fill lightgray"
    #w.m, "when leftButtonDown [Segment]"
    #w.m, "when rightButtonDown [rightbutton]"
    #w.n, "!font comic 12 italic bold"
    #w.n, "score: ";score
    nseg = 10: #w.c, str$(nseg):gosub [dim_tableau]
 
  wait'---------------------

[go]
    print "sp [go]"
    gosub [nouveau_jeu]
    wait
 
[nouveau_jeu]
    print "sp [nouveau_jeu]"
    #w.c, "!contents? var$": nseg=val(var$):gosub [dim_tableau]
    siz=6: score=0: #w.n, "score: ";score
    #w.m, "fill lightgray"
print "nombre de segments : ";nseg
   for a=1 to nseg
   print "boucle a, tour ";a
     #w.m, "up"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx1(a)=x: segy1(a)=y
     #w.m, "place ";x;" ";y
 
     'r=int(rnd(1)*255)+1: g=int(rnd(1)*255)+1: b=int(rnd(1)*255)+1
     r=int(rnd(1)*255/40)*40: g=int(rnd(1)*255/40)*40: b=int(rnd(1)*255/40)*40
 
     r$=str$(r): g$=str$(g): b$=str$(b)
     col$=r$+" "+g$+" "+b$: #w.m, "color ";col$
 
    ' siz=int(rnd(1)*2)+1
     #w.m, "size ";siz
     #w.m, "down"
     x=int(rnd(1)*580) + 1: y=int(rnd(1)*360) + 1
     segx2(a)=x: segy2(a)=y
 
     'coefficient directeur et ordonnée à l'origin
    coefd(a)=(segy1(a)-segy2(a))/(segx1(a)-segx2(a))
    ordorig(a)=(segy1(a)-segy2(a))*coefd(a)
 
     #w.m, "goto ";x;" ";y
     #w.m, "segment a"
     #w.m, "flush ";a
    print "batonnet ";a;", couleur=";col$
   next a
 
   aa=nseg
   return
 
[Segment]
    Mx = MouseX
    My = MouseY
    effacer=0
    reste=nseg
 
    for n = 1 to nseg
 
        'point A
        xA=segx1(n):yA=segy1(n)
        print "A(";xA;",";yA;")"
        'point B
        xB=segx2(n):yB=segy2(n)
        print "B(";xB;",";yB;")"
 
        'limitation au segment [AB]
        ok=0
        if Mx>=min(xA,xB) and Mx<=max(xA,xB) then ok=ok+1
        if My>=min(yA,yB) and My<=max(yA,yB) then ok=ok+10
 
        'limitation aux droites non verticales
        if xA<>xB then ok=ok+100
 
        'déterminer la droite passant par A et B
        if ok=111 then
            print "xA<>xB"
 
            'coefficient directeur
            a=(yA-yB)/(xA-xB)
            print "coefficient directeur : ";a
 
            'ordonnée à l'origine
            b=yA-a*xA
            print "ordonnée à l'origine : ";b
 
            'le clic de souris est-il fait sur [AB] ?
            errvol=0.03 'erreur volontaire pour prendre en compte l'imprécision du clic

            'sur [AB] si égalité
            '(si y=ax+b, alors y/(ax+b) doit valoir 1)
            print "rapport My/(a*Mx+b) doit être le plus proche de 1 possible"
            print "rapport : ";My/(a*Mx+b)
 
            if My/(a*Mx+b)<1+errvol and My/(a*Mx+b)>1-errvol then
                print "sur la droite !"
                aa=n
                effacer=1
            else
                print "en dehors de la droite !"
                print
            end if
 
        end if
 
    next
 
    if effacer then
        'clic sur batonnet
        score=score+1
 
        'effacement graphique
        #w.m, "delsegment ";aa
        #w.m, "redraw"
        effacer=0
        print "*** bâtonnet effacé"
        'effacement dans le tableau
        segx1(aa)=-1:segx2(aa)=-1
        segy1(aa)=-1:segy2(aa)=-1
 
        'batonnets restants
        reste=reste-1
 
    else
        'clic à côté
        score=score-1
    end if
 
    #w.n, "score: ";score   'actualise l'affichage du score

    if reste=0 then gosub [nouveau_jeu]
    wait
 
 
function min(a, b)
    min = a
    if b < a then min = b
end function
 
 
function max(a, b)
    max = a
    if b > a then max = b
end function
 
[close]
    CLOSE  #w
    END
 
'sous-programmes
[dim_tableau]
    dim segx(nseg), segy(nseg)
    dim segx1(nseg), segy1(nseg)
    dim segx2(nseg), segy2(nseg)
    dim coefd(nseg), ordorig(nseg)
    return
 
'et fin




Edité par Christophe Le 06/01/2018 à 17h26
____________________
Just BASIC v2.0 :
  • utilisation courante avec GNU/Linux Mageia6 + Wine (Pas trouvé d'incohérences ou de bug de compilation à ce jour)
  • utilisation occasionnelle ou vérification/débugage difficile avec Windows XP sur un petit eeepc

   
Le 06/01/2018 à 18h37

Administrateur

Groupe: Administrateur

Inscrit le: 04/03/2012
Messages: 2097
Pfff... J'ai essayé de faire le jeu des allumettes avec les segments; mais d'après moi y a un os dans le pâté des segments (bug aléatoires et incohérences); alors j'ai fait autrement.
Les segments, c'est pas clair.
____________________
Roro

   
Jeux » Mikado Comme un vrai, mais en faux  

 |  |

1 Utilisateur en ligne : 0 Administrateur, 0 Modérateur, 0 Membre et 1 Visiteur
Utilisateur en ligne : Aucun membre connecté
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie