class XLABaseTest(unittest.TestCase): """Provides the model and config of PolI""" def setUp(self, mPaths, cPath): mPath = xlinkanalyzer.__path__[0] xlaTestPath = path.join(path.split(mPath)[0], 'pytests/test_data') self.xlaTestMPaths = [path.join(xlaTestPath, _path) for _path in mPaths] self.xlaTestCPath = path.join(xlaTestPath, cPath) self.config = Assembly() self.rManager = ResourceManager(self.config) self.rManager.loadAssembly(None, self.xlaTestCPath) [chimera.openModels.open(_path) for _path in self.xlaTestMPaths] self.models = chimera.openModels.list() # self.xla_models = [Model(chimeraModel, self.config) for chimeraModel in self.models] def _createTestWindow(self): self.testWindow = Toplevel() w = self.testWindow.winfo_screenwidth() h = self.testWindow.winfo_screenheight() x = w/2 y = h/2 self.testWindow.geometry("+%d+%d" % (x, y)) self.testWindow.geometry("400x200") def tearDown(self): chimera.openModels.close(chimera.openModels.list())
class XLABaseTest(unittest.TestCase): """Provides the model and config of PolI""" def setUp(self, mPaths, cPath): mPath = xlinkanalyzer.__path__[0] xlaTestPath = path.join(path.split(mPath)[0], 'pytests/test_data') self.xlaTestMPaths = [ path.join(xlaTestPath, _path) for _path in mPaths ] self.xlaTestCPath = path.join(xlaTestPath, cPath) self.config = Assembly() self.rManager = ResourceManager(self.config) self.rManager.loadAssembly(None, self.xlaTestCPath) [chimera.openModels.open(_path) for _path in self.xlaTestMPaths] self.models = chimera.openModels.list() # self.xla_models = [Model(chimeraModel, self.config) for chimeraModel in self.models] def _createTestWindow(self): self.testWindow = Toplevel() w = self.testWindow.winfo_screenwidth() h = self.testWindow.winfo_screenheight() x = w / 2 y = h / 2 self.testWindow.geometry("+%d+%d" % (x, y)) self.testWindow.geometry("400x200") def tearDown(self): chimera.openModels.close(chimera.openModels.list())
def createUser(self, username, password, fname, lname): if self.gui.btd.database.newUser(username, password, fname, lname): popup = Toplevel() popup.title("Account created!") windowWidth = popup.winfo_screenwidth() windowHeight = popup.winfo_screenheight() width = .25 * windowWidth height = .1 * windowHeight x = (windowWidth - width) / 2 y = (windowHeight - height) / 2 popup.geometry("%dx%d+%d+%d" % (width, height, x, y)) popup.update() Label( popup, text="Your new account has been successfully created!").pack() Button(popup, text="Dismiss", command=popup.destroy).pack() self.gui.screenChange(title.titlePage(self.root, self.gui)) else: popup = Toplevel() popup.title("Username Exists!") windowWidth = popup.winfo_screenwidth() windowHeight = popup.winfo_screenheight() width = .25 * windowWidth height = .1 * windowHeight x = (windowWidth - width) / 2 y = (windowHeight - height) / 2 popup.geometry("%dx%d+%d+%d" % (width, height, x, y)) popup.update() Label(popup, text="A user account with that username already exists!" ).pack() Button(popup, text="Dismiss", command=popup.destroy).pack()
def createUser(self, username, password, fname, lname): if self.gui.btd.database.newUser(username, password, fname, lname): popup = Toplevel() popup.title("Account created!") windowWidth = popup.winfo_screenwidth() windowHeight = popup.winfo_screenheight() width = .25 * windowWidth height = .1 * windowHeight x = (windowWidth - width) / 2 y = (windowHeight - height) / 2 popup.geometry("%dx%d+%d+%d" % (width, height, x, y)) popup.update() Label(popup, text="Your new account has been successfully created!").pack() Button(popup, text="Dismiss", command=popup.destroy).pack() self.gui.screenChange(title.titlePage(self.root, self.gui)) else: popup = Toplevel() popup.title("Username Exists!") windowWidth = popup.winfo_screenwidth() windowHeight = popup.winfo_screenheight() width = .25 * windowWidth height = .1 * windowHeight x = (windowWidth - width) / 2 y = (windowHeight - height) / 2 popup.geometry("%dx%d+%d+%d" % (width, height, x, y)) popup.update() Label(popup, text="A user account with that username already exists!").pack() Button(popup, text="Dismiss", command=popup.destroy).pack()
def loginCommand(self, username, password): if self.gui.btd.database.login(username, password): self.gui.screenChange(welcomePage(self.root, self.gui)) else: popup = Toplevel() popup.title("Incorrect") windowWidth = popup.winfo_screenwidth() windowHeight = popup.winfo_screenheight() width = .25 * windowWidth height = .1 * windowHeight x = (windowWidth - width) / 2 y = (windowHeight - height) / 2 popup.geometry("%dx%d+%d+%d" % (width, height, x, y)) popup.update() Label(popup, text="Incorrect username or password!").pack() Button(popup, text="Dismiss", command=popup.destroy).pack()
class ContinuousTMPViewer(object): def __init__(self, suction_height, regions, tl_x=0, tl_y=0, width=500, height=150, title='Grid', background='tan'): self.tk = Tk() # tk.geometry('%dx%d+%d+%d'%(width, height, 100, 0)) self.tk.withdraw() self.top = Toplevel(self.tk) self.top.wm_title(title) self.top.protocol('WM_DELETE_WINDOW', self.top.destroy) self.suction_height = suction_height self.regions = regions self.tl_x = tl_x self.tl_y = tl_y self.width = width self.height = height self.canvas = Canvas(self.top, width=self.width, height=self.height, background=background) self.canvas.pack() # self.center() self.move_frame(self.tl_x, self.tl_y) max_width = max( map(get_width, regions.values())) # Really should take width of max minus min self.dist_to_pixel = (self.width - 2 * PIXEL_BUFFER ) / max_width # Maintains aspect ratio self.dist_width = self.width / self.dist_to_pixel self.dist_height = self.height / self.dist_to_pixel self.ground_height = self.height - self.dist_to_pixel * ENV_HEIGHT self.robot_dist = self.dist_height / 2. self.robot = [] self.blocks = [] self.holding = None self.environment = [] self.draw_environment() def center(self): self.top.update_idletasks() w = self.top.winfo_screenwidth() h = self.top.winfo_screenheight() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) x = w / 2 - size[0] / 2 y = h / 2 - size[1] / 2 self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def move_frame(self, x, y): self.top.update_idletasks() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def scale_x(self, x): # x \in [-self.dist_width/2, self.dist_width/2] return self.dist_to_pixel * (x + self.dist_width / 2.) def scale_y(self, y): # y \in [0, self.dist_height] return self.ground_height - self.dist_to_pixel * y def draw_block(self, x, y, width, height, name='', color='blue'): self.blocks.extend([ self.canvas.create_rectangle(self.scale_x(x - width / 2.), self.scale_y(y), self.scale_x(x + width / 2.), self.scale_y(y + height), fill=color, outline='black', width=2), self.canvas.create_text(self.scale_x(x), self.scale_y(y + height / 2), text=name), ]) # def draw_holding(self, x, width, height, color='blue'): # self.holding = self.canvas.create_rectangle(self.scale_x(x - width / 2.), # self.scale_y(self.robot_dist - SUCTION_HEIGHT / 2 - height), # self.scale_x(x + width / 2.), # self.scale_y(self.robot_dist - SUCTION_HEIGHT / 2), # fill=color, outline='black', width=2) def draw_region(self, region, name='', color='red'): x1, x2 = map(self.scale_x, region) y1, y2 = self.ground_height, self.height self.environment.extend([ self.canvas.create_rectangle(x1, y1, x2, y2, fill=color, outline='black', width=2), self.canvas.create_text((x1 + x2) / 2, (y1 + y2) / 2, text=name), ]) def draw_environment(self): # TODO: automatically draw in order self.environment = [] for name, region in sorted(self.regions.items(), key=lambda pair: get_width(pair[1]), reverse=True): self.draw_region(region, name=name, color=name) def draw_robot( self, x, y, color='yellow' ): # TODO - could also visualize as top grasps instead of side grasps #y = self.robot_dist self.robot = [ self.canvas.create_rectangle( self.scale_x(x - SUCTION_WIDTH / 2.), self.scale_y(y - self.suction_height / 2.), self.scale_x(x + SUCTION_WIDTH / 2.), self.scale_y(y + self.suction_height / 2.), fill=color, outline='black', width=2), self.canvas.create_rectangle( self.scale_x(x - STEM_WIDTH / 2.), self.scale_y(y + self.suction_height / 2.), self.scale_x(x + STEM_WIDTH / 2.), self.scale_y(y + self.suction_height / 2. + STEM_HEIGHT), fill=color, outline='black', width=2), ] def clear_state(self): for block in self.blocks: self.canvas.delete(block) for part in self.robot: self.canvas.delete(part) if self.holding is not None: self.canvas.delete(self.holding) def clear_all(self): self.canvas.delete('all') def save(self, filename): # TODO: screen recording based on location like I did before # TODO: only works on windows # self.canvas.postscript(file='%s.ps'%filename, colormode='color') #from PIL import ImageGrab try: import pyscreenshot as ImageGrab except ImportError: return None x, y = self.top.winfo_x(), 2 * self.top.winfo_y() width, height = self.top.winfo_width(), self.top.winfo_height( ) # winfo_width, winfo_reqheight path = filename + '.png' ImageGrab.grab((x, y, x + width, y + height)).save(path) return path
class ContinuousTMPViewer(object): def __init__(self, regions, tl_x=0, tl_y=0, width=500, height=250, title='Grid', background='tan'): self.tk = Tk() # tk.geometry('%dx%d+%d+%d'%(width, height, 100, 0)) self.tk.withdraw() self.top = Toplevel(self.tk) self.top.wm_title(title) self.top.protocol('WM_DELETE_WINDOW', self.top.destroy) self.regions = regions self.tl_x = tl_x self.tl_y = tl_y self.width = width self.height = height self.canvas = Canvas(self.top, width=self.width, height=self.height, background=background) self.canvas.pack() # self.center() self.move_frame(self.tl_x, self.tl_y) self.dist_to_pixel = (self.width - 2 * PIXEL_BUFFER) / get_width( regions[GROUND]) # Maintains aspect ratio self.dist_width = self.width / self.dist_to_pixel self.dist_height = self.height / self.dist_to_pixel self.ground_height = self.height - self.dist_to_pixel * ENV_HEIGHT self.robot_dist = self.dist_height / 2. self.robot = [] self.blocks = [] self.holding = None self.environment = [] self.draw_environment() def center(self): self.top.update_idletasks() w = self.top.winfo_screenwidth() h = self.top.winfo_screenheight() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) x = w / 2 - size[0] / 2 y = h / 2 - size[1] / 2 self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def move_frame(self, x, y): self.top.update_idletasks() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def scale_x(self, x): # x \in [-self.dist_width/2, self.dist_width/2] return self.dist_to_pixel * (x + self.dist_width / 2.) def scale_y(self, y): # y \in [0, self.dist_height] return self.ground_height - self.dist_to_pixel * y def draw_block(self, x, width, height, color='blue'): self.blocks.append( self.canvas.create_rectangle(self.scale_x(x - width / 2.), self.scale_y(0), self.scale_x(x + width / 2.), self.scale_y(height), fill=color, outline='black', width=2)) # def draw_holding(self, x, width, height, color='blue'): # self.holding = self.canvas.create_rectangle(self.scale_x(x - width / 2.), # self.scale_y(self.robot_dist - SUCTION_HEIGHT / 2 - height), # self.scale_x(x + width / 2.), # self.scale_y(self.robot_dist - SUCTION_HEIGHT / 2), # fill=color, outline='black', width=2) def draw_region(self, region, color='red'): x1, x2 = map(self.scale_x, region) self.environment.append( self.canvas.create_rectangle(x1, self.ground_height, x2, self.height, fill=color, outline='black', width=2)) def draw_environment(self, table_color='lightgrey'): self.environment = [] self.draw_region(self.regions[GROUND], color=table_color) for name, region in self.regions.items(): if name != GROUND: self.draw_region(region) def draw_robot( self, x, y, color='yellow' ): # TODO - could also visualize as top grasps instead of side grasps #y = self.robot_dist self.robot = [ self.canvas.create_rectangle(self.scale_x(x - SUCTION_WIDTH / 2.), self.scale_y(y - SUCTION_HEIGHT / 2.), self.scale_x(x + SUCTION_WIDTH / 2.), self.scale_y(y + SUCTION_HEIGHT / 2.), fill=color, outline='black', width=2), self.canvas.create_rectangle(self.scale_x(x - STEM_WIDTH / 2.), self.scale_y(y + SUCTION_HEIGHT / 2.), self.scale_x(x + STEM_WIDTH / 2.), self.scale_y(y + SUCTION_HEIGHT / 2. + STEM_HEIGHT), fill=color, outline='black', width=2), ] def clear_state(self): for block in self.blocks: self.canvas.delete(block) for part in self.robot: self.canvas.delete(part) if self.holding is not None: self.canvas.delete(self.holding) def clear_all(self): self.canvas.delete('all') def save(self, filename): # self.canvas.postscript(file='%s.ps'%filename, colormode='color') from PIL import ImageGrab ImageGrab.grab((0, 0, self.width, self.height)).save(filename + '.jpg')
class ContinuousTMPViewer(object): def __init__(self, env_region, regions=[], tl_x=0, tl_y=0, width=500, height=250, title='Grid', background='tan'): self.tk = Tk() self.tk.withdraw() self.top = Toplevel(self.tk) self.top.wm_title(title) self.top.protocol('WM_DELETE_WINDOW', self.top.destroy) self.env_region = env_region self.regions = regions self.tl_x = tl_x self.tl_y = tl_y self.width = width self.height = height self.canvas = Canvas(self.top, width=self.width, height=self.height, background=background) self.canvas.pack() self.move_frame(self.tl_x, self.tl_y) self.dist_to_pixel = (self.width - 2 * PIXEL_BUFFER) / (self.env_region.w) self.dist_width = self.width / self.dist_to_pixel self.dist_height = self.height / self.dist_to_pixel self.ground_height = self.height - self.dist_to_pixel * ENV_HEIGHT self.robot_dist = self.dist_height / 2. self.robot = [] self.blocks = [] self.holding = None self.draw_environment() def center(self): self.top.update_idletasks() w = self.top.winfo_screenwidth() h = self.top.winfo_screenheight() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) x = w / 2 - size[0] / 2 y = h / 2 - size[1] / 2 self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def move_frame(self, x, y): self.top.update_idletasks() size = tuple( int(_) for _ in self.top.geometry().split('+')[0].split('x')) self.top.geometry("%dx%d+%d+%d" % (size + (x, y))) def t_x(self, x): return self.dist_to_pixel * (x + self.dist_width / 2.) def t_y(self, y): return self.ground_height - self.dist_to_pixel * y def draw_block(self, block, x): self.blocks.append( self.canvas.create_rectangle(self.t_x(x - block.w / 2.), self.t_y(0), self.t_x(x + block.w / 2.), self.t_y(block.h), fill=block.color, outline='black', width=2)) def draw_holding(self, block, x): self.holding = self.canvas.create_rectangle( self.t_x(x - block.w / 2.), self.t_y(self.robot_dist - SUCTION_HEIGHT / 2 - block.h), self.t_x(x + block.w / 2.), self.t_y(self.robot_dist - SUCTION_HEIGHT / 2), fill=block.color, outline='black', width=2) def draw_region(self, region): self.environment.append( self.canvas.create_rectangle(self.t_x(region.x - region.w / 2.), self.ground_height, self.t_x(region.x + region.w / 2.), self.height, fill='red', outline='black', width=2)) def draw_environment(self, table_color='lightgrey', bin_color='grey'): self.environment = [ self.canvas.create_rectangle(self.t_x(-self.env_region.w / 2), self.ground_height, self.t_x(self.env_region.w / 2), self.height, fill=table_color, outline='black', width=2) ] for region in self.regions: self.draw_region(region) def draw_robot(self, x, color='yellow'): self.robot = [ self.canvas.create_rectangle( self.t_x(x - SUCTION_WIDTH / 2.), self.t_y(self.robot_dist - SUCTION_HEIGHT / 2.), self.t_x(x + SUCTION_WIDTH / 2.), self.t_y(self.robot_dist + SUCTION_HEIGHT / 2.), fill=color, outline='black', width=2), self.canvas.create_rectangle( self.t_x(x - STEM_WIDTH / 2.), self.t_y(self.robot_dist + SUCTION_HEIGHT / 2.), self.t_x(x + STEM_WIDTH / 2.), self.t_y(self.robot_dist + SUCTION_HEIGHT / 2. + STEM_HEIGHT), fill=color, outline='black', width=2), ] def clear_state(self): for block in self.blocks: self.canvas.delete(block) for part in self.robot: self.canvas.delete(part) if self.holding is not None: self.canvas.delete(self.holding) def clear_all(self): self.canvas.delete('all') def save(self, filename): from PIL import ImageGrab ImageGrab.grab((0, 0, self.width, self.height)).save(filename + '.jpg')
class GUIHandler: screenwidth = 0 screenheight = 0 windowwidth = 0 windowheight = 0 ## Initializes the GUI setup of the program. # def __init__(self,game): assert type(game) is Game self.root = Tk() self.root.title('SET') self.root.resizable(0,0) self.root.withdraw() GUIHandler.screenwidth = self.root.winfo_screenwidth() GUIHandler.screenheight = self.root.winfo_screenheight() if GUIHandler.screenwidth < 1024 or GUIHandler.screenheight < 768: showerror("Resolution Error","Your screen's resolution is likely not the best choice to run this game. Minimum resolution for this game is at least 1024x768.") raise ResolutionError(GUIHandler.screenwidth,GUIHandler.screenheight) GUIHandler.windowwidth = GUIHandler.screenwidth // 3 GUIHandler.windowheight = GUIHandler.screenheight // 1.5 self.buttonField = None self.checkButtonField = None self.Game = game self.Field = game.field assert self.Game assert self.Field self.root.geometry('%dx%d+%d+%d' % (GUIHandler.windowwidth, GUIHandler.windowheight, self.root.winfo_screenwidth()/8, self.root.winfo_screenheight()/8)) menu = Menu(self.root) gamemenu = Menu(menu,tearoff=0) gamemenu.add_command(label='New Game',command=lambda:self.startNewGame(),accelerator="F2") gamemenu.add_command(label='Leaderboards',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) gamemenu.add_command(label='Exit',command=lambda:self.root.destroy(),accelerator="Alt-F4") menu.add_cascade(label='Game',menu=gamemenu) settingmenu = Menu(menu,tearoff=0) gamedifficulty = Menu(settingmenu,tearoff=0) gamedifficulty.add_radiobutton(label='Beginner',command=lambda :self.changeGameDifficulty(Difficulty.BEGINNER),accelerator="B") gamedifficulty.add_radiobutton(label='Novice',command=lambda :self.changeGameDifficulty(Difficulty.NOVICE),accelerator="N") gamedifficulty.add_radiobutton(label='Advanced',command=lambda :self.changeGameDifficulty(Difficulty.ADVANCED),accelerator="A") settingmenu.add_cascade(label='Game Difficulty',menu=gamedifficulty) timedmode = Menu(settingmenu,tearoff=0) timedmode.add_radiobutton(label='On',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) timedmode.add_radiobutton(label='Off',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) settingmenu.add_cascade(label='Timed Mode',menu=timedmode) timeddifficulty = Menu(settingmenu,tearoff=0) timeddifficulty.add_radiobutton(label='Easy',accelerator="E") timeddifficulty.add_radiobutton(label='Medium',accelerator="M") timeddifficulty.add_radiobutton(label='Hard',accelerator="H") settingmenu.add_cascade(label='Timed Difficulty',menu=timeddifficulty) menu.add_cascade(label='Settings',menu=settingmenu) helpmenu = Menu(menu,tearoff=0) helpmenu.add_command(label='About SET',command=lambda:showinfo("Not implemented","Feature not implemented...yet.")) menu.add_cascade(label='Help',menu=helpmenu) self.root.config(menu=menu) self.root.bind('<F2>',lambda e:gamemenu.invoke(0)) self.root.bind('L',lambda e:gamemenu.invoke(1)) self.root.bind('<Alt-F4>',lambda e:gamemenu.invoke(2)) self.root.bind('b',lambda e:gamedifficulty.invoke(Difficulty.BEGINNER)) self.root.bind('n',lambda e:gamedifficulty.invoke(Difficulty.NOVICE)) self.root.bind('a',lambda e:gamedifficulty.invoke(Difficulty.ADVANCED)) self.remainderLabel = Label(self.root,text="There are %d set(s) remaining on the board." % self.Game.numSetsRemaining(),bg="white",relief=Tkinter.RAISED,font=('Helvetica',12)) self.remainderLabel.place(x=(GUIHandler.windowwidth-self.remainderLabel.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//4) timer = Label(self.root,text="Untimed Mode",bg="green",relief=Tkinter.RAISED,font=('Helvetica',12)) timer.place(x=(GUIHandler.windowwidth-timer.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//4.5) hintbutton = Button(text="Hint, please!",font=("Helvetica",12),command=lambda :self.getHint()) hintbutton.place(x=(GUIHandler.windowwidth-hintbutton.winfo_reqwidth())//2,y=3*GUIHandler.windowheight//3.5) self.userSetsCreated = Toplevel(self.root) self.userSetsHeight = 0 self.userSetsCreated.title("Sets Created") self.userSetsCreated.geometry("%dx%d+%d+%d" % (Card.pixelWidth*3, self.userSetsCreated.winfo_screenheight(), self.root.winfo_pointerx()+self.userSetsCreated.winfo_reqwidth(),0)) self.userSetsCreated.protocol("WM_DELETE_WINDOW",0) self.userSetsCreated.resizable(0,0) self.root.focus_set() self.updateCardsOnField(self.Field) ## Process the card location that the user picked. The function calls the game instance's addCardChoice method # to get a callback on the result of adding the card choice. def processCardChoice(self,i): cbutton = self.checkButtonField[i//self.Field.cols()][i%self.Field.cols()] cbutton.select() result = self.Game.addCardChoice(i) if result == 3: cbutton.deselect() return elif not result: return if result == 2: #Case 1: 3 choices were made and the Game object verified them as a set. showinfo("Good Job!","You made a set!") self.remainderLabel.config(text="There are %d set(s) remaining on the board." % self.Game.numSetsRemaining()) x = 0 for h in map(Card.getCardImgNumber,[self.Field[i//self.Field.cols()][i%self.Field.cols()] for i in self.Game.setsMadeSoFar[-1]]): pic = PhotoImage(file='../media/%d.gif'%h) label = Label(self.userSetsCreated,image=pic) label.image = pic label.place(x=x,y=self.userSetsHeight) x+=Card.pixelWidth self.userSetsHeight+=Card.pixelHeight if not self.Game.numSetsRemaining(): showinfo("WINNER!","Congratulations! You found all sets!") self.disableButtons() elif result == 1: #Case 2: 3 choices were made but the user has made this set before in the game. showinfo("Repeat","You've already made this set") elif type(result) == tuple: #Case #3: 3 choices were made but they didn't form a set. assert len(result) == 2 showinfo("Not a set","Not a set because 2 are %s and 1 is %s" % (result[0],result[1])) for i in self.checkButtonField: for j in i: j.deselect() def disableButtons(self): for i in self.buttonField: for j in i: j.config(state=Tkinter.DISABLED) for i in self.checkButtonField: for j in i: j.config(state=Tkinter.DISABLED) #Hard Coded lists of button widgets because python won't let me generate each of the Button's command #feature correctly via list comprehension. def setupNoviceField(self): self._destroyAllButtons() if self.buttonField else None self.buttonField = [[Button(self.root,command=lambda :self.processCardChoice(0)), Button(self.root,command=lambda :self.processCardChoice(1)), Button(self.root,command=lambda :self.processCardChoice(2))], [Button(self.root,command=lambda :self.processCardChoice(3)), Button(self.root,command=lambda :self.processCardChoice(4)), Button(self.root,command=lambda :self.processCardChoice(5))], [Button(self.root,command=lambda :self.processCardChoice(6)), Button(self.root,command=lambda :self.processCardChoice(7)), Button(self.root,command=lambda :self.processCardChoice(8))]] self.checkButtonField = [[Checkbutton(self.root,text='1',command=lambda :self.processCardChoice(0)), Checkbutton(self.root,text='2',command=lambda :self.processCardChoice(1)), Checkbutton(self.root,text='3',command=lambda :self.processCardChoice(2))], [Checkbutton(self.root,text='4',command=lambda :self.processCardChoice(3)), Checkbutton(self.root,text='5',command=lambda :self.processCardChoice(4)), Checkbutton(self.root,text='6',command=lambda :self.processCardChoice(5))], [Checkbutton(self.root,text='7',command=lambda :self.processCardChoice(6)), Checkbutton(self.root,text='8',command=lambda :self.processCardChoice(7)), Checkbutton(self.root,text='9',command=lambda :self.processCardChoice(8))]] #See the comment above setup Novice _Field. def setupAdvancedField(self): self._destroyAllButtons() if self.buttonField else None self.buttonField = [[Button(self.root,command=lambda :self.processCardChoice(0)), Button(self.root,command=lambda :self.processCardChoice(1)), Button(self.root,command=lambda :self.processCardChoice(2)), Button(self.root,command=lambda :self.processCardChoice(3))], [Button(self.root,command=lambda :self.processCardChoice(4)), Button(self.root,command=lambda :self.processCardChoice(5)), Button(self.root,command=lambda :self.processCardChoice(6)), Button(self.root,command=lambda :self.processCardChoice(7))], [Button(self.root,command=lambda :self.processCardChoice(8)), Button(self.root,command=lambda :self.processCardChoice(9)), Button(self.root,command=lambda :self.processCardChoice(10)), Button(self.root,command=lambda :self.processCardChoice(11))]] self.checkButtonField = [[Checkbutton(self.root,text='1',command=lambda :self.processCardChoice(0)), Checkbutton(self.root,text='2',command=lambda :self.processCardChoice(1)), Checkbutton(self.root,text='3',command=lambda :self.processCardChoice(2)), Checkbutton(self.root,text='4',command=lambda :self.processCardChoice(3))], [Checkbutton(self.root,text='5',command=lambda :self.processCardChoice(4)), Checkbutton(self.root,text='6',command=lambda :self.processCardChoice(5)), Checkbutton(self.root,text='7',command=lambda :self.processCardChoice(6)), Checkbutton(self.root,text='8',command=lambda :self.processCardChoice(7))], [Checkbutton(self.root,text='9',command=lambda :self.processCardChoice(8)), Checkbutton(self.root,text='10',command=lambda :self.processCardChoice(9)), Checkbutton(self.root,text='11',command=lambda :self.processCardChoice(10)), Checkbutton(self.root,text='12',command=lambda :self.processCardChoice(11))]] def updateCardsOnField(self,cardField): rows = cardField.rows() cols = cardField.cols() if cols == 3: self.setupNoviceField() elif cols == 4: self.setupAdvancedField() else: raise IndexError("CardField argument has illegal number of columns") assert len(self.buttonField) == rows assert len(self.buttonField[0]) == cols spacing = (GUIHandler.windowwidth-(cols * Card.pixelWidth) - 5) / (cols-1) x,y = 0,0 cbwidth = self.checkButtonField[0][0].winfo_reqwidth() for i in xrange(rows): for j in xrange(cols): pic = PhotoImage(file='../media/%s.gif' % str(cardField[i][j].getCardImgNumber())) self.buttonField[i][j].config(image=pic) self.buttonField[i][j].image = pic self.buttonField[i][j].place(x=x,y=y) self.checkButtonField[i][j].place(x=x + Card.pixelWidth//2 - cbwidth//4,y=(y+Card.pixelHeight+10)) x += Card.pixelWidth + spacing y += Card.pixelHeight + 40 x = 0 def startNewGame(self): self.userSetsHeight = 0 [i.destroy() for i in self.userSetsCreated.children.values()] self.Game.resetGame() self.updateCardsOnField(self.Game.field) self.remainderLabel.config(text="There are %d set(s) remaining on the board." % self.Game.numSetsTotal) #print map(lambda ls:map(lambda x:x+1,ls),self.Game.setsListTotal) def _destroyAllButtons(self): for i in self.buttonField: for j in i: j.destroy() for i in self.checkButtonField: for j in i: j.destroy() def changeGameDifficulty(self,difficulty): if self.Game.changeGameDifficulty(difficulty): self.startNewGame() def getHint(self): result = self.Game.callHint() if result == -3: showinfo("One set remains","You cannot use hints in finding the last set.") elif result == -2: showinfo("Game's over","Game has ended. Start a new game if you wish.") elif result == -1: showinfo("No more hints","Sorry. You are out of hints to spare.") else: showinfo("Your Hint","Pick Card #%d"%(result+1)) def run(self): self.root.deiconify() self.root.mainloop()