首先展示一下程序演示效果:
一、程序功能:
1、可演示盘数为2-7时,移动步骤
2、点击spin按钮可增或减盘子的个数,也可在编辑框内输入数字,数字必须在3-7之间
3、可连续移动盘子,也可在中间暂停,对应的按钮为“开始演示”和“暂停”
4、可单步演示盘子的移动,对应的按钮为“上一步”与“下一步”
二、基本思路:
传统的汉诺塔程序采用的是递归程序,但这并不便于进行单步操作。我这采用栈方式来实现,将中间结果存下来,以便下一步操作,然后上一步的功能是通过vector数组,存下已进行的操作。然后主要利用的SetTimer和KillTimer来实现演示,加快及减慢则是通过修改Timer的执行时间间隔。
三、局部功能实现
1、绘画背景图
void CMyDlg::ShowBg(CDC * dc)
void CMyDlg::ShowBg(CDC * dc){
//显示背景
CDC pdc, ddc;
pdc.CreateCompatibleDC(dc); // 创建一个临时显示设备
ddc.CreateCompatibleDC(dc); // 创建一个加载盘子的临时显示设备
CBitmap bmp, * obmp;
bmp.LoadBitmap(IDB_BG); // 加载背景图片
obmp = pdc.SelectObject(&bmp); // 将图片显示在设备pdc上。
//显示盘子
int n[] = {0, 0, 0}; // 用于存放每个柱子已显示多少盘子
for(int i = 0; i < number ; i++){
CBitmap dbmp, * odbmp;
dbmp.LoadBitmap(IDB_B7 - i); // 加载从大到小第i个盘子图片
odbmp = ddc.SelectObject(&dbmp); // 将盘子显示在设备ddc上。
pdc.BitBlt(10 + 150*dish[i], 225 - n[dish[i]]*20, 140, 15, &ddc, 0, 0, SRCCOPY); // 将ddc拷贝到临时显示设备pdc对应位置上
n[dish[i]] ++;
ddc.SelectObject(odbmp); // 显示完毕,还原设备
}
dc->BitBlt(10, 10, 460, 260, &pdc, 0, 0, SRCCOPY); // 将pdc拷贝到程序显示设备dc上
pdc.SelectObject(obmp); // 显示完毕,还原设备
}
2、下一步功能实现
void CMyDlg::OnBnClickedNextButton()
void CMyDlg::OnBnClickedNextButton()
{
// TODO: 在此添加控件通知处理程序代码
flag1 = true;
if (0 == number) {
MessageBox("请选择盘子数!");
return;
}
if (!flag)
{
CMyDlg::OnButton1();
}
else if (idx < int(res.size() - 1))
{
++idx;
dish[res[idx].num] = res[idx].end;
Invalidate(FALSE);//重绘
}
else
SetTimer(1015, last, NULL);
}
3、上一步功能实现
void CMyDlg::OnBnClickedPrevButton()
{
// TODO: 在此添加控件通知处理程序代码
flag1 = true;
//char str[10];
//sprintf(str, "%d\n", idx);
//MessageBox(str);
if (idx >= 0)
{
dish[res[idx].num] = res[idx].beg;
--idx;
Invalidate(FALSE);//重绘
}
}
4、加快,减慢功能实现
//加快
void CMyDlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
if (last > 100)
{
last -= 100;
UpdateData(FALSE);
KillTimer(1015);
SetTimer(1015, last, NULL);
}
}
//减慢
void CMyDlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
if (last < 800)
{
CString str;
last += 100;
UpdateData(FALSE);
KillTimer(1015);
SetTimer(1015, last, NULL);
}
}
具体实现见程序
四、参考工程
本人代码是参考网上修改的,感觉实现上应该还有有待提高的地方,各位可根据需求进行修改,工程环境是VS2015 + MFC。工程已上传
地址如下:点击打开链接
github地址:点这