def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. >>> m = TOAHModel(2) >>> m.fill_first_stool(1) >>> m.top_cheese(0) Cheese(1) >>> move(m, 0, 1) >>> m.top_cheese(1) Cheese(1) ''' # Try to make the move with model try: model.move(origin, dest) except IllegalMoveError as e: # Print the error message print("Illegal Move:", e) return
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' try: # one move model.move(origin, dest) model.moves += 1 except IllegalMoveError: print('Please enter the right move') except IndexError: print( 'Please select the origin stool where there is at least one cheese on it' ) print( 'and cannot be out of range(0 to the number of stools you entered before minus 1' ) except ValueError: print( 'Please enter a number within 0 to the number of stools you entered before(without alphabetical letters' )
def tour_of_four_stools(model: TOAHModel, delay_btw_moves: float = 0.5, console_animate: bool = False): """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to animate the tour in the console delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False """ n = model.number_of_cheeses() list_of_moves = moves_list(n, 0, 1, 2, 3) if console_animate: for move in list_of_moves: TOAHModel.move(model, move[0], move[1]) print(model) print('Moving top cheese from {} to {}'.format(move[0], move[1])) time.sleep(delay_btw_moves) else: for move in list_of_moves: TOAHModel.move(model, move[0], move[1]) print('Moving top cheese from {} to {}'.format(move[0], move[1]))
def tour_of_four_stools(model: TOAHModel, delay_btw_moves: float=0.5, console_animate: bool=False): """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to animate the tour in the console delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False """ the_four_stools(model, model.number_of_cheeses(), 0, 1, 2, 3) # stool starts at 0 and ends at 3 if console_animate == True: x = model.get_move_seq() z = x.length() y = model.number_of_cheeses() model = TOAHModel(4) model.fill_first_stool(y) index = 0 time.sleep(delay_btw_moves) print(model) while index < z: time.sleep(delay_btw_moves) m = x.get_move(index) model.move(m[0],m[1]) time.sleep(delay_btw_moves) print(model) time.sleep(delay_btw_moves) index += 1
def tour_of_four_stools(model: TOAHModel, delay_btw_moves: float = 0.5, console_animate: bool = False): """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to use ConsoleController to animate the tour delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False """ #This first part is to make the right MoveSequence cheese_num = model.number_of_cheeses() moves = MoveSequence([]) four_stool_solution(moves, cheese_num, 0, 1, 2, 3) #Then we apply it to our existing model, animating with delay if #requested. if console_animate: for move in moves._moves: print(model) model.move(move[0], move[1]) time.sleep(delay_btw_moves) print(model) else: for move in moves._moves: model.move(move[0], move[1])
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' model.move(origin, dest)
class ConsoleController: def __init__(self: 'ConsoleController', number_of_cheeses: int, number_of_stools: int): """ Initialize a new 'ConsoleController'. number_of_cheeses - number of cheese to tower on the first stool number_of_stools - number of stools """ self.number_of_stools = TOAHModel(number_of_stools) self.number_of_cheeses = \ self.number_of_stools.fill_first_stool(number_of_cheeses) def play_loop(self: 'ConsoleController'): ''' Console-based game. TODO: -Start by giving instructions about how to enter moves (which is up to you). Be sure to provide some way of exiting the game, and indicate that in the instructions. -Use python's built-in function input() to read a potential move from the user/player. You should print an error message if the input does not meet the specifications given in your instruction or if it denotes an invalid move (e.g. moving a cheese onto a smaller cheese). You can print error messages from this method and/or from ConsoleController.move; it's up to you. -After each valid move, use the method TOAHModel.__str__ that we've provided to print a representation of the current state of the game. ''' print('You will have a number of Cheeses stacked on each other in \ order of size.\n') print('You also have a number of stools and the the goal of the game\ is to get all the Cheeses from one stool to the final stool.\n') print('In the process of this you are not allowed to stack a Cheese\ that is bigger than another.\n') user_string = '' while user_string != 'Exit Game': first_move = input('What is the orgin of the Cheese?:') second_move = input('What is the destination of the Cheese?:') try: self.number_of_stools.move(int(first_move), int(second_move)) except IllegalMoveError: print('You made a mistake, please try again') except ValueError: print('You made a mistake, please change your input to an int') print(self.number_of_stools) print(self.number_of_cheeses) user_string = input('To exit, type Exit Game. Anything 2 continue')
def tour_of_four_stools(model: 'TOAHModel', delay_btw_moves: float = 0.5, console_animate: bool = False): """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to animate the tour in the console delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False >>> m = TOAHModel(4) >>> m.fill_first_stool(8) >>> tour_of_four_stools(m) >>> m.get_move_seq().length() 33 """ # Use helper function to solve the problem four_stool_move( model, model.number_of_cheeses(), SRC_INDEX, # src_stool DEST_INDEX, # dest_stool (TEMP0_INDEX, TEMP1_INDEX)) # temp_stools # If animation is requested if (console_animate): # Get the MoveSequence from model move_seq = model.get_move_seq() # Create and set up a new 4-stool TOAHModel to animate anim_model = TOAHModel(4) anim_model.fill_first_stool(model.number_of_cheeses()) # Print the initial state of anim_model print(anim_model) # Go through each move in move_seq for i in range(move_seq.length()): # Get the source and destination stool indices (src_stool, dest_stool) = move_seq.get_move(i) # Delay the next move time.sleep(delay_btw_moves) # Apply the move anim_model.move(src_stool, dest_stool) # Print the result print(anim_model) return
def move_cheeses(model: TOAHModel, n: int, source: int, intermediate: int, destination: int) -> None: """Print moves to get n cheeses from source to destination, possibly using intermediate""" if n > 1: move_cheeses(model, n - 1, source, destination, intermediate) move_cheeses(model, 1, source, intermediate, destination) move_cheeses(model, n - 1, intermediate, source, destination) else: model.move(source, destination) if animate is True: print(model) time.sleep(delay)
def move_four_stools(model: TOAHModel, n: int, source: int, intermediate1: int, intermediate2: int, destination: int): i = index_of_M(n) if n > 1: move_four_stools(model, n - i, source, destination, intermediate1, intermediate2) move_cheeses(model, i, source, intermediate1, destination) move_four_stools(model, n - i, intermediate2, source, intermediate1, destination) else: model.move(source, destination) if animate is True: print(model) time.sleep(delay)
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' model.move(origin, dest) print(model)
def move_four_stools(model: TOAHModel, n: int, source: int, intermediate1: int, intermediate2: int, destination: int) -> None: """ Print moves to get n cheeses from source to destination, possibly using intermediates """ def M(n) -> int: """ return the minimum moves of moving n Cheeses on four stools >>> M(4) 9 """ if n == 1: return 1 else: moves = [] for i in range(1, n): moves.append(2 * M(n - i) + 2**i - 1) global mo mo = moves.copy() return min(moves) def find_i(n) -> int: """ return the index of a in the global variable mo >>> find_i(9) 1 """ return mo.index(n) def find(n): """ return the index of M(n) in the global variable mo + 1 since the index has a range from 1 to n(exclusive) >>>find(9) 3 """ return find_i(M(n)) + 1 if n > 1: move_four_stools(model, n - find(n), source, intermediate2, destination, intermediate1) move_three_stools(find(n), source, intermediate2, destination) move_four_stools(model, n - find(n), intermediate1, source, intermediate2, destination) else: model.move(source, destination)
def move(model: TOAHModel, origin: int, dest: int) -> None: ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' try: model.move(origin, dest) except IllegalMoveError: print('Invalid move! Try again')
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' if model.top_cheese[dest].size > model.top_cheese[origin].size: try: model.move(origin, dest) except IllegalMoveError(): print('You made a mistake, please try again')
def move(model: TOAHModel, origin: int, dest: int): ''' (TOAHModel, int, int) -> NoneType Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. REQ: 0 <= origin < self._number_of_stools REQ: 0 <= dest < self._number_of_stools ''' # Use the TOAHModel's move method to move the cheese model.move(origin, dest)
def tour_of_four_stools(model: TOAHModel, delay_btw_moves: float=0.5, console_animate: bool=False,): """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to use ConsoleController to animate the tour delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False """ # store the number of cheeses in n, because it's shorter and easier n = model.number_of_cheeses() # create an empty list to store the moves (in tuple form) moves = [] # call the helper function so the solution can be stored in moves helper_four_stools(moves, n, 0, 1, 2, 3) # if user wants to animate if console_animate is True: # grab a movie one by one and apply it to the given model # until the moves list is empty while len(moves) != 0: # temp is basically the first move in the list # it's a tuple temp = moves[0] # delete that move from the original moves list because we # already saved it and we won't need it again moves = moves[1:] # since temp is a tuple, temp[0] is the original stool and # temp[1] is the destination stool: temp = (temp[0], temp[1]) model.move(temp[0], temp[1]) # if user wants a delay between moves, use sleep to pause time.sleep(delay_btw_moves) # print a visual representation of the model being changed print(model) # if user does not any animation, only the model is changed else: # exact same thing but this time there is no delay between moves while len(moves) != 0: # get origin stool temp = moves[0] # get destination stool moves = moves[1:] # change the model model.move(temp[0], temp[1])
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. >>> M = TOAHModel(4) >>> M.fill_first_stool(1) >>> move(M, 0, 1) >>> M.get_stools() [[], [Cheese(1)], [], []] >>> M = TOAHModel(4) >>> M.fill_first_stool(4) >>> move(M, 0, 1) >>> move(M, 0, 2) >>> move(M, 1, 2) >>> M.get_stools() == [[Cheese(4), Cheese(3)], [], [Cheese(2),\ Cheese(1)], []] True >>> move(M, 2, 1) >>> M.get_stools() [[Cheese(4), Cheese(3)], [Cheese(1)], [Cheese(2)], []] >>> move(M, 0, 3) >>> M.get_stools() == [[Cheese(4)], [Cheese(1)], [Cheese(2)], \ [Cheese(3)]] True >>> move(M, 0, 1) Traceback (most recent call last): ... TOAHModel.IllegalMoveError: Cannot move bigger Cheese onto smaller Cheese >>> M = TOAHModel(4) >>> move(M, 0, 1) Traceback (most recent call last): ... TOAHModel.IllegalMoveError: This stool is empty! REQ: model.top_cheese(dest).size > model.top_cheese(origin).size ''' # Already implemented in TOAHModel. Better to simply use it. model.move(origin, dest)
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' try: model.move(origin, dest) except IllegalMoveError: print ("***Can't perform move***") except IndexError: print ("***Stool does not exist***") except AttributeError: print ("***Move not possible***") else: pass
def move(model: TOAHModel, origin: int, dest: int): ''' Module method to apply one move to the given model, and print any error message to the console. model - the TOAHModel that you want to modify origin - the stool number (indexing from 0!) of the cheese you want to move dest - the stool number that you want to move the top cheese on stool origin onto. ''' try: model.move(origin, dest) except IllegalMoveError: #This is so we can give the interface some "personality" rand = random.randint(1, 3) if rand == 1: print("Whoops! Can't do that!") elif rand == 2: print("Clearly someone needs to read the instructions again!") else: print("I can't let you do that.") except KeyError: print("That stool doesn't exist dummy.")
class GUIController: def __init__(self: 'GUIController', number_of_cheeses: int, number_of_stools: int, content_width: float, content_height: float, cheese_scale: float): """ Initialize a new GUIView. number_of_cheeses - number of cheese to tower on the first stool number_of_stools - number of stools content_width - width in pixels of the working area content_height - height in pixels of the working area cheese_scale - height in pixels for showing cheese thicknesses, and to scale cheese diameters """ self._model = TOAHModel(number_of_stools) self._stools = [] self._cheese_to_move = None self._blinking = False self._number_of_stools = number_of_stools self.cheese_scale = cheese_scale self.root = TI.Tk() canvas = TI.Canvas(self.root, background="blue", width=content_width, height=content_height) canvas.pack(expand=True, fill=TI.BOTH) self.moves_label = TI.Label(self.root) self.show_number_of_moves() self.moves_label.pack() # the dimensions of a stool are the same as a cheese that's # one size bigger than the biggest of the number_of_cheeses cheeses. for stool_ind in range(number_of_stools): width = self.cheese_scale * (number_of_cheeses + 1) x_cent = content_width * (stool_ind + 1) / (number_of_stools + 1.0) y_cent = content_height - cheese_scale / 2 stool = StoolView(width, lambda s: self.stoolClicked(s), canvas, self.cheese_scale, x_cent, y_cent) self._stools.append(stool) # Can't use self._model.fill_first_stool because we need to # use CheeseView objects instead of just Cheese objects. total_size = self.cheese_scale for sizeparam in range(1, number_of_cheeses + 1): size = (number_of_cheeses + 1 - sizeparam) width = self.cheese_scale * size x_cent = content_width / (number_of_stools + 1.0) y_cent = content_height - cheese_scale / 2 - total_size cheese = CheeseView(size, width, lambda c: self.cheeseClicked(c), canvas, self.cheese_scale, x_cent, y_cent) self._model.add(0, cheese) total_size += self.cheese_scale def cheeseClicked(self: 'GUIController', cheese: 'CheeseView'): """React to cheese being clicked: if not in the middle of blinking then select cheese for moving, or for moving onto. cheese - clicked cheese """ if not self._blinking: self.select_cheese(cheese) def stoolClicked(self: 'GUIController', stool: 'StoolView'): """React to cheese being clicked: if not in the middle of blinking then select cheese for moving, or for moving onto. cheese - clicked cheese """ if not self._blinking: self.select_stool(stool) def select_cheese(self: 'GUIController', cheese: CheeseView): """ Called by cheeseClicked. If no cheese is selected to move, then select the cheese at top of clicked_cheese's stool (which may be clicked_cheese itself) and highlight it. If selected_cheese is already highlighted, then unhighlight it. Otherwise try to move self._cheese_to_move onto the stool that clicked_cheese is on. """ stool = self._stools[self._model.cheese_location(cheese)] stool_index = self.stool_index(stool) cheese = self._model.top_cheese(stool_index) #print(stool, stool_index, cheese) if self._cheese_to_move is None: self._cheese_to_move = cheese self._cheese_to_move.highlight(True) self.root.update() elif self._cheese_to_move is cheese: self._cheese_to_move.highlight(False) self._cheese_to_move = None self.root.update() else: self.select_platform_for_move(cheese, stool_index) def select_stool(self: 'GUIController', dest_stool: StoolView): """ Called by stoolClicked. Initiate a move if there is already some cheese highlighted (i.e. self._cheese_to_move is not None), unless self._cheese_to_move is on dest_stool, in which case do nothing. """ if self._cheese_to_move is not None: origin_stool = self._stools[ self._model.cheese_location(self._cheese_to_move)] dest_stool_index = self.stool_index(dest_stool) origin_stool_index = self.stool_index(origin_stool) if origin_stool_index != dest_stool_index: top_cheese = self._model.top_cheese(dest_stool_index) if top_cheese is None: self.select_platform_for_move(dest_stool, dest_stool_index) else: self.select_platform_for_move(top_cheese, dest_stool_index) def select_platform_for_move(self: 'GUIController', platform: PlatformView, stool_index: int): """ Actually responsible for showing the cheese move on the screen, and for telling the model to update itself. Change self._cheese_to_move's coordinates so that it's on top of platform. platform - the StoolView or CheeseView that we want to move self._cheese_to_move onto. stool_index - if platform is a stool, then this is its index, and if platform is a cheese then this is the index of the stool that it is on. """ if self._cheese_to_move is not None: try: from_stool = self._model.cheese_location( self._cheese_to_move) self._model.move(from_stool, stool_index) self._cheese_to_move.place(platform.x_center, platform.y_center - self.cheese_scale) self.show_number_of_moves() except IllegalMoveError as e: print(e) self._blinking = True for i in range(10): self._cheese_to_move.highlight(i % 2 != 0) self.root.update() time.sleep(0.1) self._blinking = False self._cheese_to_move.highlight(False) self._cheese_to_move = None self.root.update() def stool_index(self: 'GUIView', stool: 'StoolView') -> int: return self._stools.index(stool) def show_number_of_moves(self: 'GUIView'): """Show the number of moves so far.""" self.moves_label.config(text='Number of moves: ' + str(self._model.number_of_moves())) def get_stool(self: 'GUIController', i: int) -> 'StoolView': return self._stools[i] def top_cheese(self: 'GUIController', i: int) -> 'CheeseView': return self._model.top_cheese(i)
def tour_of_four_stools(model: TOAHModel, delay_btw_moves: float = 0.5, console_animate: bool = False) -> None: """Move a tower of cheeses from the first stool in model to the fourth. model - a TOAHModel with a tower of cheese on the first stool and three other empty stools console_animate - whether to animate the tour in the console delay_btw_moves - time delay between moves in seconds IF console_animate == True no effect if console_animate == False """ def move_three_stools(n: int, source: int, intermediate: int, destination: int) -> None: """ Print moves to get n cheeses from source to destination, possibly using intermediate """ if n > 1: move_three_stools(n - 1, source, destination, intermediate) move_three_stools(1, source, intermediate, destination) move_three_stools(n - 1, intermediate, source, destination) else: model.move(source, destination) def move_four_stools(model: TOAHModel, n: int, source: int, intermediate1: int, intermediate2: int, destination: int) -> None: """ Print moves to get n cheeses from source to destination, possibly using intermediates """ def M(n) -> int: """ return the minimum moves of moving n Cheeses on four stools >>> M(4) 9 """ if n == 1: return 1 else: moves = [] for i in range(1, n): moves.append(2 * M(n - i) + 2**i - 1) global mo mo = moves.copy() return min(moves) def find_i(n) -> int: """ return the index of a in the global variable mo >>> find_i(9) 1 """ return mo.index(n) def find(n): """ return the index of M(n) in the global variable mo + 1 since the index has a range from 1 to n(exclusive) >>>find(9) 3 """ return find_i(M(n)) + 1 if n > 1: move_four_stools(model, n - find(n), source, intermediate2, destination, intermediate1) move_three_stools(find(n), source, intermediate2, destination) move_four_stools(model, n - find(n), intermediate1, source, intermediate2, destination) else: model.move(source, destination) move_four_stools(model, NUM_CHEESES, 0, 1, 2, 3) model2 = TOAHModel(4) model2.fill_first_stool(NUM_CHEESES) print(model2) for moves in model.get_move_seq()._moves: if console_animate: time.sleep(delay_btw_moves) model2.move(moves[0], moves[1]) print(model2)
class GUIController: def __init__(self: 'GUIController', number_of_cheeses: int, number_of_stools: int, content_width: float, content_height: float, cheese_scale: float): """ Initialize a new GUIView. number_of_cheeses - number of cheese to tower on the first stool number_of_stools - number of stools content_width - width in pixels of the working area content_height - height in pixels of the working area cheese_scale - height in pixels for showing cheese thicknesses, and to scale cheese diameters """ self._model = TOAHModel(number_of_stools) self._stools = [] self._cheese_to_move = None self._blinking = False self._number_of_stools = number_of_stools self.cheese_scale = cheese_scale self.root = TI.Tk() canvas = TI.Canvas(self.root, background="blue", width=content_width, height=content_height) canvas.pack(expand=True, fill=TI.BOTH) self.moves_label = TI.Label(self.root) self.show_number_of_moves() self.moves_label.pack() # the dimensions of a stool are the same as a cheese that's # one size bigger than the biggest of the number_of_cheeses cheeses. for stool_ind in range(number_of_stools): width = self.cheese_scale * (number_of_cheeses + 1) x_cent = content_width * (stool_ind + 1) / (number_of_stools + 1.0) y_cent = content_height - cheese_scale / 2 stool = StoolView(width, lambda s: self.stoolClicked(s), canvas, self.cheese_scale, x_cent, y_cent) self._stools.append(stool) # Can't use self._model.fill_first_stool because we need to # use CheeseView objects instead of just Cheese objects. total_size = self.cheese_scale for sizeparam in range(1, number_of_cheeses + 1): size = (number_of_cheeses + 1 - sizeparam) width = self.cheese_scale * size x_cent = content_width / (number_of_stools + 1.0) y_cent = content_height - cheese_scale / 2 - total_size cheese = CheeseView(size, width, lambda c: self.cheeseClicked(c), canvas, self.cheese_scale, x_cent, y_cent) self._model.add(0, cheese) total_size += self.cheese_scale def cheeseClicked(self: 'GUIController', cheese: 'CheeseView'): """React to cheese being clicked: if not in the middle of blinking then select cheese for moving, or for moving onto. cheese - clicked cheese """ if not self._blinking: self.select_cheese(cheese) def stoolClicked(self: 'GUIController', stool: 'StoolView'): """React to cheese being clicked: if not in the middle of blinking then select cheese for moving, or for moving onto. cheese - clicked cheese """ if not self._blinking: self.select_stool(stool) def select_cheese(self: 'GUIController', cheese: CheeseView): """ Called by cheeseClicked. If no cheese is selected to move, then select the cheese at top of clicked_cheese's stool (which may be clicked_cheese itself) and highlight it. If selected_cheese is already highlighted, then unhighlight it. Otherwise try to move self._cheese_to_move onto the stool that clicked_cheese is on. """ stool = self._stools[self._model.cheese_location(cheese)] stool_index = self.stool_index(stool) cheese = self._model.top_cheese(stool_index) #print(stool, stool_index, cheese) if self._cheese_to_move is None: self._cheese_to_move = cheese self._cheese_to_move.highlight(True) self.root.update() elif self._cheese_to_move is cheese: self._cheese_to_move.highlight(False) self._cheese_to_move = None self.root.update() else: self.select_platform_for_move(cheese, stool_index) def select_stool(self: 'GUIController', dest_stool: StoolView): """ Called by stoolClicked. Initiate a move if there is already some cheese highlighted (i.e. self._cheese_to_move is not None), unless self._cheese_to_move is on dest_stool, in which case do nothing. """ if self._cheese_to_move is not None: origin_stool = self._stools[self._model.cheese_location( self._cheese_to_move)] dest_stool_index = self.stool_index(dest_stool) origin_stool_index = self.stool_index(origin_stool) if origin_stool_index != dest_stool_index: top_cheese = self._model.top_cheese(dest_stool_index) if top_cheese is None: self.select_platform_for_move(dest_stool, dest_stool_index) else: self.select_platform_for_move(top_cheese, dest_stool_index) def select_platform_for_move(self: 'GUIController', platform: PlatformView, stool_index: int): """ Actually responsible for showing the cheese move on the screen, and for telling the model to update itself. Change self._cheese_to_move's coordinates so that it's on top of platform. platform - the StoolView or CheeseView that we want to move self._cheese_to_move onto. stool_index - if platform is a stool, then this is its index, and if platform is a cheese then this is the index of the stool that it is on. """ if self._cheese_to_move is not None: try: from_stool = self._model.cheese_location(self._cheese_to_move) self._model.move(from_stool, stool_index) self._cheese_to_move.place( platform.x_center, platform.y_center - self.cheese_scale) self.show_number_of_moves() except IllegalMoveError as e: print(e) self._blinking = True for i in range(10): self._cheese_to_move.highlight(i % 2 != 0) self.root.update() time.sleep(0.1) self._blinking = False self._cheese_to_move.highlight(False) self._cheese_to_move = None def stool_index(self: 'GUIView', stool: 'StoolView') -> int: return self._stools.index(stool) def show_number_of_moves(self: 'GUIView'): """Show the number of moves so far.""" self.moves_label.config(text='Number of moves: ' + str(self._model.number_of_moves())) def get_stool(self: 'GUIController', i: int) -> 'StoolView': return self._stools[i] def top_cheese(self: 'GUIController', i: int) -> 'CheeseView': return self._model.top_cheese(i)