@@ -22,6 +22,7 @@ def set_cell(self, obj, pos, val, dirty={}):
2222 we prepare a possible flip
2323 or we try to complete the flip if it has been prepared previously
2424 """
25+ #print("in the adapter for pos =", pos, "val =", val, "dirty =", dirty)
2526 # Find out the relevant matching for 'pos'
2627 d1 = obj .domino_for_position (pos )
2728 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={}):
3435 continue
3536 if d2 in d1 .neighbors ():
3637 # Do the flip
38+ print ("before flipping :" , d1 , d2 )
3739 obj .flip (d1 , d2 )
40+ print ("after flipping :" , d1 , d2 )
3841 return obj
3942 return Exception ("Please select a second domino!" )
4043 else :
@@ -43,7 +46,7 @@ def set_cell(self, obj, pos, val, dirty={}):
4346
4447class ddlink (dlink ):
4548 """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
4750 Usage: b1 = Button(description = 'B1')
4851 b2 = Button(description = 'B2')
4952 b3 = Button(description = 'B3')
@@ -101,6 +104,9 @@ def _busy_updating(self):
101104 def _update (self , change ):
102105 #if self.updating or self.target[0].donottrack:
103106 # return
107+ #if self.target[0].donottrack:
108+ # print("on sort ici !!!")
109+ # return
104110 with self ._busy_updating ():
105111 if self .logic == 'and' :
106112 if self .intermediate_value == False : # aucun bouton pressé avant
@@ -142,22 +148,26 @@ class Domino(HasTraits):
142148 boutons qu'il contient étant, eux, des widgets"""
143149 value = Bool ()
144150
145- def __init__ (self , parent , b1 , b2 ):
151+ def __init__ (self , parent , b1 , b2 , link = True ):
146152 """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
147157 super (Domino , self ).__init__ ()
158+ self .value = False
148159 self .geometry = DominoGeometry (b1 .position , b2 .position )
149160 self .parent = parent
150161 self .key = None
151162 self .first = b1
152163 self .second = b2
153164 self .buttons = (b1 ,b2 )
154- b1 .link = dlink ((b1 , 'value' ), (b2 , 'value' ))
155- b2 .link = dlink ((b2 , 'value' ), (b1 , 'value' ))
156165 self .link = None
157166 self .direction = None
158167 self .orientation = None
159168 self .compute ()
160- self .donottrack = False
169+ if link :
170+ self .set_links ()
161171
162172 def __repr__ (self ):
163173 if self .value :
@@ -168,7 +178,6 @@ def compute(self, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
168178 """Compute buttons relative positions.
169179 Create double directional link from both buttons"""
170180 self .geometry .compute ()
171- #print(self.geometry.__dict__)
172181 if css_classes :
173182 for cl in css_classes :
174183 self .first .remove_class (cl )
@@ -196,26 +205,21 @@ def compute(self, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
196205 elif self .geometry .orientation == - 1 :
197206 self .first .add_class ('bottom' )
198207 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' ))
199212 self .link = ddlink (((self .first , 'value' ), (self .second , 'value' )), (self , 'value' ), logic = 'and' , set_at_init = False ) # Fresh ddlink
200213
201214 def is_pressed (self ):
202215 """Is the domino pressed?"""
203216 return self .value
204217
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"""
218220 self .link .unlink ()
221+ self .first .link .unlink ()
222+ self .second .link .unlink ()
219223
220224 def flip (self , other ):
221225 """Flip self with some neighboring domino"""
@@ -246,6 +250,8 @@ def __init__(self, g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
246250 with flipping aztec diamond graph `g`
247251 """
248252 self .css_classes = css_classes
253+ #self.resetting = None
254+ #self.resetting = True
249255 super (FlippingDominosWidget , self ).__init__ (g , adapter = FlippingDominosAdapter (),
250256 cell_layout = smallblyt ,
251257 cell_widget_classes = [styled_button_cell (),
@@ -256,6 +262,8 @@ def __init__(self, g, css_classes=['b0', 'b1', 'b2', 'b3', 'b4']):
256262 ],
257263 cell_widget_class_index = make_cell_widget_class_index (g ),
258264 blank_widget_class = BlankButton )
265+ self .resetting_cells = []
266+
259267 def draw (self ):
260268 self .dominos = {}
261269 super (FlippingDominosWidget , self ).draw ()
@@ -279,8 +287,10 @@ def apply_matching(self, matching):
279287 """Apply a matching"""
280288 self .dominos = {}
281289 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+ )
284294
285295 def update (self ):
286296 self .apply_matching (self .value .matching )
@@ -292,14 +302,8 @@ def domino_for_position(self, pos):
292302 geometry = self .value .domino_for_position (pos )
293303 for t in (geometry .first , geometry .second ):
294304 if t in self .dominos :
295- print ("domino for position" , t , ":" , self .dominos [t ].geometry , self .dominos [t ].value )
296305 return self .dominos [t ]
297306
298- def not_tracking (self , value ):
299- self .donottrack = value
300- for d in self .dominos .values ():
301- d .donottrack = value
302-
303307 @observe (All )
304308 def set_cell (self , change ):
305309 if self .donottrack :
@@ -309,37 +313,92 @@ def set_cell(self, change):
309313 else :
310314 print ("set_cell()" , change .name )
311315 # 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
318324 other = None
319325 if self .dirty :
320326 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 ))
321330 other = self .domino_for_position (pos )
322331 if other and not other .geometry in domino .geometry .neighbors ():
323332 other = None
324333 continue # we don't have to reset everything, I guess(hope)
325334 if not other :
335+ # Feed the 'dirty' dict and return
326336 self .dirty [domino .geometry .first ] = True
327337 self .dirty [domino .geometry .second ] = True
328- self .not_tracking (False )
329338 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
335340 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
343403 self .reset_dirty ()
344- self .update ()
345- self .not_tracking (False )
404+ self .donottrack = False
0 commit comments