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

📄

📁 VC汉诺塔游戏-能很好的演示过程
💻
字号:
// 汉诺塔View.cpp : implementation of the CMyView class
//

#include "stdafx.h"
#include "汉诺塔.h"

#include "汉诺塔Doc.h"
#include "汉诺塔View.h"
#include "MainFrm.h"
#include "SetGame.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMyView

IMPLEMENT_DYNCREATE(CMyView, CView)

BEGIN_MESSAGE_MAP(CMyView, CView)
	//{{AFX_MSG_MAP(CMyView)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_RESETGAME, OnResetgame)
	ON_WM_TIMER()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_COMMAND(ID_SETGAME, OnSetgame)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyView construction/destruction

CMyView::CMyView()
{
	// TODO: add construction code here
    dx=10;
	dy=15;
	m_height=240;

    m_maxstick=8;//默认最大棍子为8根,最大为15根
	m_bkcolor=RGB(255,255,255);
	InitGameData();
	m_cursor=AfxGetApp()->LoadStandardCursor(IDC_ARROW);
}

CMyView::~CMyView()
{
}

BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
    cs.lpszClass=AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW,
                 AfxGetApp()->LoadStandardCursor(IDC_ARROW), 
                 (HBRUSH)GetStockObject(GRAY_BRUSH),
                 AfxGetApp()->LoadIcon(IDR_MAINFRAME));

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMyView drawing

void CMyView::InitGameData()
{
	m_left=0;//左边最上层棍子为最短的
	m_center=-1;//左边最上层棍子没有
	m_right=-1;//左边最上层棍子没有

	//初始化各棍子位置
	for(int i=0;i<m_maxstick;i++)
	{
		m_stick[i].value=i+1;
		m_stick[i].pos=-1;
		m_stick[i].next=i+1;
	}
	m_stick[m_maxstick-1].next=-1;

	m_lflag=m_cflag=m_rflag=FALSE;
	m_times=0;
}

void CMyView::DrawStick(HDC hdc,int index,int *height)
{
	if(index==-1) return;

	if(m_stick[index].next!=-1)
	{
		DrawStick(hdc,m_stick[index].next,height);

		int x=16*dx*(m_stick[index].pos+1)+dx;
        x+=(15*dx-m_stick[index].value*dx)/2;
		COLORREF color=0;
	
		if((m_lflag && m_stick[index].pos==-1)
		 ||(m_cflag && m_stick[index].pos==0)
		 ||(m_rflag && m_stick[index].pos==1)
		 )
		color=RGB(0,0,255);
		else
		color=0x200000*(index%8+1)+0x4000*(index/4+2)+0x40*(index%4+1);

		HBRUSH brush=::CreateSolidBrush(color);
		::SelectObject(hdc,brush);
		::Rectangle(hdc,x,*height,x+m_stick[index].value*dx,*height+dy);
		::DeleteObject(brush);
	}
	else
	{
		int x=16*dx*(m_stick[index].pos+1)+dx;
		x+=(15*dx-m_stick[index].value*dx)/2;
		COLORREF color=0;
		
		if((m_lflag && m_stick[index].pos==-1)
		 ||(m_cflag && m_stick[index].pos==0)
		 ||(m_rflag && m_stick[index].pos==1)
		 )
		color=RGB(0,0,255);
		else
		color=0x200000*(index%8)+0x4000*(index/4+2)+0x40*(index%4+1);

		HBRUSH brush=::CreateSolidBrush(color);
		::SelectObject(hdc,brush);
		::Rectangle(hdc,x,*height,x+m_stick[index].value*dx,*height+dy);
		::DeleteObject(brush);
	}
		
	*height-=dy;
}
BOOL CMyView::GameSuccess()
{
	for(int i=0;i<m_maxstick;i++)
		if(m_stick[i].pos!=1) return FALSE;

	return TRUE;
}

