Skip to content

Instantly share code, notes, and snippets.

@tungli
Created March 14, 2021 12:01
Show Gist options
  • Save tungli/d98bfada2f35e9b0bc032c1783b3444d to your computer and use it in GitHub Desktop.
Save tungli/d98bfada2f35e9b0bc032c1783b3444d to your computer and use it in GitHub Desktop.
class Disc:
def __init__(self, size):
self.size = size
def __str__(self):
return self.size * "#"
class HanoiState:
"""Draws Hanoi Towers in ASCII art style.
This does not check for illegal moves nor does it implement error handling.
"""
line_width = 99
centers = (17, 17 + 33, 17 + 2*33)
smallest_size = 3
max_n = 10
labels = ("A", "B", "C")
label2index = {"A" : 0, "B" : 1, "C" : 2}
def __init__(self, n):
if n > HanoiState.max_n:
raise ValueError("Max {} discs allowed!".format(HanoiState.max_n))
else:
self.n = n
self.pegs = [self._init_discs(), [], []]
def _init_discs(self):
discs = []
size = HanoiState.smallest_size
for i in range(self.n):
discs.append(Disc(size))
size += 2
return list(reversed(discs))
def draw(self):
line_width, centers = HanoiState.line_width, HanoiState.centers
lines = [ list(line_width*" ") for _i in range(self.n + 3) ]
for i in range(len(lines)):
line = lines[i]
for j, peg in enumerate(self.pegs):
if i < len(peg):
disc = str(peg[i])
# TODO factor out center text to function
r = range(centers[j] - len(disc) // 2, centers[j] + len(disc)//2 + 1)
assert len(r) == len(disc)
line[r.start:r.stop] = list(disc)
else:
line[centers[j]] = '|'
for line in reversed(lines):
print("".join(line))
label_line = list(99*" ")
for l, c in zip(HanoiState.labels, centers):
label_line[c] = l
print("".join(label_line))
print(HanoiState.line_width * "-")
def move(self, f, t):
f, t = tuple(map(lambda x: HanoiState.label2index[x.strip()], (f, t)))
disc = self.pegs[f].pop()
self.pegs[t].append(disc)
def move_and_draw(self, f, t):
print(HanoiState.line_width * "-")
print("{}{} -> {}".format(47*" ", f, t))
self.move(f, t)
print(HanoiState.line_width * "-")
self.draw()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment