📄
字号:
// 汉诺塔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 + -