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
Exemple #2
0
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]))
Exemple #3
0
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.
    >>> M = TOAHModel(4)
    >>> M.fill_first_stool(5)
    >>> M.move(0,2)
    >>> M.get_move_seq()
    MoveSequence([(0, 2)])
    >>> M1 = TOAHModel(4)
    >>> M1.fill_first_stool(5)
    >>> M1.move(0,2)
    >>> M1.move(2,1)
    >>> M1.get_move_seq()
    MoveSequence([(0, 2), (2, 1)])
    '''   
    has_cheese = False
    length_of_dest_stool = len(model.stools[dest])
    if length_of_dest_stool > 0:
        has_cheese = True
    if has_cheese and model.top_cheese(origin).size > model.top_cheese(dest).size:
        raise IllegalMoveError('Illegal move, try again!')
    else:
        relocate = model.stools[origin].pop()
        model.stools[dest].append(relocate)
        model.move_count += 1
        moves_tup = (origin,dest)
        model._move_seq.append(moves_tup)      
Exemple #5
0
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'
        )
Exemple #6
0
def move_cheeses(n: int, i, source: int, intermediate1: int, intermediate2,
                 destination: int) -> None:
    """Print moves to get n cheeses from source to destination, possibly
    using intermediate"""
    if i > 1:
        if n > 1:
            move_cheeses(n - i, i, source, destination, intermediate1,intermediate2)
            move_cheeses(i-1, i, source, intermediate2, destination, intermediate1)
            move_cheeses(1, i, source, intermediate1, intermediate2, destination)
            move_cheeses(i-1, i, intermediate1, source, intermediate2, destination)
            move_cheeses(n -i, i, intermediate2, intermediate1, source, destination)
        else:
            print("Move top cheese from {} to {}".format(source, destination))
    else: # just one cheese --- no recursion required!
        print("Move top cheese from {} to {}".format(intermediate2, destination)


if __name__ == '__main__' :
       NUM_CHEESES = 8
       DELAY_BETWEEN_MOVES = .5
       CONSOLE_ANIMATE = False
       # DO NOT MODIFY THE CODE BELOW.
       four_stools = TOAHModel(4)    
       four_stools.fill_first_stool(number_of_cheeses=NUM_CHEESES)
    
        tour_of_four_stools(four_stools, console_animate=CONSOLE_ANIMATE, delay_btw_moves=DELAY_BETWEEN_MOVES)
    
        print(four_stools.number_of_moves())
Exemple #7
0
    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 __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
        """
        model = TOAHModel(number_of_stools)
        model.fill_first_stool(number_of_cheeses)
        self._model = model
    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 __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.model = TOAHModel(number_of_stools)
        self.model.fill_first_stool(number_of_cheeses)
        self.has_seen_instructions = False
Exemple #11
0
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 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)
Exemple #13
0
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)
Exemple #14
0
class ConsoleController:
    def __init__(self: 'ConsoleController', number_of_cheeses: int,
                 number_of_stools: int) -> None:
        """
        Initialize a new 'ConsoleController'.
        """

        TOAHModel.__init__(self, number_of_stools)
        TOAHModel.fill_first_stool(self, number_of_cheeses)
        self.cheese_model = TOAHModel(number_of_stools)
        self.number_of_stools = number_of_stools
        self.cheese_model.fill_first_stool(number_of_cheeses)

    def play_loop(self: 'ConsoleController') -> None:
        '''    
        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.
        '''
        instructions = input("In order to make a move, you must insert the \
initial_stool number and the final_stool number seperated by a comma. If you \
wish to exit the game, input 'exit' and answer'yes'. Press enter to begin!")

        prompt = input('Your move (initial_stool, final_stool):')
        while prompt != 'exit':
            new_list = prompt.split(sep=',')
            move_list = []
            try:
                int(new_list[0]) or int(new_list[1])
            except ValueError:
                print('Invalid entry! Try again')
                prompt = input('Your move (initial_stool, final_stool):')

            move_list.append(int(new_list[0]))
            move_list.append(int(new_list[1]))
            move(self.cheese_model, move_list[0], move_list[1])
            print(self.cheese_model.__str__())
            prompt = input('Your move (initial_stool, final_stool):')

        else:
            exit()
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)
Exemple #16
0
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)
Exemple #17
0
    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)
Exemple #18
0
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)
Exemple #19
0
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')
Exemple #20
0
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 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])
Exemple #22
0
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_cheeses = number_of_cheeses
        self.number_of_stools = number_of_stools
        self.model = TOAHModel(number_of_stools)
        self.model.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('')
        print(
            'Move the top cheese from the origin stool to the destination stool'
        )
        print(
            'by entering the number within the number of stools you have entered'
        )
        print(
            '(number between 0 to the number of stools you entered before minus one'
        )
        print('since the order of stools starts with 0)')
        print('')
        print(self.model)
        origin = int(input('Please enter the original stool: '))
        dest = int(input('Please enter the destination stool: '))
        move(self.model, 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.

    >>> 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 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
Exemple #25
0
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
    """
    # Call helper functions to move the cheese
    # If console_animate is true, print each step
    if (console_animate is True):
        # Pass true in the parameter to print
        four_stool_hanoi(model, model.number_of_cheeses(), 0, 1, 2, 3, True)
    # Otherwise don't print it
    else:
        four_stool_hanoi(model, model.number_of_cheeses(), 0, 1, 2, 3, False)
Exemple #26
0
    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,
                            not counting the bottom cheese acting as stool
        number_of_stools - number of stools, to be shown as large cheeses
        """
        # REPRESENTATION INVARIANT
        # self._number_of_cheeses is an integer which represents the number
        # of cheeses in the game
        # self._number_of_stools is an integer which represents the number
        # of stools in the game
        # self._model is a TOAHModel, which represents the game as a whole
        self._number_of_cheeses = number_of_cheeses
        self._number_of_stools = number_of_stools
        self._model = TOAHModel(self._number_of_stools)
        # Fill the first stool with the amount of cheese entered
        self._model.fill_first_stool(self._number_of_cheeses)
    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,
                            not counting the bottom cheese acting as stool
        number_of_stools - number of stools, to be shown as large cheeses
        """
        self._model = TOAHModel(number_of_stools)
        self._model.fill_first_stool(number_of_cheeses)
Exemple #28
0
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
Exemple #29
0
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
    """

    four_hanoi(model.number_of_cheeses(), 0, 1, 2,
               3, console_animate, delay_btw_moves)
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.")
Exemple #31
0
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
    """

    four_hanoi(model.number_of_cheeses(), 0, 1, 2, 3, console_animate,
               delay_btw_moves)
 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.
     '''
     
     m = TOAHModel(self.number_of_stools)
     m.fill_first_stool(self.number_of_cheeses)        
     print("Then enter 2 integers sperated by a comma. first integer will be the stool to move the cheese from and second will be the stool the cheese has to be moved")
     print("Enter 'exit' to exit")
     
    
     s = input("Enter your move: ")
     while (s != "exit"):
         l=s.split(',')
         if len(l)==2:
             if not (l[0].isalpha() and l[1].isalpha()):
                 move(m, int(l[0]),(int(l[1]))) # ask ta
             else:
                 raise IllegalInputError("Not valid input")
             
         else:
             raise IllegalInputError("Not valid input") 
                 
         s=input("Enter the next move: ")
    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
        """
        # Initialize dict for converting the user command strings
        # to their methods
        self._cmd_to_method = {
            "MOVE": self.move,
            "HELP": self.help,
            "QUIT": self.quit,
            "EXIT": self.quit
        }

        # Create a TOAHModel with the specified number of stools
        self._model = TOAHModel(number_of_stools)

        # Put the TOAHModel in the starting config with the number of cheeses
        self._model.fill_first_stool(number_of_cheeses)

        return
Exemple #34
0
    def __init__(self: 'ConsoleController', number_of_cheeses: int,
                 number_of_stools: int) -> None:
        """
        Initialize a new 'ConsoleController'.
        """

        TOAHModel.__init__(self, number_of_stools)
        TOAHModel.fill_first_stool(self, number_of_cheeses)
        self.cheese_model = TOAHModel(number_of_stools)
        self.number_of_stools = number_of_stools
        self.cheese_model.fill_first_stool(number_of_cheeses)
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 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
    """
    src = 0
    spare_1 = 1
    spare_2 = 2
    dest = 3
    num_cheeses = model.number_of_cheeses()

    rec_four_stools(model, num_cheeses, src, spare_1, spare_2, dest,
                    delay_btw_moves, console_animate)
	    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
		    


