智能终端定制开发 ad
MTK/瑞芯微/高通-Android,智能模块/智能终端方案商

深度定制各类智能终端和智能硬件产品,提供硬件选型咨询、参考设计、元器件推荐、驱动开发、行业模块集成、操作系统定制与算法集成等软硬件定制服务。
contact.aspx

Android核心板产品覆盖2G、3G、4G通讯,双核、四核、八核CPU,可选的平台有MTK6580、MTK6737、MTK6750等,Android版本有5.1 6.0 7.0等。
contact.aspx

可广泛应用于低端智能POS、安防监控、车载设备、低端智能机器人、智能家居、智能硬件、工业智能手持设备、低端智能对讲设备、低端警务或执法设备、智能穿戴、贩卖机、物流柜、智能门禁系统等行业和设备。
contact.aspx

可提供以太网转串口透传,WIFI转串口透传,蓝牙转串口透传,CAN总线模拟量控制输出模块等。
contact.aspx

带3G或4G通讯功能,运行android系统,有多个串口,可以外挂各种模块:条码扫描、RFID、指纹识别、身份证识别、磁条卡、ID卡、GPS/北斗模块等。
contact.aspx

具有4G通讯功能,多个RS232或RS485接口,以太网接口,USB接口,CAN接口,多个AD输入。基于Android系统智能平台,方便APP应用开发。器件严格选型,运行稳定,质量可靠。
contact.aspx

汉诺塔游戏的设计
[VC 编程] 2008-04-03



作者:苍竹先生

下载源代码

汉诺塔问题是最经典的递归问题,笔者就该问题设计了这个游戏,由用户交互游戏和自动演示两部分组成,支持撤销功能、选关、自动完成等功能。

首先建立了类CMap,该类主要实现用户每一步的操作和画图显示功能,记录的时候只须记录每组盘子的个数和盘子的矩形。代码和注释如下:

//记录每一步的盘子的情况 class CMap { public: //每组盘子的个数 int iCount[3]; //3组盘子里面,每个盘子的位置,用矩形表示 RECT *Rect[3]; //构造函数 CMap() { //三组盘子,每组盘子的矩形 for(int i=0;i<3;i++) Rect[i]=new RECT[NUM]; //初始化每组盘子的个数 iCount[0]=NUM; iCount[1]=0; iCount[2]=0; //第一组盘子的矩形的位置 for(i=0;i<NUM;i++) { Rect[0][i].left=Center[0]-(NUM-i)*Dx2; Rect[0][i].right=Center[0]+(NUM-i)*Dx2; Rect[0][i].bottom=(NUM+1-i)*Dx; Rect[0][i].top=(NUM-i)*Dx; } //第二组盘子的矩形初始化为空 for(i=0;i<NUM;i++) { Rect[1][i].left=0; Rect[1][i].right=0; Rect[1][i].bottom=0; Rect[1][i].top=0; } //第三组盘子的矩形初始化为空 for(i=0;i<NUM;i++) { Rect[2][i].left=0; Rect[2][i].right=0; Rect[2][i].bottom=0; Rect[2][i].top=0; } } //运算符重载 CMap operator=(CMap Other) { //对新的CMap对象,应该重新分配内存 for(int i=0;i<3;i++) Rect[i]=new RECT[NUM]; //依次赋值 for(i=0;i<3;i++) { iCount[i]=Other.iCount[i]; for(int j=0;j<NUM;j++) Rect[i][j]=Other.Rect[i][j]; } //返回 return *(this); } //画图,显示盘子的情况 void OnDraw(HDC hdc) { //画出每个盘子 for(int i=0;i<3;i++) for(int j=0;j<iCount[i];j++) Rectangle(hdc, Rect[i][j].left, Rect[i][j].top, Rect[i][j].right, Rect[i][j].bottom); } //析构函数 ~CMap() { //内存的释放 for(int i=0;i<3;i++) { if(Rect[i]!=NULL) { Rect[i]=NULL; delete Rect[i]; } } } };
下面是汉诺塔的主类Hanio,该类的成员函数有OnDraw(),Undo(),Move(),AutoMove()等,分别实现汉诺塔的画图显示、撤销、移动盘子、自动移动盘子等功能,代码及注释如下:
class Hanio { public: //当前的步数 int iStep; //记录每一步的盘子的情况 CMap Record[MAXSTEP]; public: //构造函数 Hanio() { //初始化,步数为0 iStep=0; //初始化记录 for(int i=0;i<MAXSTEP;i++) { Record[i]=CMap(); } } //画图,显示汉诺塔的情况 void OnDraw(HDC hdc) { Record[iStep].OnDraw(hdc); } //撤销 void Undo() { if(iStep>0) iStep--; //重绘 Draw(); } //移动盘子 void Move(int iStart,int iEnd) { //得到当前盘子的记录 CMap Map=Record[iStep]; //移动的情况判断,去除非法的移动 if(iStart<0||iStart>=3) return; if(iEnd<0||iEnd>=3) return; if(iStart==iEnd) return; if(Map.iCount[iStart]<1) return; //得到移动前的开始组,结束组的盘子的个数 int iStartRectNum=Map.iCount[iStart]; int iEndRectNum=Map.iCount[iEnd]; //从小盘子移动到大盘子上面的情况是不可以的。 if(iEndRectNum>0) if(Width(Map.Rect[iStart][iStartRectNum-1])>=Width(Map.Rect[iEnd][iEndRectNum-1])) return; //步数累加 iStep++; //记录新的盘子的情况 Record[iStep]=Record[iStep-1]; //移走的那一组盘子的个数减少 Record[iStep].iCount[iStart]--; //被移到的那一组的盘子个数增加 Record[iStep].iCount[iEnd]++; //重新计算移动后的盘子的矩形 //主要是被移到的那一组的最上面那个盘子的矩形的计算 RECT rect; rect.left=Center[iEnd]-Width(Map.Rect[iStart][iStartRectNum-1])/2; rect.right=Center[iEnd]+Width(Map.Rect[iStart][iStartRectNum-1])/2; rect.bottom=(NUM+1-Map.iCount[iEnd])*Dx; rect.top=(NUM-Map.iCount[iEnd])*Dx; Record[iStep].Rect[iEnd][iEndRectNum]=rect; //刷新 SendMessage(hWnd,WM_PAINT,0,0); } //自动移盘子 void AutoMove(int iA,int iB,int iC,int iNum) { //递归实现自动移盘子 //递归的出口,如果个数为3,按如下进行移动。 if(iNum==3) { Move(iA,iC); ::Sleep(500); Move(iA,iB); ::Sleep(500); Move(iC,iB); ::Sleep(500); Move(iA,iC); ::Sleep(500); Move(iB,iA); ::Sleep(500); Move(iB,iC); ::Sleep(500); Move(iA,iC); ::Sleep(500); } //个数大于3,递归实现移动。 else { //递归自动移动。 AutoMove(iA,iC,iB,iNum-1); Move(iA,iC); ::Sleep(500); AutoMove(iB,iA,iC,iNum-1); } } };
程序实现的结果如下图:


由于堆栈内存的限制,选关不可能是无限个盘子,本程序设计的最大关数是8。自动移动是用递归实现的,自动移动的过程中,其他消息无法响应,可以改成多线程或由用户控制的形式。上述的程序附有Visual C++源代码,并在Windows XP和Visual C++6.0下调试成功。
[VC 编程添加评论 | 评论/阅读(0/296)
评论
昵称
主页
内容
递交


Copyright @ 我的开发笔记     2008 - 2017         粤ICP备19155526号-1