📄 hanoitowerdoc.cpp
字号:
// HanoiTowerDoc.cpp : implementation of the CHanoiTowerDoc class
//
#include "stdafx.h"
#include "HanoiTower.h"
#include "HanoiTowerDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHanoiTowerDoc
IMPLEMENT_DYNCREATE(CHanoiTowerDoc, CDocument)
BEGIN_MESSAGE_MAP(CHanoiTowerDoc, CDocument)
//{{AFX_MSG_MAP(CHanoiTowerDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHanoiTowerDoc construction/destruction
CHanoiTowerDoc::CHanoiTowerDoc()
{
// TODO: add one-time construction code here
m_pDisc=NULL;
m_nDiscNum=5;
m_nIsAuto=0;
m_nIsFinished=0;
m_bIsOpenFile=FALSE;
m_strSpeed="中速";
m_nDelay=600;
}
CHanoiTowerDoc::~CHanoiTowerDoc()
{
//清楚堆栈,消灭野指针
if(m_pDisc!=NULL)
{
delete[] m_pDisc;
m_pDisc=NULL;
}
m_DiscStepList.RemoveAll();
}
BOOL CHanoiTowerDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
//注意顺序
InitializeTower();
InitializeDisc();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CHanoiTowerDoc serialization
void CHanoiTowerDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{ //storing code
if(m_DiscStepList.IsEmpty())
{
AfxMessageBox("没有开始游戏,不能存盘", NULL);
}
else
{
ar<<m_nIsAuto<<m_nDiscNum<<m_nDelay<<m_strSpeed;
TRACE("saving m_nIsAuto is:%d, m_nDiscNum is:%d\n", m_nIsAuto, m_nDiscNum);
ListSerialize(ar);
DiscArrSerialize(ar);
}
}
else
{ //loading code
ar>>m_nIsAuto>>m_nDiscNum>>m_nDelay>>m_strSpeed;
m_bIsOpenFile=TRUE;
TRACE("loading m_nIsAuto is:%d, m_nDiscNum is:%d\n", m_nIsAuto, m_nDiscNum);
ListSerialize(ar);
DiscArrSerialize(ar);
//路径清空
SetPathName(" ");
}
}
/////////////////////////////////////////////////////////////////////////////
// CHanoiTowerDoc diagnostics
#ifdef _DEBUG
void CHanoiTowerDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CHanoiTowerDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CHanoiTowerDoc commands
void CHanoiTowerDoc::AutoPlay()
{
//复制一个disc对象组,以保留原对象组。
Disc *pDiscArr=NULL;
pDiscArr=new Disc[m_nDiscNum];
for(int i=0; i<m_nDiscNum; i++)
{
(pDiscArr+i)->m_nDiscCurrentLayer=(m_pDisc+i)->m_nDiscCurrentLayer;
(pDiscArr+i)->m_nDiscCurrentTower=(m_pDisc+i)->m_nDiscCurrentTower;
(pDiscArr+i)->m_nDiscSerialNum=(m_pDisc+i)->m_nDiscSerialNum;
(pDiscArr+i)->m_pointCenterBottom=(m_pDisc+i)->m_pointCenterBottom;
(pDiscArr+i)->m_sizeDisc=(m_pDisc+i)->m_sizeDisc;
}
//自动运算,并记录步骤
Hanoi(m_nDiscNum, m_TowerA, m_TowerB, m_TowerC, pDiscArr);
//释放堆栈空间,清除野指针
delete[] pDiscArr;
pDiscArr=NULL;
m_nIsFinished=1;
}
void CHanoiTowerDoc::Hanoi(int nCount,
Tower &T1,
Tower &T2,
Tower &T3,
Disc *pDiscArr)
{
if (nCount==1)
{
move(T1, T3, pDiscArr);
}
else
{
Hanoi(nCount-1, T1, T3, T2, pDiscArr);
move(T1, T3, pDiscArr);
Hanoi(nCount-1, T2, T1, T3, pDiscArr);
}
}
void CHanoiTowerDoc::move(Tower &FromTower,
Tower &ToTower,
Disc *pDiscArr)
{
Disc *pMoveDisc;
//获得当前搬运的disc序号
pMoveDisc=pDiscArr+FromTower.m_nTopDiscSerialNum-1;
//原disc矩形存入链表
CRect *oldDiscRect;
oldDiscRect=new CRect; //建立CRect类指针,用于存储原Disc矩形
oldDiscRect->CopyRect(&(pMoveDisc->GetDisc())); //复制原矩形
m_DiscStepList.AddTail(oldDiscRect) ;
//移动Disc并修改相关数据成员
FromTower.m_nTotalDiscNum--; //源塔中disc总数减一
ToTower.m_nTotalDiscNum++; //目标塔中disc总数加一
ToTower.m_nTopDiscSerialNum=pMoveDisc->m_nDiscSerialNum; //目标塔顶层disc序号改为当前搬运的disc序号
//遍历所有disc,将原目标塔上的disc的所在层加一;
//将源塔上的所有disc所在层减一
//被移动的disc,目前还在原塔,但是其所在层已经由1变为0
//这不影响,下一步就是修改被移动disc的属性。
for(int i=0; i<m_nDiscNum; i++)
{
if( (pDiscArr+i)->m_nDiscCurrentTower==FromTower.m_nTowerSerialNum )
{
(pDiscArr+i)->m_nDiscCurrentLayer--;
if((pDiscArr+i)->m_nDiscCurrentLayer==1)
{
FromTower.m_nTopDiscSerialNum=(i+1);
}
}
else if((pDiscArr+i)->m_nDiscCurrentTower==ToTower.m_nTowerSerialNum )
{
(pDiscArr+i)->m_nDiscCurrentLayer++;
}
}
//修改被移动disc的属性
pMoveDisc->m_nDiscCurrentLayer=1;
pMoveDisc->m_nDiscCurrentTower=ToTower.m_nTowerSerialNum;
//重新获得disc的重点位置
pMoveDisc->SetCerterBottomPoint(ToTower);
//移动后的disc存入链表
CRect *newDiscRect;
newDiscRect=new CRect; //建立CRect类指针,用于存储移动后Disc矩形
newDiscRect->CopyRect(&(pMoveDisc->GetDisc())); //复制移动后矩形
m_DiscStepList.AddTail(newDiscRect);
}
void CHanoiTowerDoc::InitializeDisc()
{
//初始化碟子
m_pDisc=new Disc[m_nDiscNum];
for(int i=0; i<m_nDiscNum; i++)
{
//位置相关
(m_pDisc+i)->m_nDiscCurrentTower=1;
(m_pDisc+i)->m_nDiscCurrentLayer=i+1;
(m_pDisc+i)->m_nDiscSerialNum=i+1;
//绘图相关
(m_pDisc+i)->m_sizeDisc.cy=30;
(m_pDisc+i)->m_sizeDisc.cx=100+20*i;
(m_pDisc+i)->m_pointCenterBottom.x=m_TowerA.m_pointCenter.x;
(m_pDisc+i)->m_pointCenterBottom.y=m_TowerA.m_sizeBase.cy+(m_nDiscNum-i-1)*30;
(m_pDisc+i)->m_DiscColor=GetColor(i+1);
}
}
void CHanoiTowerDoc::InitializeTower()
{
//初始化汉诺塔
m_TowerA.InitialTower(1, 1, m_nDiscNum);
m_TowerB.InitialTower(2, 0, 0);
m_TowerC.InitialTower(3, 0, 0);
}
COLORREF CHanoiTowerDoc::GetColor(int nDiscNum)
{
COLORREF Color;
//根据碟子序号决定碟子颜色
int ColorNum=(nDiscNum-1)%3;
switch(ColorNum)
{
case 0:
{
Color=RGB(0,255,0);
break;
}
case 1:
{
Color=RGB(255,0,0);
break;
}
case 2:
{
Color=RGB(0,128,255);
break;
}
default:
{
break;
}
}
return Color;
}
void CHanoiTowerDoc::ListSerialize(CArchive& ar)
{
int listlen; //记录链表长度
POSITION position; //链表位置指针
if (ar.IsStoring())
{ //storing code
CRect tempRect; //建立临时矩形对象
//保存链表
listlen=m_DiscStepList.GetCount(); //获得链表长度
ar<<listlen; //保存链表长度
position=m_DiscStepList.GetHeadPosition();
for(int i=0; i<listlen; i++)
{
tempRect=(*m_DiscStepList.GetAt(position));
ar<<tempRect;
m_DiscStepList.GetNext(position);
TRACE("save list %d is: %d\n", i, tempRect.bottom);
}
}
else
{ //loading code
CRect *pTempRect; //临时矩形对象
ar>>listlen; //读出长度
m_DiscStepList.RemoveAll(); //清除原队列
for(int i=0; i<listlen; i++)
{
pTempRect=new CRect;
ar>>(*pTempRect);
m_DiscStepList.AddTail(pTempRect);
TRACE("load list %d is: %d\n", i, pTempRect->bottom);
}
}
}
void CHanoiTowerDoc::DiscArrSerialize(CArchive &ar)
{
if (ar.IsStoring())
{ //storing code
for(int i=0; i<m_nDiscNum; i++)
{
Disc tempDisc;
tempDisc=*(m_pDisc+i);
ar<<tempDisc.m_DiscColor
<<tempDisc.m_nDiscCurrentLayer
<<tempDisc.m_nDiscCurrentTower
<<tempDisc.m_nDiscSerialNum
<<tempDisc.m_pointCenterBottom
<<tempDisc.m_sizeDisc;
TRACE("saving DiscNum is:%d\n", tempDisc.m_nDiscSerialNum);
}
}
else
{ //loading code
//删除原disc数组
delete[] m_pDisc;
m_pDisc=new Disc[m_nDiscNum];
for(int i=0; i<m_nDiscNum; i++)
{
Disc *tempDisc;
tempDisc=new Disc;
ar>>(m_pDisc+i)->m_DiscColor
>>(m_pDisc+i)->m_nDiscCurrentLayer
>>(m_pDisc+i)->m_nDiscCurrentTower
>>(m_pDisc+i)->m_nDiscSerialNum
>>(m_pDisc+i)->m_pointCenterBottom
>>(m_pDisc+i)->m_sizeDisc;
TRACE("loading DiscNum is:%d\n", (m_pDisc+i)->m_nDiscSerialNum);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -