⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hanoiview.cpp

📁 1.有三根杆子A,B,C。A杆上有若干碟子 2.每次移动一块碟子,小的只能叠在大的上面 3.把所有碟子从A杆全部移到C杆上 经过研究发现
💻 CPP
字号:
// HanoiView.cpp : implementation of the CHanoiView class
//

#include "stdafx.h"
#include "Hanoi.h"

#include "HanoiDoc.h"
#include "HanoiView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CHanoiView

IMPLEMENT_DYNCREATE(CHanoiView, CView)

BEGIN_MESSAGE_MAP(CHanoiView, CView)
	//{{AFX_MSG_MAP(CHanoiView)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHanoiView construction/destruction

CHanoiView::CHanoiView()
{
	// TODO: add construction code here

}

CHanoiView::~CHanoiView()
{
}

BOOL CHanoiView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CHanoiView drawing

void CHanoiView::OnDraw(CDC* pDC)
{
	CHanoiDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
    //画Rect
	int i=0;
	CBrush Brush(RGB(255,0,0));
	while(i<CHESSNUM)
	{
		pDC->FillRect(&node[i].Rect,&Brush);
        i++;
	}

	//画中轴线和底线
	//pDC->SelectObject(&Brush);
	//pDC->SelectStockObject(NULL_PEN);
	//pDC->Ellipse(10,10,60,60);
	pDC->MoveTo(MIDDLELINEA,100);
	pDC->LineTo(MIDDLELINEA,400);
    pDC->MoveTo(MIDDLELINEB,100);
	pDC->LineTo(MIDDLELINEB,400);
	pDC->MoveTo(MIDDLELINEC,100);
	pDC->LineTo(MIDDLELINEC,400);
	pDC->MoveTo(0,400);
	pDC->LineTo(700,400);
	pDC->TextOut(MIDDLELINEA-10,410,"A盘");
	pDC->TextOut(MIDDLELINEB-10,410,"B盘");
	pDC->TextOut(MIDDLELINEC-10,410,"C盘");

	CFont NewFont;
	NewFont.CreateFont(20,20,0,0,FW_DONTCARE,TRUE,FALSE,FALSE,DEFAULT_CHARSET,
		OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS
		,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");

	pDC->SelectObject(&NewFont);
	pDC->TextOut(MIDDLELINEB-100,50,"汉诺塔游戏");
}

/////////////////////////////////////////////////////////////////////////////
// CHanoiView printing

BOOL CHanoiView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CHanoiView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CHanoiView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CHanoiView diagnostics

#ifdef _DEBUG
void CHanoiView::AssertValid() const
{
	CView::AssertValid();
}

void CHanoiView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CHanoiDoc* CHanoiView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHanoiDoc)));
	return (CHanoiDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CHanoiView message handlers

void CHanoiView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();
	
	// TODO: Add your specialized code here and/or call the base class
	//初始化变量
    float length=(100.0-20.0)/CHESSNUM;
	float width=200;
	float height=400;
	int i=0;
    SelectChess=-1;

	while(i<CHESSNUM)
	{
		node[i].Rect.left=MIDDLELINEA-width/2;
		node[i].Rect.right=MIDDLELINEA+width/2;
		node[i].Rect.top=height-20+2;
		node[i].Rect.bottom=height;
		node[i].Holder=1;
		width=width-length*2;
		height=height-20;
		i++;      
	}
	
}

