# # Graphic display for dimer model on grid # Bryan Clair 2012 # from cs1graphics import * import DimerGrid class DimerDisplay: """A graphic display of a Dimer model""" def __init__(self,state,bricksize=20,colors=['red','yellow','green','blue']): """Create display and all possible dimers. Should be called with an actual tiled state, no undefined spots.""" # Each dimer is stored at its top left corner site. self._state = state self._sizex,self._sizey = state.size() self._spacing = bricksize # grid width self._c = Canvas(self._sizex*self._spacing, self._sizey*self._spacing) self._c.setAutoRefresh(False) self._updateFrequency = 1 self._timeToUpdate = 1 # Create the dimers self._horizontal = list() self._vertical = list() for x in range(self._sizex): hcol = list() vcol = list() for y in range(self._sizey): if self._state[x,y] == False: # not part of the tiled region h = None v = None else: h = Rectangle(2*self._spacing, self._spacing, Point(x * self._spacing + self._spacing, y*self._spacing + self._spacing/2)) v = Rectangle(self._spacing, 2*self._spacing, Point(x * self._spacing + self._spacing/2, y*self._spacing + self._spacing)) h.setFillColor(colors[(x+y)%2]) v.setFillColor(colors[(x+y)%2 + 2]) # Visible dimers if self._state[x,y] == (1,0): self._c.add(h) elif self._state[x,y] == (0,1): self._c.add(v) elif self._state[x,y] == True: # No dimer here - shouldn't occur if called with properly initialized state raise ValueError('Improperly initialized state.') hcol.append(h) vcol.append(v) self._horizontal.append(hcol) self._vertical.append(vcol) self._c.refresh() def getCanvas(self): """Access graphics display.""" return self._c def setUpdateFrequency(self, steps): """Only refresh display after given number of steps occur.""" self._updateFrequency = steps self._timeToUpdate = min(self._timeToUpdate,steps) def update(self,x,y): """Update the graphical display, given that (x,y) just changed""" if self._state[x,y] == (1,0): # was vertical, now horizontal self._c.add(self._horizontal[x][y]) self._c.add(self._horizontal[x][y+1]) self._c.remove(self._vertical[x][y]) self._c.remove(self._vertical[x+1][y]) else: # was horizontal, now vertical self._c.add(self._vertical[x][y]) self._c.add(self._vertical[x+1][y]) self._c.remove(self._horizontal[x][y]) self._c.remove(self._horizontal[x][y+1]) self._timeToUpdate -= 1 if self._timeToUpdate == 0: self._c.refresh() self._timeToUpdate = self._updateFrequency if __name__ == '__main__': p = DimerGrid.AztecDiamond(8) p.fillhorizontal() d = DimerDisplay(p) i = 1000 print i while i > 0: val = p.onestep() if val: (x,y) = val d.update(x,y) i -= 1 if i % 100 == 0: print i print p raw_input('hit return') d.getCanvas().close()