汉诺塔演示程序(MFC)

首先展示一下程序演示效果:

汉诺塔动态演示

一、程序功能:

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。工程已上传

地址如下:点击打开链接














猜你喜欢

转载自blog.csdn.net/happyeveryday62/article/details/80032157