Skip to content

Instantly share code, notes, and snippets.

@yi-jiayu
Last active November 26, 2015 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yi-jiayu/82f675b9fa03dd278aa9 to your computer and use it in GitHub Desktop.
Save yi-jiayu/82f675b9fa03dd278aa9 to your computer and use it in GitHub Desktop.
from collections import namedtuple
Disk = namedtuple('Disk', ['size', 'colour'])
class BicolorTowersOfHanoi(object):
def __init__(self, disks=3):
self._disks = disks
self._moves = 0
self._towers = {1: [], 2: [], 3: []}
self.reset()
def reset(self):
self._moves = 0
self._towers[1] = [Disk(x + 1, 'black' if x & 1 else 'white') for x in reversed(range(self._disks))]
self._towers[2] = [Disk(x + 1, 'white' if x & 1 else 'black') for x in reversed(range(self._disks))]
self._towers[3] = []
self._render()
def move(self, from_, to):
if from_ == to or from_ not in (1, 2, 3) or to not in (1, 2, 3):
print('Invalid move!')
return
if len(self._towers[from_]) == 0:
print('There are no more disks on that stack!')
return
if len(self._towers[to]) == 0 or self._towers[from_][-1].size <= self._towers[to][-1].size:
self._towers[to].append(self._towers[from_].pop())
self._moves += 1
self._render()
else:
print("Can't move a larger disk onto a smaller disk!")
def _render(self):
width = self._disks * 4 - 1
for i in reversed(range(self._disks * 2)):
row = []
for j in (1, 2, 3):
try:
size = self._towers[j][i].size * 4 - 1
colour = self._towers[j][i].colour
symbol = 'X' if colour == 'black' else 'O'
row.append(str.center(symbol * size, width))
except (IndexError, AttributeError):
row.append(str.center('|', width))
pass
print('{} {} {}'.format(*row))
print('Moves: {}'.format(self._moves))
# win checking not working yet
# if (len(self._towers[1]) == 0 or self._towers[1][0].colour != 'black') and (
# len(self._towers[2]) == 0 or self._towers[2][0] != 'white'):
# if {self._disks, self._disks, 0} == set(len(x) for x in self._towers.values()):
# win = 0
# for x in self._towers.values():
# if len(x) == 0:
# win += 1
# elif set(y.colour for y in x) == set(x[0]):
# win += 1
# if win == 2:
# print('Congratulations! You won!')
# break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment