@@ -22,6 +22,7 @@ def set_cell(self, obj, pos, val, dirty={}):
22
22
we prepare a possible flip
23
23
or we try to complete the flip if it has been prepared previously
24
24
"""
25
+ #print("in the adapter for pos =", pos, "val =", val, "dirty =", dirty)
25
26
# Find out the relevant matching for 'pos'
26
27
d1 = obj .domino_for_position (pos )
27
28
if dirty : # if i'm a neighbor, then flip and return a new obj ; else return an error
@@ -34,7 +35,9 @@ def set_cell(self, obj, pos, val, dirty={}):
34
35
continue
35
36
if d2 in d1 .neighbors ():
36
37
# Do the flip
38
+ print ("before flipping :" , d1 , d2 )
37
39
obj .flip (d1 , d2 )
40
+ print ("after flipping :" , d1 , d2 )
38
41
return obj
39
42
return Exception ("Please select a second domino!" )
40
43
else :
@@ -43,7 +46,7 @@ def set_cell(self, obj, pos, val, dirty={}):
43
46
44
47
class ddlink (dlink ):
45
48
"""Double directional link with logic = or/and/none.
46
- Double_source is a tuple of (source, target ) tuples
49
+ `double_source` is a tuple of (source, traitname ) tuples
47
50
Usage: b1 = Button(description = 'B1')
48
51
b2 = Button(description = 'B2')
49
52
b3 = Button(description = 'B3')
@@ -101,6 +104,9 @@ def _busy_updating(self):
101
104
def _update (self , change ):
102
105
#if self.updating or self.target[0].donottrack:
103
106
# return
107
+ #if self.target[0].donottrack:
108
+ # print("on sort ici !!!")
109
+ # return
104
110
with self ._busy_updating ():
105
111
if self .logic == 'and' :
106
112
if self .intermediate_value == False : # aucun bouton pressé avant
@@ -142,22 +148,26 @@ class Domino(HasTraits):
142
148
boutons qu'il contient étant, eux, des widgets"""
143
149
value = Bool ()
144
150
145
- def __init__ (self , parent , b1 , b2 ):
151
+ def __init__ (self , parent , b1 , b2 , link = True ):
146
152
"""A domino has a parent widget and is made of 2 buttons"""
153
+ b1 .link = None
154
+ b2 .link = None
155
+ b1 .value = False
156
+ b2 .value = False
147
157
super (Domino , self ).__init__ ()
158
+ self .value = False
148
159
self .geometry = DominoGeometry (b1 .position , b2 .position )
149
160
self .parent = parent
150
161
self .key = None
151
162
self .first = b1
152
163
self .second = b2
153
164
self .buttons = (b1 ,b2 )
154
- b1 .link = dlink ((b1 , 'value' ), (b2 , 'value' ))
155
- b2 .link = dlink ((b2 , 'value' ), (b1 , 'value' ))
156
165
self .link = None
157
166
self .direction = None
158
167
self .orientation = None
159
168
self .compute ()
160
- self .donottrack = False
169
+ if link :
170
+ self .set_links ()
161
171
162
172
def __repr__ (self ):
163
173
if self .value :
@@ -168,7 +178,6 @@ def compute(self, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
168
178
"""Compute buttons relative positions.
169
179
Create double directional link from both buttons"""
170
180
self .geometry .compute ()
171
- #print(self.geometry.__dict__)
172
181
if css_classes :
173
182
for cl in css_classes :
174
183
self .first .remove_class (cl )
@@ -196,26 +205,21 @@ def compute(self, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
196
205
elif self .geometry .orientation == - 1 :
197
206
self .first .add_class ('bottom' )
198
207
self .second .add_class ('top' )
208
+
209
+ def set_links (self ):
210
+ self .first .link = dlink ((self .first , 'value' ), (self .second , 'value' ))
211
+ self .second .link = dlink ((self .second , 'value' ), (self .first , 'value' ))
199
212
self .link = ddlink (((self .first , 'value' ), (self .second , 'value' )), (self , 'value' ), logic = 'and' , set_at_init = False ) # Fresh ddlink
200
213
201
214
def is_pressed (self ):
202
215
"""Is the domino pressed?"""
203
216
return self .value
204
217
205
- # def set_value(self, value):
206
- # """Set domino value
207
- # As we have a directional link,
208
- # the domino value will also be set.
209
- # """
210
- # self.link.unlink()
211
- # self.first.value = value
212
- # self.second.value = value
213
- # self.link = ddlink(((self.first, 'value'), (self.second, 'value')), (self, 'value'), logic='and', set_at_init=False) # Fresh ddlink
214
-
215
- def reset (self ):
216
- """Full domino reset"""
217
- #self.set_value(False)
218
+ def unlink (self ):
219
+ """Full domino unlink"""
218
220
self .link .unlink ()
221
+ self .first .link .unlink ()
222
+ self .second .link .unlink ()
219
223
220
224
def flip (self , other ):
221
225
"""Flip self with some neighboring domino"""
@@ -246,6 +250,8 @@ def __init__(self, g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
246
250
with flipping aztec diamond graph `g`
247
251
"""
248
252
self .css_classes = css_classes
253
+ #self.resetting = None
254
+ #self.resetting = True
249
255
super (FlippingDominosWidget , self ).__init__ (g , adapter = FlippingDominosAdapter (),
250
256
cell_layout = smallblyt ,
251
257
cell_widget_classes = [styled_button_cell (),
@@ -256,6 +262,8 @@ def __init__(self, g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
256
262
],
257
263
cell_widget_class_index = make_cell_widget_class_index (g ),
258
264
blank_widget_class = BlankButton )
265
+ self .resetting_cells = []
266
+
259
267
def draw (self ):
260
268
self .dominos = {}
261
269
super (FlippingDominosWidget , self ).draw ()
@@ -279,8 +287,10 @@ def apply_matching(self, matching):
279
287
"""Apply a matching"""
280
288
self .dominos = {}
281
289
for d in matching :
282
- self .match (self .children [d .first [0 ]].children [d .first [1 ]],
283
- self .children [d .second [0 ]].children [d .second [1 ]])
290
+ self .match (
291
+ self .children [d .first [0 ]].children [d .first [1 ]],
292
+ self .children [d .second [0 ]].children [d .second [1 ]]
293
+ )
284
294
285
295
def update (self ):
286
296
self .apply_matching (self .value .matching )
@@ -292,14 +302,8 @@ def domino_for_position(self, pos):
292
302
geometry = self .value .domino_for_position (pos )
293
303
for t in (geometry .first , geometry .second ):
294
304
if t in self .dominos :
295
- print ("domino for position" , t , ":" , self .dominos [t ].geometry , self .dominos [t ].value )
296
305
return self .dominos [t ]
297
306
298
- def not_tracking (self , value ):
299
- self .donottrack = value
300
- for d in self .dominos .values ():
301
- d .donottrack = value
302
-
303
307
@observe (All )
304
308
def set_cell (self , change ):
305
309
if self .donottrack :
@@ -309,37 +313,92 @@ def set_cell(self, change):
309
313
else :
310
314
print ("set_cell()" , change .name )
311
315
# Try to reset everything right now to avoid unwanted propagations
312
- domino = self .domino_for_position (extract_coordinates (change .name ))
313
- # First, we want to make the pressed domino visible to the user
314
- self .not_tracking (True )
315
- domino .first .value = True
316
- domino .second .value = True
317
- # Any pressed neighbor?
316
+ click_pos = extract_coordinates (change .name )
317
+ domino = self .domino_for_position (click_pos )
318
+ if not domino : # or domino.donottrack:
319
+ return
320
+ # The domino must be entirely pressed
321
+ if not domino .first .value or not domino .second .value :
322
+ return
323
+ # The domino must have a pressed neighbor
318
324
other = None
319
325
if self .dirty :
320
326
for pos in self .dirty :
327
+ if other and other .geometry != self .domino_for_position (pos ).geometry :
328
+ raise Exception ("on a un double dans les voisins pressés: %s et %s" % (
329
+ other .geometry , self .domino_for_position (pos ).geometry ))
321
330
other = self .domino_for_position (pos )
322
331
if other and not other .geometry in domino .geometry .neighbors ():
323
332
other = None
324
333
continue # we don't have to reset everything, I guess(hope)
325
334
if not other :
335
+ # Feed the 'dirty' dict and return
326
336
self .dirty [domino .geometry .first ] = True
327
337
self .dirty [domino .geometry .second ] = True
328
- self .not_tracking (False )
329
338
return
330
- if domino .link :
331
- domino .link .unlink ()
332
- if other .link :
333
- other .link .unlink ()
334
- self .not_tracking (False )
339
+ # Do the flip
335
340
super (FlippingDominosWidget , self ).set_cell (change )
336
- self .not_tracking (True )
337
- # And now, we want to reset everything before the flip
338
- domino .first .value = False
339
- domino .second .value = False
340
- other .first .value = False
341
- other .second .value = False
342
- # Now, recreate the 2 dominos and compute style
341
+ # Unlink
342
+ self .donottrack = True
343
+ domino .unlink ()
344
+ other .unlink ()
345
+ # Build our new dominos
346
+ new_domino , new_other = None , None
347
+ for g1 in self .value .matching :
348
+ if g1 .first == domino .geometry .first or g1 .first == other .geometry .first :
349
+ d1 , d2 = domino .geometry , other .geometry
350
+ if g1 .first == domino .geometry .first :
351
+ new_domino = Domino (
352
+ self ,
353
+ self .children [g1 .first [0 ]].children [g1 .first [1 ]],
354
+ self .children [g1 .second [0 ]].children [g1 .second [1 ]],
355
+ link = False
356
+ )
357
+ self .dominos [domino .key ] = new_domino
358
+ for g2 in g1 .neighbors ():
359
+ if not g2 in self .value .matching :
360
+ continue
361
+ if (other .key in (g2 .first , g2 .second )) or \
362
+ (other .key == g1 .second and domino .geometry .second in (g2 .first , g2 .second )):
363
+ new_other = Domino (
364
+ self ,
365
+ self .children [g2 .first [0 ]].children [g2 .first [1 ]],
366
+ self .children [g2 .second [0 ]].children [g2 .second [1 ]],
367
+ link = False
368
+ )
369
+ self .dominos [other .key ] = new_other
370
+ break
371
+ elif g1 .first == other .geometry .first :
372
+ new_other = Domino (
373
+ self ,
374
+ self .children [g1 .first [0 ]].children [g1 .first [1 ]],
375
+ self .children [g1 .second [0 ]].children [g1 .second [1 ]],
376
+ link = False
377
+ )
378
+ self .dominos [other .key ] = new_other
379
+ for g2 in g1 .neighbors ():
380
+ if not g2 in self .value .matching :
381
+ continue
382
+ if (domino .key in (g2 .first , g2 .second )) or \
383
+ (domino .key == g1 .second and other .geometry .second in (g2 .first , g2 .second )):
384
+ new_domino = Domino (
385
+ self ,
386
+ self .children [g2 .first [0 ]].children [g2 .first [1 ]],
387
+ self .children [g2 .second [0 ]].children [g2 .second [1 ]],
388
+ link = False
389
+ )
390
+ self .dominos [domino .key ] = new_domino
391
+ break
392
+ if new_domino and new_other :
393
+ break
394
+ # Check that new dominos are sound and the flip has actually been performed
395
+ assert (new_domino is not None and new_other is not None )
396
+ assert (new_domino .geometry != domino .geometry and new_other .geometry != other .geometry )
397
+ # Compute the dominos
398
+ new_domino .compute ()
399
+ new_other .compute ()
400
+ new_domino .set_links ()
401
+ new_other .set_links ()
402
+ # Reset
343
403
self .reset_dirty ()
344
- self .update ()
345
- self .not_tracking (False )
404
+ self .donottrack = False
0 commit comments