|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionTowers of Hanoi is a puzzle game where there are three stands, each holds number of plates.
Please note that I used the recursive method. BackgroundFormally, Towers of Hanoi recursive function is given by : void Hanoi(int platesCount, int from, int dest, int by)
{
if (platesCount==1)
{
printf(
"Move the plate from %d to %d through %d"
, from, dest, by);
}
else
{
Hanoi(platesCount -1, from, by, dest);
Hanoi(1, from, dest, by);
Hanoi(platesCount -1, by, dest, from);
}
}
And here is a conceptual image :
Credits: MG from Wikipedia
Using the ProgramWhen you lunch the application you will see the next screen:
Then you have to select whether to let the program step into solution automatically or not.
Using the CodeWhile implementing the program I faced a problem in separating steps since I used the recursive version, so I decided to keep the recursive way. But the call to Hanoi method will happen just first time when "next" or "solve" button is pressed. Inside Hanoi method I stored the states of the solution, meaning each time a call is happened the solution of the current step is stored in a list of integers. Since each step in Hanoi method require 4 parameters as mentioned above, 4 integer represents parameter is added to the list. Then each time SolveNextStep method is called, the program read from the list 4 items that represents the state. Available classes:
Anyway I'll describe methods in HanoiDrawer Class// Advance one step to solve Hanoi
void HanoiDrawer::SolveNextStep()
{
int platesCount
, source
, destination
, intermediate;
if(listSavedState.size()==0)
{
this->Hanoi(this->iPlatesCount, HanoiDrawer::SOURCE
, HanoiDrawer::DESTINATION, HanoiDrawer::INTERMEDIATE);
}
if(listSavedState.size() % 4 != 0 )
{
return;
}
platesCount = listSavedState.front();
listSavedState.pop_front();
source = listSavedState.front();
listSavedState.pop_front();
destination = listSavedState.front();
listSavedState.pop_front();
intermediate = listSavedState.front();
listSavedState.pop_front();
MovePlateFromTo(source, destination);
this->iMovesCount++;
if(iMovesCount == this->GetTotalMovesCount())
{
this->solved = true;
}
SetDlgItemInt(this->hWnd, this->countContainerResourceId,
GetMovesCount(), FALSE);
SetDlgItemText(this->hWnd, this->fromContainerResourceId
, PlaceIntToString(source).c_str() );
SetDlgItemText(this->hWnd, this->toContainerResourceId
, PlaceIntToString(destination).c_str() );
SetDlgItemText(this->hWnd, this->throughContainerResourceId
, PlaceIntToString(intermediate).c_str() );
}
// Draws stands and plates
// then do Invalidate
// this operation is required
// in each step
void HanoiDrawer::ReDraw()
{
DrawStands();
DrawPlates();
Invalidate();
}
// The internal function that is responsible
// about solve the problem.
// platesCount : how many plates
// source : the index of the source
// destination : the index of the destination
// intermediate : the index of the intermediate
void HanoiDrawer::Hanoi(int platesCount, int source, int destination, int intermediate)
{
if (platesCount == 1)
{
listSavedState.push_back(platesCount);
listSavedState.push_back(source);
listSavedState.push_back(destination);
listSavedState.push_back(intermediate);
return;
}
else
{
Hanoi(platesCount - 1, source, intermediate, destination);
Hanoi(1, source, destination, intermediate);
Hanoi(platesCount - 1, intermediate, destination, source);
return;
}
}
Improvements
Notices
History
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||