package require Tk
set p 2
array set color {0 #abcdef 1 #fedcba}
set max [expr {2 << $p}]
set s [list]
foreach i {0 1} \
{
set img($i) [image create photo -width 10 -height 10]
$img($i) put $color($i) -to 0 0 10 10
}
for {set i 0} {$i < $max} {incr i} \
{
for {set j 0} {$j < $max} {incr j} \
{
button .($i:$j) -image $img(0) -command ($i:$j) -bd 0
grid .($i:$j) -row $i -column $j
bind .($i:$j) <ButtonPress-3> undo
proc ($i:$j) {} \
{
foreach {i j} [split [string range [info level 0] 1 end-1] :]
break
for {set ii [expr {$i - 1}]} {$ii <= [expr {$i + 1}]} {incr ii}
\
{
for {set jj [expr {$j - 1}]} {$jj <= [expr {$j + 1}]} {incr
jj} \
{ if {!($ii & $::max || $jj & $::max)} { ($ii!$jj) } }
}
lappend ::s ($i:$j)
}
proc ($i!$j) {} \
{
foreach {i j} [split [string range [info level 0] 1 end-1] !]
break
set n [expr {([.($i:$j) cget -image] == $::img(1)) ^ 1}]
.($i:$j) config -image $::img($n)
}
}
}
}
for {set n 0} {$n < $max} {incr n} \
{
set i [expr {int(rand() * $max)}]
set j [expr {int(rand() * $max)}]
($i!$j)
}
proc undo {} \
{
set n [llength $::s]
if {$n > 0} \
{
[lindex $::s end]
set ::s [lrange $::s 0 end-2]
}
}
un désespéré
complètement désespéré
Il s'agit d'un jeu que je connais pour y avoir joué
sur un ZX81 (ça date:-) A l'origine c'était paru dans un
magazine Jeux&Stratégies.
Il y a une grille (matrice) de cases noires ou blanches,
remplie aléatoirement.
Le but est que toutes les cases soient de la même couleur.
Mais ça se corse là, car le seul moyen d'y parvenir
est de cliquer sur une case, ce qui a pour effet
de changer la couleur (inverser) d'un bloc 3x3
dont le centre est la case cliquée.
En plus, le jeu est très dur et peut prendre sérieusement
la tête.
Pour ton patron, tu peux essayer de refactoriser le code
en créant de petites procédures spécialisées.
Le principal problème que je vois dans ce code
est l'abondance de boucles imbriquées.
Salutations,
Stéphane
Merci Stephane.
Pour l'instant, dès que j'essaye de simplifier quelque chose ça
rajoute des instructions !
> Pour l'instant, dès que j'essaye de simplifier quelque chose ça
> rajoute des instructions !
>
C'est vraiment contradictoire? La simplicite est-elle toujours
inversement proportionnelle au nombre d'instruction ou de lignes? En
jetant un coup d'oeil aux gagnants de l'IOCCC, categorie "Best One Liner
Program", j'ai tendance a penser le contraire ;-)
http://www.ioccc.org/winners.html
Bon, mais c'est vrai, l'exercice est toujours distrayant, autant a
ecrire qu'a dechiffrer.
Eric
En tout cas moins il y a de commandes et moins il y a de bug.
Et un programme sans commandes est le seul dont on soit sûr.
(bon, il ne fait pas forcément grand chose...)
ulis
foreach color {#fedcba #abcdef} {
image create photo $color -width 10 -height 10
$color put $color -to 0 0 10 10
}
proc do {W} {
foreach "x y" [split [string range $W 1 end] :] {}
for {set i [expr {$x - 1}]} {$i <= [expr {$x + 1}]} {incr i} {
for {set j [expr {$y - 1}]} {$j <= [expr {$y + 1}]} {incr j} {
if {![catch ".$i:$j cget -image" image] && $image eq
"#fedcba"} {
.$i:$j configure -image "#abcdef"
} else {
.$i:$j configure -image "#fedcba"
}
}
}
lappend ::s $W
}
proc undo {} {
if {[llength $::s]} {
do [lindex $::s end]
set ::s [lrange $::s 0 end-2]
}
}
for {set i 0} {$i < [expr {2 << $p}]} {incr i} {
for {set j 0} {$j < [expr {2 << $p}]} {incr j} {
grid [button .$i:$j -image $color -command [list do .$i:$j] \
-bd 0] -row $i -column $j
bind .$i:$j <ButtonPress-3> undo
}
}
--
David Zolli - Kroc
Voilà le bon :
package require Tk
set p 2
set s {}
foreach color {#fedcba #abcdef} {
image create photo $color -width 10 -height 10
$color put $color -to 0 0 10 10
}
proc do {W} {
foreach "x y" [split [string range $W 1 end] :] {}
for {set i [expr {$x - 1}]} {$i <= [expr {$x + 1}]} {incr i} {
for {set j [expr {$y - 1}]} {$j <= [expr {$y + 1}]} {incr j} {
if {[winfo exists .$i:$j]} {
switch [.$i:$j cget -image] {
"#fedcba" {.$i:$j configure -image "#abcdef"}
"#abcdef" {.$i:$j configure -image "#fedcba"}
for {set i 0} {$i < [expr {2 << $p}]} {incr i} {
for {set j 0} {$j < [expr {2 << $p}]} {incr j} {
if {rand() > .5} {set I "#abcdef"} {set I "#fedcba"}
grid [button .$i:$j -image $I -command [list do .$i:$j] \
Merci Kroc de venir à mon secours.
Ton script a l'air bougrement intéressant mais mon patron (si tu
savais ce que c'est qu'un patron) râle :
- il y a des constantes dupliquées (il veut le moins de constantes
possibles),
- et il manque l'initialisation (la boucle de randomisation avant la
proc undo).
En tout cas, bravo ! tu as l'air d'avoir pigé comment il marche. Et tu
vas peut-être me sauver.
ulis qui reprend espoir
package require Tk
set p 2
set s {}
foreach c {#abcdef #fedcba} {
[image create photo [llength [image names]] -width 10 -height 10]\
put $c -to 0 0 10 10
}
proc do {W} {
foreach "x y" [split [string range $W 1 end] :] {}
for {set i [expr {$x - 1}]} {$i <= [expr {$x + 1}]} {incr i} {
for {set j [expr {$y - 1}]} {$j <= [expr {$y + 1}]} {incr j} {
if {[winfo exists .$i:$j]} {
.$i:$j configure -image [expr {![.$i:$j cget -image]}]
}
}
}
lappend ::s $W
}
proc undo {} {
if {[llength $::s]} {
do [lindex $::s end]
set ::s [lrange $::s 0 end-2]
}
}
for {set i 0} {$i < [expr {2 << $p}]} {incr i} {
for {set j 0} {$j < [expr {2 << $p}]} {incr j} {
grid [button .$i:$j -image [expr int(round(rand()))]\
Quelqu'un peut confirmer ou infirmer cette impression ?
o represente les cases a cocher.
Kroc a écrit :
> Si il n'y a aucun pb.
> xxxxxxxx
> oxxoxxox
> xxxxxxxx
> oxxoxxox
> xxxxxxxx
> xxxxxxxx
> oxxoxxox
> xxxxxxxx
>
> o represente les cases a cocher.
Une solution unique pour une grille générée aléatoirement !! c'est
une martinguale ? ;-)
Blague à part, ce que je voudrais savoir c'est si c'est TOUJOURS
possible avec une grille de 8x8, pas seulement possible dans certains
cas.
proc do {W} {
foreach "x y" [split [string range $W 1 end] :] {}
for {set a [expr {8*atan(1)}]} {$a > 0} {set a [expr
{$a-(atan(1))}]} {
set i [expr {round($x + cos($a))}]
set j [expr {round($y + sin($a))}]
if {[winfo exists .$i:$j]} {
.$i:$j configure -image [expr {![.$i:$j cget -image]}]
}
}
.$x:$y configure -image [expr {![.$x:$y cget -image]}]
lappend ::s $W
}
--
David Zolli - Kroc
Ben alors Maurice : pas de commentaire ? C'est toujours pas bon ou ça
te laisse sans voix ? ;-)
Laisse moi le temps de compter, sacrebleu !
- ton code en fait autant,
- il définit bien p et les deux couleurs (bon on va faire comme si)
- il n'utilise pas d'autre constante (..., comme l'autre, quoi)
- il a 44 commandes en bleu alors que l'autre en a 59
Tu as donc réussi à faire une économie de plus de 20%
(bon, foreach ... break remplacé par foreach ... {}, c'est facile,
mais valable)
Bravo ! Tu as fait un véritable exploit.
Je pense que mon patron voudrait t'embaucher s'il savait.
ulis qui se sent revivre :-)
> > Ben alors Maurice : pas de commentaire ? C'est toujours pas bon ou ça
> > te laisse sans voix ? ;-)
>
> Laisse moi le temps de compter, sacrebleu !
>
> - ton code en fait autant,
> - il définit bien p et les deux couleurs (bon on va faire comme si)
> - il n'utilise pas d'autre constante (..., comme l'autre, quoi)
> - il a 44 commandes en bleu alors que l'autre en a 59
>
> Tu as donc réussi à faire une économie de plus de 20%
> (bon, foreach ... break remplacé par foreach ... {}, c'est facile,
> mais valable)
>
> Bravo ! Tu as fait un véritable exploit.
Youhou !! :-) J'ai gagné !
D'un autre côté c'est pas vraiment (voire vraiment pas) le genre de
code à montrer aux débutants ou à prendre en exemple. C'est un grand
fou ton "patron" ! ;-)
Tiens, c'est intéressant...je connaissais pas ce genre de choses.
en regardant http://wfr.tcl.tk/expr
on (enfin je) apprend pas grand-chose sur cette affaire.
En testant avec tkcon, il me semble donc que
expr {$n << $p} remplace expr {pow(2,$p)*$n}
Si je dis pas de bêtises, il s'agit donc d'une sorte de décalage de
bits.
Par contre je ne comprends pas l'autre opérateur : >>
Mes questions :
- pourquoi utiliser dans le script : 2 << $p plutôt que : 1 << $p+1 ?
- pourquoi "éviter" : pow(2,$p+1) ?
- à quoi ça sert (question qui tue) typiquement ?
- c'est quoi >> alors ?
--
cordialement
david cobac
Merci à toi , O grand Ulis, toi qui a su vaincre tant d'épreuves au
cours de ton long voyage dans les profondeurs de Tcl...
(je suis en forme, ce soir !)
-+- vincent v in fr.comp.lang.tcl -+-
oups enfin expr {int(pow(2,$p)*$n)}
--
cordialement
david cobac
<david z> Serait-ce là la manifestation d'une envie irrépressible
d'essayer OS X ?
<ulis> non, non.
C'est que mon i-book est un béta.
pardon, mon i-book est déjà en beta.
-+- fr.comp.lang.tcl -+-
On gagne peut-être un cycle d'exécution (au prix du CPU, c'est pas
grand chose)
> - pourquoi "éviter" : pow(2,$p+1) ?
on passe d'un ordre d'exponentiation (un gros sous-programme) à un
ordre de décalage (une instruction)
(au prix du CPU, c'est un peu plus)
> - à quoi ça sert (question qui tue) typiquement ?
heu ???
Quel est le sujet de "à quoi ça sert"
Les ordres de décalages ? Bin à décaler des bits. Ca permet
d'optimiser certaines opérations couteuses sur les nombres. Les
exponentiations par des multiples de 2 par exemple.
> - c'est quoi >> alors ?
Décalage à droite
Pour les profs de maths :
8 >> 2 :=: 8 /2^2
> Merci à toi , O grand Ulis, toi qui a su vaincre tant d'épreuves au
> cours de ton long voyage dans les profondeurs de Tcl...
> (je suis en forme, ce soir !)
> -+- vincent v in fr.comp.lang.tcl -+-
de rien ;-)
> Tiens, c'est intéressant...je connaissais pas ce genre de choses.
> en regardant http://wfr.tcl.tk/expr
> on (enfin je) apprend pas grand-chose sur cette affaire.
> En testant avec tkcon, il me semble donc que
> expr {$n << $p} remplace expr {pow(2,$p)*$n}
> Si je dis pas de bêtises, il s'agit donc d'une sorte de décalage de
> bits.
> Par contre je ne comprends pas l'autre opérateur : >>
>
> Mes questions :
> - pourquoi utiliser dans le script : 2 << $p plutôt que : 1 << $p+1 ?
Parce que ça va plus vite
> - pourquoi "éviter" : pow(2,$p+1) ?
Parce que ça va moins vite
> - à quoi ça sert (question qui tue) typiquement ?
- à multiplier et diviser vite par 2
- à retourner les octets dans les mots pour passer du big au little endian
- à mettre une tripotée de flags (0 ou 1) dans une même variable le flag
n étant retrouvable par f = (var >> n) & 1 et activable via var = (f <<
n) | var on peut même transformer ça en va et vient en utilisant un XOR
à la place du OR.
- A obscurcir le code quand ce n'est pas nécessaire de l'optimiser à e
point :)
Exemples parlant:
3 >> 2 ça donne 0 : 00000000
3 >> 1 ça donne 1 : 00000001
3 s'écrit en binaire 00000011
3 << 1 ça donne 6 : 00000110
3 << 2 ça donne 12: 00001100
on "tire" d'un côté ou de l'autre pour déplacer un bit. Mais alors,
comment est on sûr que c'est un 0 qui arrive ? Parce que le monde est
bien fait maintenant, mais ça n'a pas toujours été le cas.
Les vieux barbus valident ça avec un masque.
01111111 pour >> 1
et
11111110 pour << 1
Donc pour être sûr on doit/devrait écrire
resultat = (depart >> 1) & 0x7f
resultat = (depart >> 2) & 0x3f
resultat = (depart >> 8) & 0x0f
resultat = (depart << 1) & 0xf7
resultat = (depart << 2) & 0xf3
resultat = (depart << 8) & 0xf0
par exemple.
> - c'est quoi >> alors ?
>
Pareil dans l'autre sens.
a+
--
Xavier Garreau
http://www.xgarreau.org/