if __name__ == '__main__':
    NUM_CHEESES = 9
    DELAY_BETWEEN_MOVES = 0.5
    CONSOLE_ANIMATE = True
    
    # DO NOT MODIFY THE CODE BELOW.
    four_stools = TOAHModel(4)    
    four_stools.fill_first_stool(number_of_cheeses=NUM_CHEESES)
    
    tour_of_four_stools(four_stools, 
                        console_animate=CONSOLE_ANIMATE,
                        delay_btw_moves=DELAY_BETWEEN_MOVES)
    
    print(four_stools.number_of_moves())
    print('=========================================================================')
    print("However, please choose how many cheeses you want on your stool: ")
    how_many_cheeses = input()
    if how_many_cheeses == 'Finish':
        print('Thanks for playing! ')
        sys.exit('You have chosen to exit the program. Bye!')
    
    while how_many_cheeses.isdigit() == False or int(how_many_cheeses) <= 0:
        print("Please enter a numeral value that is greater than 0")
        how_many_cheeses = input()
    try:
        how_many_cheeses = int(how_many_cheeses)
    except:
        print('Bad input, try again!')
        how_many_cheeses = int(input())

        
            
    c1 = ConsoleController(how_many_cheeses,4)
    m5 = TOAHModel(c1.number_of_stools)
    m5.fill_first_stool(c1.number_of_cheeses)
    c1.play_loop()
    print('======================================================================')
    print('Below are the moves you made:')
    print(m5.get_move_seq())
    x = m5.get_move_seq()
    print("Total moves made: "+str(x.length()))
    print("Play again soon!")
    print('======================================================================')

