need help with tower of hanoi logic

I'm working on making a program that can solve a tower of hanoi with a given number of rings on it. My logic is faulty and the program eventually falls into an infinite loop where it moves the same ring between the same two pegs for eternity.

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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
Program solves the tower of hanoi logic puzzle.
Size of towers is determined by user.
Puzzle is solved using recursion.
Created by REDACTED.
Date Created: 10/27/2016
Date Last Modified: 11/2/2016
*/

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <vector>

using namespace std;

void print(const vector <vector<int>>&, const int);
void solve(vector <vector<int>>&, const int);
void performMove(vector <vector<int>>&, const int, const int, const int);
bool checkMove(const vector <vector<int>>&, const int, const int, const int);


int _tmain(int argc, _TCHAR* argv[])
{
	const int WIDTH = 3;
	int towerSize;
	int loop;
	int innerLoop;
	vector <vector<int>> towers;

	cout << "Please input the number of rings you want the program to solve.\n";
	cin >> towerSize;

	//set array size
	towers.resize(WIDTH);
	for (loop = 0; loop < WIDTH; loop++)
		towers.at(loop).resize(towerSize);
	

	//initialize vector of vectors
	for (loop = 0; loop < towerSize; loop++)
	{
		for (innerLoop = 0; innerLoop < WIDTH; innerLoop++)
		{
			if (innerLoop == 0)
				towers.at(innerLoop).at(loop) = loop + 1;
			else
				towers.at(innerLoop).at(loop) = 0;
		}
	}

	print(towers, towerSize);
	solve(towers, towerSize);

	system("pause");
	return 0;
}


void print(const vector <vector<int>> &towers, const int towerSize)
{
	int loop;
	int innerLoop;

	//clears previous iteration
	system("cls");
	//print vector of vectors contents
	for (loop = 0; loop < towerSize; loop++)
	{
		for (innerLoop = 0; innerLoop < 3; innerLoop++)
		{
			cout << towers.at(innerLoop).at(loop) << " ";
		}
		cout << endl;
	}
	//pause to allow user to see printed output
	Sleep(1000);
}


//solves tower of hanoi recursisvely
void solve(vector <vector<int>> &towers, const int towerSize)
{
	//variables go here
	//base case activates if solved
	if (towers.at(2).at(0) == 1)
		return;

	if (towerSize % 2 == 0)
	{
		//attempts to make valid move between pegs 1 and 2
		if (checkMove(towers, 0, 1, towerSize))
		{
			performMove(towers, 0, 1, towerSize);
			print(towers, towerSize);
		}
		else if (checkMove(towers, 0, 1, towerSize))
		{
			performMove(towers, 0, 1, towerSize);
			print(towers, towerSize);
		}

		//attempts to make valid move between pegs 1 and 3
		if (checkMove(towers, 0, 2, towerSize))
		{
			performMove(towers, 0, 2, towerSize);
			print(towers, towerSize);
		}
		else if(checkMove(towers, 2, 0, towerSize))
		{
			performMove(towers, 2, 0, towerSize);
			print(towers, towerSize);
		}

		//attempts to make valid move between pegs 2 and 3
		if (checkMove(towers, 1, 2, towerSize))
		{
			performMove(towers, 1, 2, towerSize);
			print(towers, towerSize);
		}
		else if (checkMove(towers, 2, 1, towerSize))
		{
			performMove(towers, 2, 1, towerSize);
			print(towers, towerSize);
		}
	}
	else
	{
		//attempts to make valid move between towers 1 and 3
		if (checkMove(towers, 0, 2, towerSize))
		{
			performMove(towers, 0, 2, towerSize);
			print(towers, towerSize);
		}
		else if (checkMove(towers, 2, 0, towerSize))
		{
			performMove(towers, 2, 0, towerSize);
			print(towers, towerSize);
		}

		//attempts to make valid move between towers 1 and 2
		if (checkMove(towers, 0, 1, towerSize))
		{
			performMove(towers, 0, 1, towerSize);
			print(towers, towerSize);
		}
		else if (checkMove(towers, 1, 0, towerSize))
		{
			performMove(towers, 1, 0, towerSize);
			print(towers, towerSize);
		}

		//attempts to make valid move between towers 3 and 2
		if (checkMove(towers, 2, 1, towerSize))
		{
			performMove(towers, 2, 1, towerSize);
			print(towers, towerSize);
		}
		else if (checkMove(towers, 1, 2, towerSize))
		{
			performMove(towers, 1, 2, towerSize);
			print(towers, towerSize);
		}
	}
	//goes to next 3 steps
	solve(towers, towerSize);
}


//moves ring from a given tower to another given tower.
void performMove(vector <vector<int>> &towers, const int moveFrom, 
	const int moveTo, const int towerSize)
{
	int loop = 0;
	int top1 = towerSize-1;
	int top2 = towerSize-1;

	//finds top of tower ring is to be moved from
	for (loop = 0; loop < towerSize - 1; loop++)
	{
		if (towers.at(moveFrom).at(loop) != 0)
			top1--;
	}

	//finds top of tower ring is to be moved to
	for (loop = 0; loop < towerSize - 1; loop++)
	{
		if (towers.at(moveTo).at(loop) != 0)
			top2--;
	}

	if (towers.at(moveTo).at(top2) == 0)
		towers.at(moveTo).at(top2) = towers.at(moveFrom).at(top1);
	else if (top2 > 0)
		towers.at(moveTo).at(top2 - 1) = towers.at(moveFrom).at(top1);

	towers.at(moveFrom).at(top1) = 0;
}


//checks that a move can be made between given towers
bool checkMove(const vector <vector<int>> &towers, const int moveFrom, 
	const int moveTo, const int towerSize)
{
	bool output = true;
	int loop = 0;
	int top1 = towerSize-1;
	int top2 = towerSize-1;

	//finds top of tower ring is to be moved from
	for (loop = 0; loop < towerSize-1; loop++)
	{
		if (towers.at(moveFrom).at(loop) != 0)
			top1--;
	}

	//finds top of tower ring is to be moved to
	for (loop = 0; loop < towerSize-1; loop++)
	{
		if (towers.at(moveTo).at(loop) != 0)
			top2--;
	}


	//if ring from first tower is larger than ring from second,
	//and second tower is not empty, change output to false
	if (towers.at(moveFrom).at(top1) > towers.at(moveTo).at(top2) &&
		towers.at(moveTo).at(towerSize-1) != 0)
		output = false;

	return output;
}
Can you tell us the function that causes that problem?
It's the series of if statements in the solve function, which I based off the first example on the wikipedia article for Tower of Hanoi
Last edited on
Topic archived. No new replies allowed.