Created
March 14, 2021 12:01
-
-
Save tungli/d98bfada2f35e9b0bc032c1783b3444d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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