汉诺塔游戏的设计
2010-08-15 20:47:43 来源:WEB开发网下面是汉诺塔的主类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);
}
}
};
更多精彩
赞助商链接