Nov-18-2019, 08:24 PM
Hello
Puzzle Tower of Hanoi
Puzzle Tower of Hanoi
""" Puzzle Tower of Hanoi """ class Disk: def __init__(self, number, color): self.number = number self.view = self.get_disk(number, color) def get_disk(self, number, color): disk = '\u2588' * (number*2+1) shift = ' ' * ((13-len(disk))//2) disk_line = f'{shift}{disk}{shift}' return f'\033[{color}m{disk_line}\033[0m' def get_pole(pyramid): pole, j = [], 1 height = len(pyramid) free = 6 - height for i in range(6): if i < free: pole.append(' \u2551 ') else: disk = pyramid[height - j] pole.append(disk.view) j += 1 return pole def show(poles): show_time = [] for i in list('123'): show_time.append(get_pole(poles[i])) fmt = '{:^13}'*3 print(fmt.format(1, 2, 3)) for a, b, c in zip(*show_time): print(f'{a}{b}{c}') def check_moves(move, poles): from_pole, to_pole = move.split() if from_pole == to_pole or \ not from_pole in poles or\ not to_pole in poles: return False fp = poles[from_pole] if len(fp) > 0: move_disk = fp[-1] else: return False tp = poles[to_pole] if len(tp) > 0: top_disk = tp[-1] else: return True if move_disk.number < top_disk.number: return True return False def move(from_pole, to_pole, poles): fp, tp = poles[from_pole], poles[to_pole] tp.append(fp.pop()) def choice_n_disks(): n_disks = 3 s = input('Enter the number of disks[1..5](default 3):\n>> ').strip() if s in list('12345'): n_disks = int(s) low_steps = 2**n_disks-1 print(f'Disks in tower: {n_disks}.\nMinimum steps: {low_steps}.') return n_disks, low_steps def introduce(): print('Puzzle "Tower of Hanoi".\n' 'Move tower to position two.\n' 'Example first move: 1 2 .\n' 'Rules: https://en.wikipedia.org/wiki/Tower_of_Hanoi .') def run_game(poles, win): show(poles) steps = 1 while True: s = input(f'Step {steps}, enter move or write "exit":\n>> ') if s == 'exit': exit() elif len(s.split()) == 2 and check_moves(s, poles): move(*s.split(), poles) show(poles) if win == poles['2']: return steps steps += 1 else: print(f'Error, invalid move: "{s}".') def get_poles(n_disks): colors = [91, 92, 94, 95, 96] poles = { '1': [], '2': [], '3': [], } pole = poles['1'] for i in range(n_disks, 0, -1): pole.append(Disk(i, colors[i-1])) return poles, pole.copy() def main(): win_msg = 'Congratulations! The tower has been moved! Steps: ' introduce() while True: n_disks, low_steps = choice_n_disks() poles, win = get_poles(n_disks) steps = run_game(poles, win) if steps == low_steps: print(f'{win_msg}{steps}. Excellent!!!') else: print(f'{win_msg}{steps}. You can better!!!') s = input("Let's play some more?([y]/n)\n>> ") if s == 'n': return if __name__ == '__main__': main()