Exemple #39
0
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_cheeses = number_of_cheeses
        self.number_of_stools = number_of_stools
        self.model = TOAHModel(number_of_stools)
        self.cheeses = self.model.fill_first_stool(number_of_cheeses)
        self.play_loop()
                
    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 ("Welcome to Towers Of Anne Hoy!")
        print ("Instructions: The stool numbers start from 0.")
        print ("Please enter the source stool when prompted.")
        print ("Source stool is the stool number to move the cheese from.")
        print ("Please enter the destination stool when prompted.")
        print ("Destination stool is the stool number to move the cheese to.")
        print ("Enter 'e' to exit.")
        print (" ")
        print (self.model)
        print (" ")
        print ("Let's start!")
        print (" ")

        while True: 
            try:
                if self.model.end_game_stool == self.model.stool_lst[-1]:
                    print ("GAME OVER!")
                    raise SystemExit
                self.play_loop
                origin_stool = input("Please enter the source stool: ")
                if origin_stool == 'e':
                    print ("***Thanks for playing!***")
                    raise SystemExit    
                dest_stool = input("Please enter the destination stool: ")
                if dest_stool == 'e':
                    print ("***Thanks for playing!***")
                    raise SystemExit 
                move(self.model, int(origin_stool), int(dest_stool))
                print (self.model)
                print ("Number of moves so far: "
                       +str(self.model.number_of_moves()))
                print (" ")
            except ValueError:
                print ("***Bad input***")
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)
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.model = TOAHModel(number_of_stools)
        self.model.fill_first_stool(number_of_cheeses)
        self.has_seen_instructions = False

    def intro(self: 'ConsoleController') -> None:
        """
        Simply prints an introduction to the console.
        """
        print('--------------------------------------------------')
        print('|    Welcome to the Towers of Anne Hoi game!     |')
        print('|       Can you move all of the cheeses?         |')
        print("|Be careful though, you can't put a cheese on top|")
        print('|              of a smaller cheese.              |')
        print('|                   Good Luck!                   |')
        print('--------------------------------------------------')

    def display_instructions(self: 'ConsoleController'):
        """
        Prints instructions to the console.
        """
        print("Moves are entered in the following format:")
        print("'Location Stool' 'Destination Stool'")
        print("Separated by a space. ex. '1 2' moves the cheese")
        print("from the first stool to the second.")

    def process_query(self: "ConsoleController", query: str):
        """
        Takes an input, and applies the appropriate command.

        """
        #applies the move if it is indeed a move, or prints instructions
        #the only other valid command is exit which is accounted for in
        #play_loop
        if is_move(query):
            relocation = query.split()
            #I decided to make the first stool 1 instead of 0
            #since it seems more intuitive to a user who doesn't
            #program.
            location = int(relocation[0]) - 1
            destination = int(relocation[1]) - 1
            move(self.model, location, destination)
        elif query.lower() == 'i':
            self.has_seen_instructions = False

    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.
        '''
        self.intro()
        query = ''
        print(self.model)

        while not query.lower() == 'e':
            #So that we only see the instructions when wanted
            if not self.has_seen_instructions:
                self.display_instructions()
                self.has_seen_instructions = True
            else:
                print(self.model)
            print("Type 'i' to see instructions again. 'e' to exit")
            query = input("Please enter a move:")
            self.process_query(query)
        print("Goodbye!")
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)
Exemple #43
0
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)
Exemple #44
0
    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])


if __name__ == '__main__':
    NUM_CHEESES = 25
    DELAY_BETWEEN_MOVES = .1
    CONSOLE_ANIMATE = True

    # DO NOT MODIFY THE CODE BELOW.
    four_stools = TOAHModel(4)
    four_stools.fill_first_stool(number_of_cheeses=NUM_CHEESES)

    tour_of_four_stools(four_stools,
                        console_animate=CONSOLE_ANIMATE,
                        delay_btw_moves=DELAY_BETWEEN_MOVES)

    print(four_stools.number_of_moves())
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,
                            not counting the bottom cheese acting as stool
        number_of_stools - number of stools, to be shown as large cheeses
        """
        self._model = TOAHModel(number_of_stools)
        self._model.fill_first_stool(number_of_cheeses)

    def get_model(self):
        """ (ConsoleController) -> TOAHModel
        Return the TOAHModel of this game.
        """
        return self._model

    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
        provded to print a representation of the current state of the game.
        '''
        print(self.get_model())
        print(INSTRUCTIONS)

        print(DASH_SEPARATOR)
        cmd = input("Please enter your command: ")
        while(cmd != "quit"):
            # parse the user input to get src and dest stool index
            # re-enter if InvalidInputError exception caught
            try:
                src, dest = _instruction_filter(cmd)
            except InvalidInputError:
                print("Invalid Input!\nPlease follow the instruction!")
                print(INSTRUCTIONS + "\n" + DASH_SEPARATOR)
                cmd = input("Please enter your command: ")
                continue

            # perform move operation, re-enter command if exception caught
            try:
                move(self.get_model(), src, dest)
            except IllegalMoveError:
                print("Illegal Move!\nPlease follow the instruction!")
                print(INSTRUCTIONS + "\n" + DASH_SEPARATOR)
                cmd = input("Please enter your command: ")
                continue

            print(self.get_model())
            print(DASH_SEPARATOR)

            # check if the game is ended
            if (self._winning_check()):
                print("Congratulation!")
                cmd = "quit"
            else:
                cmd = input("Please enter your command: ")

        print("Thank you for playing.")

    def _winning_check(self):
        """ (ConsoleController) -> bool
        Return True if all cheeses are moved to the last stool.
        This represents the game is ended.
        """
        last_stool = self.get_model().get_stool(-1)
        return len(last_stool) == self.get_model().number_of_cheeses()
    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 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
    """
    src = 0
    spare_1 = 1
    spare_2 = 2
    dest = 3
    num_cheeses = model.number_of_cheeses()

    rec_four_stools(model, num_cheeses, src, spare_1, spare_2, dest,
                    delay_btw_moves, console_animate)

if __name__ == '__main__':
    # DO NOT MODIFY THE CODE BELOW.
    model = TOAHModel(4)
    model.fill_first_stool(number_of_cheeses=8)

    tour_of_four_stools(model, console_animate=True, delay_btw_moves=0.5)
    print(model.number_of_moves())

    # some debug code below, don't forget to comment it #
    # print(model.get_move_seq().get_moves())