void CHanoiView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int i=0;
	CBrush BrushBlue(RGB(0,0,255)),BrushRed(RGB(255,0,0)),BrushWhite(RGB(255,255,255));
	HCURSOR pt;
	CClientDC pDC(this);
 
	pDC.TextOut(MIDDLELINEA-10,410,"A盘");
	pDC.TextOut(MIDDLELINEB-10,410,"B盘");
	pDC.TextOut(MIDDLELINEC-10,410,"C盘");
	CFont NewFont;
	NewFont.CreateFont(20,20,0,0,FW_DONTCARE,TRUE,FALSE,FALSE,DEFAULT_CHARSET,
		OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS
		,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Times New Roman");

	pDC.SelectObject(&NewFont);
	pDC.TextOut(MIDDLELINEB-100,50,"*汉诺塔游戏*");
	
	//当mousr经过Rect时
	while(i<CHESSNUM)
	{
		if(node[i].Rect.PtInRect(point))
		{
            pDC.FillRect(&node[i].Rect,&BrushBlue);
		}
		else
		{
			//pt=AfxGetApp()->LoadCursor(IDC_CURSOR2);
			//::SetCursor(pt);
			pDC.FillRect(&node[i].Rect,&BrushRed);
		}
		i++;
	}

	//移动选中的盘子
	if(SelectOrNot==1&&PutOrNot==0)
	{
		//擦盘
		pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);
        //node[SelectChess].Holder=-1;
		//重画
		int width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;
        node[SelectChess].Rect.left=point.x-PointInRectWidth;
		node[SelectChess].Rect.right=node[SelectChess].Rect.left+width;
		node[SelectChess].Rect.top=point.y-PointInRectHeight;
		node[SelectChess].Rect.bottom=node[SelectChess].Rect.top+14;
		pDC.FillRect(&node[SelectChess].Rect,&BrushRed);
	}

    //判断选中的rect是否进入中轴线
	CPen Pen,PenB;
	Pen.CreatePen(PS_SOLID,1,RGB(0,0,255));PenB.CreatePen(PS_SOLID,1,RGB(0,0,0));
	if(SelectChess!=-1){
		pDC.SelectObject(&Pen);
		if(node[SelectChess].Rect.left<=MIDDLELINEA&&node[SelectChess].Rect.right>=MIDDLELINEA)
		{
			ComeLine=1;
            pDC.MoveTo(MIDDLELINEA,100);
	        pDC.LineTo(MIDDLELINEA,400);
		}
	    else if(node[SelectChess].Rect.left<=MIDDLELINEB&&node[SelectChess].Rect.right>=MIDDLELINEB)
		{
			ComeLine=2;
            pDC.MoveTo(MIDDLELINEB,100);
        	pDC.LineTo(MIDDLELINEB,400);
		}
	    else if(node[SelectChess].Rect.left<=MIDDLELINEC&&node[SelectChess].Rect.right>=MIDDLELINEC)
		{
			ComeLine=3;
        	pDC.MoveTo(MIDDLELINEC,100);
	        pDC.LineTo(MIDDLELINEC,400);
		}
		else
		{
			pDC.SelectObject(&PenB);
			ComeLine=-1;
			pDC.MoveTo(MIDDLELINEA,100);
			pDC.LineTo(MIDDLELINEA,400);
  		    pDC.MoveTo(MIDDLELINEB,100);
			pDC.LineTo(MIDDLELINEB,400);
			pDC.MoveTo(MIDDLELINEC,100);
			pDC.LineTo(MIDDLELINEC,400);
		}
		pDC.SelectObject(&PenB);

	}

	pDC.MoveTo(0,400);
	pDC.LineTo(700,400);

	CView::OnMouseMove(nFlags, point);
}

