-
Notifications
You must be signed in to change notification settings - Fork 0
/
hanoiGame.py
119 lines (100 loc) · 3.88 KB
/
hanoiGame.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
from collections import deque
from tower import Tower, TowerPosition
from hanoiGameGui import HanoiGameGui
class HanoiGame(HanoiGameGui):
def __init__(self, canvas, numDiscs = 3):
super(HanoiGame, self).__init__(canvas, numDiscs)
discs = range(1, numDiscs + 1)
self.left_tower = Tower('Torre Esquerda', TowerPosition.Left)
self.central_tower = Tower('Torre Central', TowerPosition.Center, sorted(discs, reverse=True))
self.right_tower = Tower('Torre Direita', TowerPosition.Right)
self.disc_1_mutex = True
self.moveCount = 0
def move(self):
if self.disc_1_mutex:
self.forward_move(1)
self.disc_1_mutex = False
else:
disc_on_left = self.left_tower.top()
disc_on_center = self.central_tower.top()
disc_on_right = self.right_tower.top()
values = [v for v in [disc_on_left, disc_on_center, disc_on_right] if v != 1 and v > 0]
minValue = min(values)
self.forward_move(minValue)
self.disc_1_mutex = True
self.moveCount += 1
def able_tower(self, d, tower):
if len(tower) == 0:
return True
value = tower[len(tower) - 1]
if d > value:
return False
return True
def forward_move(self, d):
if d in self.right_tower:
self.next_move(d, self.left_tower, self.central_tower)
elif d in self.central_tower:
self.next_move(d, self.right_tower, self.left_tower)
elif d in self.left_tower:
self.next_move(d, self.right_tower, self.central_tower)
def next_move(self, d, tower_a, tower_b):
#first movement
if len(tower_a) == 0 and len(tower_b) == 0:
self.move_disc(d, tower_b)
return
#if any tower is unable to receive the disk, it goes the other way
if not self.able_tower(d, tower_a):
self.move_disc(d, tower_b)
return
if not self.able_tower(d, tower_b):
self.move_disc(d, tower_a)
return
disc_on_a = tower_a.top()
disc_on_b = tower_b.top()
if (disc_on_a - 1) == d:
self.move_disc(d, tower_a)
elif (disc_on_b - 1) == d:
self.move_disc(d, tower_b)
elif d == 1:
tower = self.disc1_new_tower(tower_a, tower_b)
print('disc1 new tower', tower)
self.move_disc(d, tower)
def disc1_new_tower(self, tower_a, tower_b):
current_tree = []
disc1_current_tower = self.get_tower(1)
i = len(disc1_current_tower) - 1
current_tree.append(disc1_current_tower[i])
while disc1_current_tower[i - 1] - disc1_current_tower[i] == 1:
i-=1
current_tree.append(disc1_current_tower[i])
max_current_tree = max(current_tree)
len_current_tree = len(current_tree)
len_is_odd = len_current_tree % 2 != 0
building_tower = self.get_tower(max_current_tree + 1)
if len_is_odd:
if building_tower == tower_a:
return tower_a
return tower_b
else:
if building_tower == tower_a:
return tower_b
return tower_a
def get_tower(self, d):
if d in self.right_tower:
return self.right_tower
elif d in self.central_tower:
return self.central_tower
elif d in self.left_tower:
return self.left_tower
def move_disc(self, d, tower):
if d in self.left_tower:
self.left_tower.pop()
if d in self.central_tower:
self.central_tower.pop()
if d in self.right_tower:
self.right_tower.pop()
#self.write_movement(d, tower)
super(HanoiGame, self).moveDiscToTower(d, tower)
tower.append(d)
def write_movement(self, d, tower):
print(d, '=>', tower)