void CMyView::OnDraw(CDC* pDC)
{
	CMyDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	int height=m_height;

	CBrush brush;
	brush.CreateSolidBrush(m_bkcolor);
	pDC->SelectObject(&brush);
	pDC->Rectangle(5,height-15*dy-5,45*dx+2*dx+15,height+dy*5/2);
	brush.DeleteObject();

    DrawStick(pDC->m_hDC,m_left,&height);
    height=m_height;
    DrawStick(pDC->m_hDC,m_center,&height);
	height=m_height;
    DrawStick(pDC->m_hDC,m_right,&height);

    brush.CreateSolidBrush(RGB(0,255,0));
	pDC->SelectObject(&brush);
	pDC->Rectangle(dx,m_height+dy*3/2,16*dx,m_height+dy*2);
	pDC->Rectangle(17*dx,m_height+dy*3/2,32*dx,m_height+dy*2);
	pDC->Rectangle(33*dx,m_height+dy*3/2,48*dx,m_height+dy*2);
	brush.DeleteObject();
}

void CMyView::SwapStick(int i,int j)//i->j
{
	if(i==j) return;
	if(i>1 || i<-1 || j>1 || j<-1) return;

	if(i==-1 && j==0)//左到中
	{
		if(m_left!=-1)
		{
			if(m_stick[m_center].value>m_stick[m_left].value || m_center==-1)
			{
				int temp=m_left;
				m_left=m_stick[temp].next;
				m_stick[temp].next=m_center;
				m_center=temp;
				m_stick[temp].pos=j;
			}
		}
	}
	else
	if(i==0 && j==-1)//中到左
	{
		if(m_center!=-1)
		{
			if(m_stick[m_left].value>m_stick[m_center].value || m_left==-1)
			{
				int temp=m_center;
				m_center=m_stick[temp].next;
				m_stick[temp].next=m_left;
				m_left=temp;
				m_stick[temp].pos=j;
			}
		}
	}
	else
	if(i==-1 && j==1)//左到右
	{
        if(m_left!=-1)
		{
			if(m_stick[m_right].value>m_stick[m_left].value || m_right==-1)
			{
				int temp=m_left;
				m_left=m_stick[temp].next;
				m_stick[temp].next=m_right;
				m_right=temp;
				m_stick[temp].pos=j;
			}
		}
	}
	else
	if(i==1 && j==-1)//右到左
	{
		if(m_right!=-1)
		{
			if(m_stick[m_left].value>m_stick[m_right].value || m_left==-1)
			{
				int temp=m_right;
				m_right=m_stick[temp].next;
				m_stick[temp].next=m_left;
				m_left=temp;
				m_stick[temp].pos=j;
			}
		}
	}
	else
	if(i==0 && j==1)//中到右
	{
		if(m_center!=-1)
		{
			if(m_stick[m_right].value>m_stick[m_center].value || m_right==-1)
			{
				int temp=m_center;
				m_center=m_stick[temp].next;
				m_stick[temp].next=m_right;
				m_right=temp;
				m_stick[temp].pos=j;
			}
		}
	}
	else
	if(i==1 && j==0)//右到中
	{
		if(m_right!=-1)
		{
			if(m_stick[m_center].value>m_stick[m_right].value || m_center==-1)
			{
				int temp=m_right;
				m_right=m_stick[temp].next;
				m_stick[temp].next=m_center;
				m_center=temp;
				m_stick[temp].pos=j;
			}
		}
	}

	Invalidate(FALSE);

	if(GameSuccess())
	{
		CString inf;
		if(m_times<3600)
		inf.Format("游戏成功,您真棒,所有时间:%d分%d秒.",m_times/60,m_times%60);
		else
		inf.Format("游戏成功,您真棒,所有时间:%d时%d分%d秒.",m_times/3600,(m_times/60)%60,m_times%60);
		MessageBox(inf);
        InitGameData();
		Invalidate(FALSE);
	}
}
/////////////////////////////////////////////////////////////////////////////
// CMyView diagnostics

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

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

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

void CMyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int x1=dx+(15-m_maxstick)*dx/2;
	int x2=x1+m_maxstick*dx;

	int x3=17*dx+(15-m_maxstick)*dx/2;
	int x4=x3+m_maxstick*dx;

	int x5=33*dx+(15-m_maxstick)*dx/2;
	int x6=x5+m_maxstick*dx;

	//int y1=m_height-m_maxstick*dy+dy;
	//int y2=m_height+dy;

	if(point.x>x1 && point.x<x2)// && point.y>y1 && point.y<y2)
	{
		if(m_cflag==FALSE && m_rflag==FALSE)
		{
			m_lflag^=TRUE;
			Invalidate(FALSE);
		}
		else
		if(m_cflag)
		{
            SwapStick(0,-1);
			m_cflag=FALSE;
			Invalidate(FALSE);
		}
		else
		if(m_rflag)
		{
			SwapStick(1,-1);
			m_rflag=FALSE;
			Invalidate(FALSE);
		}
	}

	if(point.x>x3 && point.x<x4)// && point.y>y1 && point.y<y2)
	{
		if(m_lflag==FALSE && m_rflag==FALSE)
		{
			m_cflag^=TRUE;
			Invalidate(FALSE);
		}
		else
		if(m_lflag)
		{
			SwapStick(-1,0);
			m_lflag=FALSE;
			Invalidate(FALSE);
		}
		else
		if(m_rflag)
		{
			SwapStick(1,0);
			m_rflag=FALSE;
			Invalidate(FALSE);
		}
	}

	if(point.x>x5 && point.x<x6)// && point.y>y1 && point.y<y2)
	{
		if(m_lflag==FALSE && m_cflag==FALSE)
		{
			m_rflag^=TRUE;
			Invalidate(FALSE);
		}
		else
		if(m_lflag)
		{
			SwapStick(-1,1);
			m_lflag=FALSE;
			Invalidate(FALSE);
		}
		else
		if(m_cflag)
		{
			SwapStick(0,1);
			m_cflag=FALSE;
			Invalidate(FALSE);
		}
	}

	CView::OnLButtonDown(nFlags, point);
}

void CMyView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int x1=dx+(15-m_maxstick)*dx/2;
	int x2=x1+m_maxstick*dx;

	int x3=17*dx+(15-m_maxstick)*dx/2;
	int x4=x3+m_maxstick*dx;

	int x5=33*dx+(15-m_maxstick)*dx/2;
	int x6=x5+m_maxstick*dx;

	//int y1=m_height-m_maxstick*dy+dy;
	//int y2=m_height+dy;


    if( //(point.y>y1 && point.y<y2)
		//&&
		 ((point.x>x1 && point.x<x2)
		 ||(point.x>x3 && point.x<x4)
		 ||(point.x>x5 && point.x<x6)
		 )
	  )
	{
		 m_cursor=AfxGetApp()->LoadCursor(IDC_SWAP);
		 if(m_cursor!=NULL)
		 ::SetCursor(m_cursor);
	}
	else
	{
		m_cursor=AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		::SetCursor(m_cursor);
	}

	CView::OnMouseMove(nFlags, point);
}

BOOL CMyView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	// TODO: Add your message handler code here and/or call default
    ::SetCursor(m_cursor);

	return TRUE;//CView::OnSetCursor(pWnd, nHitTest, message);
}

void CMyView::OnResetgame() 
{
	// TODO: Add your command handler code here
	InitGameData();
	Invalidate(FALSE);
}

void CMyView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	m_times++;
	if(m_times>=0xffffff) m_times=0;
    CString t;
	if(m_times<3600)
	t.Format(" 所有时间: %d分%d秒 ",m_times/60,m_times%60);
	else
	t.Format(" 所有时间: %d时%d分%d秒 ",m_times/3600,(m_times/60)%60,m_times%60);
	static CMainFrame *frm=(CMainFrame*)(AfxGetApp()->m_pMainWnd);
    frm->m_wndStatusBar.SetPaneText(0,t);

	CView::OnTimer(nIDEvent);
}

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	SetTimer(WM_USER+100,1000,NULL);

	return 0;
}

void CMyView::OnDestroy() 
{
	CView::OnDestroy();
	
	// TODO: Add your message handler code here
	KillTimer(WM_USER+100);
}

void CMyView::OnSetgame() 
{
	// TODO: Add your command handler code here
	CSetGame set;

	set.m_bkcolor=m_bkcolor;
	set.m_sticks=m_maxstick;

	if(set.DoModal()==IDOK)
	{
		m_bkcolor=set.m_bkcolor;
		m_maxstick=set.m_sticks;
		InitGameData();
		Invalidate();
	}
}

⌨️ 快捷键说明

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