void CHanoiView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	SendMessage(WM_CLOSE,0,0);
	int i=0;
	float length=(100.0-20.0)/CHESSNUM;
	CClientDC pDC(this);
	CBrush BrushBlue(RGB(0,0,255)),BrushRed(RGB(255,0,0)),BrushWhite(RGB(255,255,255));
    HCURSOR pt=AfxGetApp()->LoadCursor(IDC_CURSOR1);
	::SetCursor(pt);

	SetCapture();//当mouse移出window时仍捕捉mouse坐标

	//标记选中盘子
	while(i<CHESSNUM)
	{
		if(node[i].Rect.PtInRect(point))
		{
			SelectChess=i;
			break;
		}
		i++;
	}

	//判断是否为顶端盘子
	i=0;
	while(i<CHESSNUM&&SelectChess!=-1)
	{
		if(node[i].Holder==node[SelectChess].Holder){
			if(i!=SelectChess&&(node[i].Rect.right-node[i].Rect.left)<(node[SelectChess].Rect.right-node[SelectChess].Rect.left))break;
			else i++;
		}
		else i++;
	}
	if(i>=CHESSNUM)//是顶端盘子
	{
		SelectOrNot=1;
		PutOrNot=0;
        FormerRect=node[SelectChess].Rect;
	}

	
	//加亮选中盘子
	//erase the rect;
	if(SelectChess!=-1){
	pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);
	//change the rect's paramiter
	node[SelectChess].Rect.left+=2;
    node[SelectChess].Rect.right-=2;
    node[SelectChess].Rect.top+=2;
    node[SelectChess].Rect.bottom-=2;
    pDC.FillRect(&node[SelectChess].Rect,&BrushRed);
    //计算mouse在rect内的位置
    PointInRectWidth=point.x-node[SelectChess].Rect.left;
	PointInRectHeight=point.y-node[SelectChess].Rect.top;
	}

	//画中轴线和底线
	pDC.MoveTo(MIDDLELINEA,100);
	pDC.LineTo(MIDDLELINEA,400);
  	pDC.MoveTo(MIDDLELINEB,100);
	pDC.LineTo(MIDDLELINEB,400);
	pDC.MoveTo(MIDDLELINEC,100);
	pDC.LineTo(MIDDLELINEC,400);

	CView::OnLButtonDown(nFlags, point);
}

