汉诺塔游戏的设计

作者:苍竹先生

下载源代码

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

首先建立了类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

{

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

{

Rect[1][i].left=0;

Rect[1][i].right=0;

Rect[1][i].bottom=0;

Rect[1][i].top=0;

}

//第三组盘子的矩形初始化为空

for(i=0;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

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

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

{

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下调试成功。

c语言汉诺塔课设计报告,汉诺塔游戏的设计相关推荐

  1. python小游戏课程设计报告_贪吃蛇游戏课程设计报告

    贪吃蛇游戏程序设计 一.课程设计任务 贪吃蛇小游戏程序设计 二.设计要求 通过游戏程序设计,提高编程兴趣与编程思路,巩固 C 语言中所学的知识,合理的运 用资料,实现理论与实际相结合. ( 1 ) . ...

  2. python黑白棋结课设计报告_黑白棋游戏课程设计

    黑白棋程序源代码 : #include "graphics.h" #include "stdio.h" #include "stdlib.h" ...

  3. 计算机钢琴汇编设计报告,TC键盘模拟钢琴发声设计报告.docx

    文档介绍: TC键盘模拟钢琴发声设计报告.docxTC键盘模拟钢琴发声"设计报告 设计任务要求 用PC键盘模拟钢琴发声 1 .使PC机成为一架可以弹奏的"钢琴:当按下数字1时,依次 ...

  4. c语言学生考勤系统课设报告,C语言课程设计总结报告学生考勤系统设计

    C语言课程设计总结报告学生考勤系统设计 C语言程序设计课程设计报告设计题目:学生考勤系统设计专 业 自 动 化 班 级 自 动 化 071 学 生 朱 胜 佳 指导教师 梁 德 胜 2008 年 春季 ...

  5. c语言学生成绩查询课设报告,C语言课设报告(学生考试成绩查询程序)【荐】.doc...

    C语言课设报告(学生考试成绩查询程序)[荐].doc 学生考试成绩查询程序 学号:******** 姓名:***** 完成日期:****年月 通过键盘输入学生的考试信息,包括:学号.姓名.课程名称.学 ...

  6. 语言程序推箱子课设报告_“延期不延学”第13期 | C++篇 | c++课设建议

    关于C++课程设计的一些建议 虽然现在学校还未开学,但已经正式上课了.大家需要在课程设计答辩前完成自己的C++课程设计. 一些C++基础好的同学,说不定已经完成了.学而当初只花了两天的时间就完成了一个 ...

  7. 计算机网络课程设计报告 组建校园局域网,计算机网络课程设计报告-组建校园局域网.pdf...

    课程设计报告 课程设计题目:组建校园局域网 专 业: 班 级: 姓 名 : 学 号 : 指导教师 : 2015 年 7 月 3 日 计算机网络课程设计 目录 一.课程设计目的及要求 - 2 - 1.1 ...

  8. java课程设计报告连连看_连连看_java课程设计报告.doc

    连连看_java课程设计报告 <连连看> 项目设计报告 专 业: 软件工程 班 级: 07级2班 姓 名: 二00九 年 七 月 二十一 日 目 录 1.项目设计目的.意义-------- ...

  9. android音乐播放器课程设计报告,android音乐播放器课程设计报告11.doc

    最新精品文档,知识共享! android音乐播放器课程设计报告 基于Android音乐播放器的设计与实现 滨江学院 <移动通信程序设计> 课程设计 题 目 院 系 专 业学生姓名 学 号 ...

  10. python贪吃蛇的实验报告_贪吃蛇游戏课程设计实验报告

    DOC 可编辑修改 -------- 为你整理各种最新最全办公范文 -------- 双击可以删除 爱心 --- 用心 --- 恒心 贪吃蛇游戏课程设计实验报告 辽 宁 科 技 大 学 课程设计说明书 ...

最新文章

  1. [冲昏头脑]IDEA中的maven项目中学习log4j的日志操作
  2. 曙光i620c20用户手册_曙光天阔I620-G20服务器技术白皮书.pdf
  3. The way of Webpack learning (II.) -- Extract common code(多页面提取公共代码)
  4. 春季每日一题2022 Week 2 【完结】
  5. windows + cmake + vs2019 编程
  6. angularjs 同步請求_angularjs $q、$http 处理多个异步请求
  7. spring中定时器的使用
  8. 电脑计算器_哪几种计算器可以携带入考场!注会考试忘带计算器了怎么办?
  9. set集合判断集合中是否有无元素_第八章 集合
  10. throw er; // Unhandled 'error' event 和Error: listen EADDRNOTAVAIL 192.168.0.109:8081
  11. java零基础从入门到精通(全)
  12. 关于git 提交报错rejected解决
  13. 机器学习(六)统计学习理论
  14. cpu_relax()函数的意义
  15. 川土微电子|推出带隔离电源的双通道数字隔离器
  16. css纯代码实现圆边框和圆按钮
  17. 关于U盘格式化后缩水的解决办法
  18. 护理专业有必要考计算机吗,护理专业考研有前途吗
  19. Rails sanitize
  20. Excel表格批量将文本转换为超链接 批量文本转链接 一键转URL

热门文章

  1. 利器 | Terminal Shell 改造记录 Windows Terminal + ZSH + Tmux
  2. 对闰年和平年计算均值
  3. 给设计师的建设性反馈
  4. [渝粤教育] 九江职业技术学院 客户关系管理 参考 资料
  5. xp 架设网站服务器,WinXP如何设置iis服务器?WinXP iis服务器设置教程
  6. JAVA-判断三阶矩阵是否满秩
  7. CC00024.NavigationLog——|Open网络2.4.9服务端/客户端部署/本地client配置/连接成功测试|
  8. 深度学习与神经网络之 反卷积/转置卷积 (deconvolution/transposed convolution/fractional strided convolution) (upsample)
  9. 英特尔DAOS分布式异步存储系统
  10. Window应急响应(七 NesMiner挖矿病毒)