void CHanoiView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CClientDC pDC(this);
	CBrush BrushBlue(RGB(0,0,255)),BrushRed(RGB(255,0,0)),BrushWhite(RGB(255,255,255));
    int i=0,min,j,HaveChess=0,width;
    float length=(100.0-20.0)/CHESSNUM;

    ReleaseCapture();//当mouse移到window外,且mouse已按下,则不捕捉mouse

	HCURSOR pt=AfxGetApp()->LoadCursor(IDC_CURSOR2);
	::SetCursor(pt);

	if(SelectChess!=-1)
	{
		node[SelectChess].Rect.left-=2;
		node[SelectChess].Rect.right+=2;
		node[SelectChess].Rect.bottom+=2;
		node[SelectChess].Rect.top-=2;
        pDC.FillRect(&node[SelectChess].Rect,&BrushRed);
	}

	if(SelectOrNot)
	{
		switch(ComeLine)
		{
		case 1: pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);//擦盘
		    //找出当前堆的最小盘j
			i=0;min=1000;
	        while(i<CHESSNUM)
			{
				if(node[i].Holder==1)
				{   
					HaveChess=1;
					if(node[i].Rect.right-node[i].Rect.left<min)
					{min=node[i].Rect.right-node[i].Rect.left;
				    j=i;
					}	   
				}
				i++;
			}
            //放入盘子
			if(HaveChess==1)
            {
				//放的下
				if(node[SelectChess].Rect.right-node[SelectChess].Rect.left-(node[j].Rect.right-node[j].Rect.left)<0)
				{
					node[SelectChess].Rect.bottom=node[j].Rect.top-2;
					node[SelectChess].Rect.top=node[j].Rect.top-20;
					width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;			 
					node[SelectChess].Rect.left=MIDDLELINEA-width/2; 
					node[SelectChess].Rect.right=MIDDLELINEA+width/2;
					node[SelectChess].Holder=1;	
					PutOrNot=1;
				}
				else//放不下
				{
					node[SelectChess].Rect=FormerRect;//返回
				}
			}
			else
			{
				node[SelectChess].Rect.bottom=400;
				node[SelectChess].Rect.top=400-20+2;
			    width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;
				node[SelectChess].Rect.left=MIDDLELINEA-width/2;
                node[SelectChess].Rect.right=MIDDLELINEA+width/2;
			    node[SelectChess].Holder=1;
				PutOrNot=1;
			}
			break;
		case 2: pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);//擦盘
		    //找出当前堆的最小盘j
			i=0;min=1000;
	        while(i<CHESSNUM)
			{
				if(node[i].Holder==2)
				{   
					HaveChess=1;
					if(node[i].Rect.right-node[i].Rect.left<min)
					{min=node[i].Rect.right-node[i].Rect.left;
				    j=i;
					}	   
				}
				i++;
			}
            //放入盘子
			if(HaveChess==1)
            {
				//放的下
				if(node[SelectChess].Rect.right-node[SelectChess].Rect.left-(node[j].Rect.right-node[j].Rect.left)<0)
				{
					node[SelectChess].Rect.bottom=node[j].Rect.top-2;
					node[SelectChess].Rect.top=node[j].Rect.top-20;
					width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;			 
					node[SelectChess].Rect.left=MIDDLELINEB-width/2; 
					node[SelectChess].Rect.right=MIDDLELINEB+width/2;
					node[SelectChess].Holder=2;
					PutOrNot=1;
				}
				else//放不下
				{
					node[SelectChess].Rect=FormerRect;//返回
				}
			}
			else
			{
				node[SelectChess].Rect.bottom=400;
				node[SelectChess].Rect.top=400-20+2;
			    width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;
				node[SelectChess].Rect.left=MIDDLELINEB-width/2;
                node[SelectChess].Rect.right=MIDDLELINEB+width/2;
			    node[SelectChess].Holder=2;
				PutOrNot=1;
			}
			break;
		case 3: pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);//擦盘
		    //找出当前堆的最小盘j
			i=0;min=1000;
	        while(i<CHESSNUM)
			{
				if(node[i].Holder==3)
				{   
					HaveChess=1;
					if(node[i].Rect.right-node[i].Rect.left<min)
					{min=node[i].Rect.right-node[i].Rect.left;
				    j=i;
					}	   
				}
				i++;
			}
            //放入盘子
			if(HaveChess==1)
            {
				//放的下
				if(node[SelectChess].Rect.right-node[SelectChess].Rect.left-(node[j].Rect.right-node[j].Rect.left)<0)
				{
					node[SelectChess].Rect.bottom=node[j].Rect.top-2;
					node[SelectChess].Rect.top=node[j].Rect.top-20;
					width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;			 
					node[SelectChess].Rect.left=MIDDLELINEC-width/2; 
					node[SelectChess].Rect.right=MIDDLELINEC+width/2;
					node[SelectChess].Holder=3;
					PutOrNot=1;
				}
				else//放不下
				{
					node[SelectChess].Rect=FormerRect;//返回
				}
			}
			else
			{
				node[SelectChess].Rect.bottom=400;
				node[SelectChess].Rect.top=400-20+2;
			    width=node[SelectChess].Rect.right-node[SelectChess].Rect.left;
				node[SelectChess].Rect.left=MIDDLELINEC-width/2;
                node[SelectChess].Rect.right=MIDDLELINEC+width/2;
			    node[SelectChess].Holder=3;
				PutOrNot=1;
			}
			break;
		case -1:pDC.FillRect(&node[SelectChess].Rect,&BrushWhite);//擦盘
			node[SelectChess].Rect=FormerRect;//返回			
			break;
		}
		pDC.FillRect(&node[SelectChess].Rect,&BrushRed);//刷新
	}
	SelectOrNot=0;
	SelectChess=-1;

	pDC.MoveTo(MIDDLELINEA,100);
	pDC.LineTo(MIDDLELINEA,400);
  	pDC.MoveTo(MIDDLELINEB,100);
	pDC.LineTo(MIDDLELINEB,400);
	pDC.MoveTo(MIDDLELINEC,100);
	pDC.LineTo(MIDDLELINEC,400);


	CView::OnLButtonUp(nFlags, point);
}

void CHanoiView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
    node[SelectChess].Rect.left+=2;
	node[SelectChess].Rect.right-=2;
	node[SelectChess].Rect.bottom-=2;
	node[SelectChess].Rect.top+=2;
	CView::OnLButtonDblClk(nFlags, point);
}

void CHanoiView::OnAppChessnum() 
{
	// TODO: Add your command handler code here
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -