头文件: GameSet.h Lose.h NumSkipDoc.h NumSkipView.h SkipOut.h Win.h 源文件: GameSet.cpp Lose.cpp NumSkipDoc.cpp NumSkipView.cpp SkipOut.cpp Win.cpp 代码: GameSet.h #pragma once // GameSet 对话框 class GameSet : public CDialog { DECLARE_DYNAMIC(GameSet) public: GameSet(CWnd* pParent = NULL); // 标准构造函数 virtual ~GameSet(); // 对话框数据 enum { IDD = IDD_GAMESET }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedLeveal1(); //声明各单选按钮消息函数 afx_msg void OnBnClickedLeveal2(); afx_msg void OnBnClickedLeveal3(); afx_msg void OnBnClickedLeveal4(); afx_msg void OnBnClickedLeveal5(); afx_msg void OnBnClickedLeveal6(); afx_msg void OnBnClickedLeveal7(); afx_msg void OnBnClickedModel1(); afx_msg void OnBnClickedModel2(); int m_radio_leveal; int m_radio_modol; afx_msg void OnBnClickedOk(); afx_msg void OnBnClickedCancel(); afx_msg void OnBnClickedShowPath(); afx_msg void OnBnClickedHidePath(); BOOL m_Show; afx_msg void OnBnClickedYellow(); afx_msg void OnBnClickedGreen(); }; //********************** GameSet.cpp // GameSet.cpp : 实现文件 // #include "stdafx.h" #include "NumSkip.h" #include "GameSet.h" #include "afxdialogex.h" // GameSet 对话框 IMPLEMENT_DYNAMIC(GameSet, CDialog) GameSet::GameSet(CWnd* pParent /*=NULL*/) : CDialog(GameSet::IDD, pParent) { m_Show=FALSE; m_radio_leveal = 0; m_radio_modol = 0; } GameSet::~GameSet() { } void GameSet::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); // DDX_Control(pDX, IDC_LEVEAL1, m_radio_leveal); //将成员变量与ID对应 // DDX_Control(pDX, IDC_MODEL1, m_radio_modol); DDX_Radio(pDX, IDC_LEVEAL1, m_radio_leveal); DDV_MinMaxInt(pDX, m_radio_leveal, 0, 6); DDX_Radio(pDX, IDC_MODEL1, m_radio_modol); DDV_MinMaxInt(pDX, m_radio_modol, 0, 1); DDX_Radio(pDX, IDC_SHOW_PATH, m_Show); } BEGIN_MESSAGE_MAP(GameSet, CDialog) //各消息函数与各ID相映射 ON_BN_CLICKED(IDC_LEVEAL1, &GameSet::OnBnClickedLeveal1) ON_BN_CLICKED(IDC_LEVEAL2, &GameSet::OnBnClickedLeveal2) ON_BN_CLICKED(IDC_LEVEAL3, &GameSet::OnBnClickedLeveal3) ON_BN_CLICKED(IDC_LEVEAL4, &GameSet::OnBnClickedLeveal4) ON_BN_CLICKED(IDC_LEVEAL5, &GameSet::OnBnClickedLeveal5) ON_BN_CLICKED(IDC_LEVEAL6, &GameSet::OnBnClickedLeveal6) ON_BN_CLICKED(IDC_LEVEAL7, &GameSet::OnBnClickedLeveal7) ON_BN_CLICKED(IDC_MODEL1, &GameSet::OnBnClickedModel1) ON_BN_CLICKED(IDC_MODEL2, &GameSet::OnBnClickedModel2) ON_BN_CLICKED(IDC_SHOW_PATH, &GameSet::OnBnClickedShowPath) ON_BN_CLICKED(IDC_HIDE_PATH, &GameSet::OnBnClickedHidePath) ON_BN_CLICKED(IDC_YELLOW, &GameSet::OnBnClickedYellow) ON_BN_CLICKED(IDC_GREEN, &GameSet::OnBnClickedGreen) END_MESSAGE_MAP() // GameSet 消息处理程序 void GameSet::OnBnClickedLeveal1() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=0; } void GameSet::OnBnClickedLeveal2() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=1; } void GameSet::OnBnClickedLeveal3() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=2; } void GameSet::OnBnClickedLeveal4() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=3; } void GameSet::OnBnClickedLeveal5() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=4; } void GameSet::OnBnClickedLeveal6() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=5; } void GameSet::OnBnClickedLeveal7() { // TODO: 在此添加控件通知处理程序代码 m_radio_leveal=6; } void GameSet::OnBnClickedModel1() { // TODO: 在此添加控件通知处理程序代码 m_radio_modol=0; } void GameSet::OnBnClickedModel2() { // TODO: 在此添加控件通知处理程序代码 m_radio_modol=1; } void GameSet::OnBnClickedShowPath() { // TODO: 在此添加控件通知处理程序代码 } void GameSet::OnBnClickedHidePath() { // TODO: 在此添加控件通知处理程序代码 } void GameSet::OnBnClickedYellow() { // TODO: 在此添加控件通知处理程序代码 } void GameSet::OnBnClickedGreen() { // TODO: 在此添加控件通知处理程序代码 } //******************* Lose.h #pragma once // Lose 对话框 class Lose : public CDialog { DECLARE_DYNAMIC(Lose) public: Lose(CWnd* pParent = NULL); // 标准构造函数 virtual ~Lose(); // 对话框数据 enum { IDD = IDD_LOSE }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedAgain(); afx_msg void OnBnClickedBack1(); }; //******************* Lose.cpp // Lose.cpp : 实现文件 // #include "stdafx.h" #include "NumSkip.h" #include "Lose.h" #include "afxdialogex.h" // Lose 对话框 IMPLEMENT_DYNAMIC(Lose, CDialog) Lose::Lose(CWnd* pParent /*=NULL*/) : CDialog(Lose::IDD, pParent) { } Lose::~Lose() { } void Lose::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(Lose, CDialog) ON_BN_CLICKED(IDC_AGAIN, &Lose::OnBnClickedAgain) ON_BN_CLICKED(IDC_BACK1, &Lose::OnBnClickedBack1) END_MESSAGE_MAP() // Lose 消息处理程序 void Lose::OnBnClickedAgain() { // TODO: 在此添加控件通知处理程序代码 EndDialog(IDC_AGAIN); } void Lose::OnBnClickedBack1() { // TODO: 在此添加控件通知处理程序代码 EndDialog(IDC_BACK1); } //***************** NumSkipDoc.h // NumSkipDoc.h : CNumSkipDoc 类的接口 // #pragma once #include"GameSet.h" #include"SkipOut.h" #include"Win.h" #include"Lose.h" class CNumSkipDoc : public CDocument { protected: // 仅从序列化创建 CNumSkipDoc(); DECLARE_DYNCREATE(CNumSkipDoc) // 特性 public: // 操作 public: int xx; //屏幕宽度 int yy; //屏幕高度 int segment; //每个方格的长度 int OverTag; //结束标志 int order; int CurrentPositionX; //当前位置的横坐标 int CurrentPositionY;//当前位置的纵坐标 int PrePositionX; //上一位置的横坐标 int PrePositionY; //上一位置的纵坐标 int Path_Long; //规定矩阵路径长度 GameSet GS; //定义对菜单话框 Win W; //定义赢对话框 Lose L; //定义输对话框 SkipOut So; //矩阵对象 // 重写 public: virtual BOOL OnNewDocument(); virtual void Serialize(CArchive& ar); #ifdef SHARED_HANDLERS virtual void InitializeSearchContent(); virtual void OnDrawThumbnail(CDC& dc, LPRECT lprcBounds); #endif // SHARED_HANDLERS // 实现 public: virtual ~CNumSkipDoc(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // 生成的消息映射函数 protected: DECLARE_MESSAGE_MAP() #ifdef SHARED_HANDLERS // 用于为搜索处理程序设置搜索内容的 Helper 函数 void SetSearchContent(const CString& value); #endif // SHARED_HANDLERS public: virtual void SetTitle(LPCTSTR lpszTitle); }; //****************** NumSkipDoc.cpp // NumSkipDoc.cpp : CNumSkipDoc 类的实现 // #include "stdafx.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "NumSkip.h" #endif #include"GameSet.h" #include "NumSkipDoc.h" #include"SkipOut.h" #include <propkey.h> #ifdef _DEBUG #define new DEBUG_NEW #endif // CNumSkipDoc IMPLEMENT_DYNCREATE(CNumSkipDoc, CDocument) BEGIN_MESSAGE_MAP(CNumSkipDoc, CDocument) END_MESSAGE_MAP() // CNumSkipDoc 构造/析构 CNumSkipDoc::CNumSkipDoc() { // TODO: 在此添加一次性构造代码 order=7; OverTag=0; //未结束 xx=GetSystemMetrics(SM_CXSCREEN); yy=GetSystemMetrics(SM_CYSCREEN); Path_Long=order-3; //矩阵的路径长度 So.row=order-2; //矩阵的行数 So.column=order-2; //矩阵的列数 while(1) //随机选出矩阵中数字不超过9的矩阵 { So.Input(Path_Long); for(int i=0;i!=order-2;i++) { for(int j=0;j!=order-2;j++) { if(So.matrix[i][j]->elem>9) { continue; } } } if(GS.m_radio_modol==1) //单路径模式 { int ShortPath; //矩阵中最短的路径 int CenterX; //矩阵起点横坐标 int CenterY; //矩阵起点纵坐标 CenterX=So.row/2; CenterY=So.column/2; So.Check(CenterX,CenterY,ShortPath); So.SinglePath(Path_Long); // } break; } CurrentPositionX=order/2;//起点位置,刚开始为中心 CurrentPositionY=order/2; PrePositionX=0; //上一位置横坐标,刚开始为0 PrePositionY=0; //上一位置纵坐标 segment=(yy-95)/order; } CNumSkipDoc::~CNumSkipDoc() { } BOOL CNumSkipDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: 在此添加重新初始化代码 // (SDI 文档将重用该文档) return TRUE; } // CNumSkipDoc 序列化 void CNumSkipDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: 在此添加存储代码 } else { // TODO: 在此添加加载代码 } } #ifdef SHARED_HANDLERS // 缩略图的支持 void CNumSkipDoc::OnDrawThumbnail(CDC& dc, LPRECT lprcBounds) { // 修改此代码以绘制文档数据 dc.FillSolidRect(lprcBounds, RGB(255, 255, 255)); CString strText = _T("TODO: implement thumbnail drawing here"); LOGFONT lf; CFont* pDefaultGUIFont = CFont::FromHandle((HFONT) GetStockObject(DEFAULT_GUI_FONT)); pDefaultGUIFont->GetLogFont(&lf); lf.lfHeight = 36; CFont fontDraw; fontDraw.CreateFontIndirect(&lf); CFont* pOldFont = dc.SelectObject(&fontDraw); dc.DrawText(strText, lprcBounds, DT_CENTER | DT_WORDBREAK); dc.SelectObject(pOldFont); } // 搜索处理程序的支持 void CNumSkipDoc::InitializeSearchContent() { CString strSearchContent; // 从文档数据设置搜索内容。 // 内容部分应由“;”分隔 // 例如: strSearchContent = _T("point;rectangle;circle;ole object;"); SetSearchContent(strSearchContent); } void CNumSkipDoc::SetSearchContent(const CString& value) { if (value.IsEmpty()) { RemoveChunk(PKEY_Search_Contents.fmtid, PKEY_Search_Contents.pid); } else { CMFCFilterChunkValueImpl *pChunk = NULL; ATLTRY(pChunk = new CMFCFilterChunkValueImpl); if (pChunk != NULL) { pChunk->SetTextValue(PKEY_Search_Contents, value, CHUNK_TEXT); SetChunkValue(pChunk); } } } #endif // SHARED_HANDLERS // CNumSkipDoc 诊断 #ifdef _DEBUG void CNumSkipDoc::AssertValid() const { CDocument::AssertValid(); } void CNumSkipDoc::Dump(CDumpContext& dc) const { CDocument::Dump(dc); } #endif //_DEBUG // CNumSkipDoc 命令 void CNumSkipDoc::SetTitle(LPCTSTR lpszTitle) { // TODO: 在此添加专用代码和/或调用基类 CDocument::SetTitle(_T("跳格子")); } //*********************** NumSkipView.h // NumSkipView.h : CNumSkipView 类的接口 // #pragma once #include"vector" typedef struct Position{ int x; //位置横坐标 int y; //位置纵坐标 int elem; //位置元素 }; class CNumSkipView : public CView { protected: // 仅从序列化创建 CNumSkipView(); DECLARE_DYNCREATE(CNumSkipView) // 特性 public: CNumSkipDoc* GetDocument() const; // 操作 public: int Green; //绿色 int White; //白色 int Yellow; //黄色 int Red; //红色 int Black; //黑色 int NowColor; //当前点的颜色 int BackroundColor; //背景颜色 vector<Position> p; vector<node2> pp; //标记 // 重写 public: virtual void OnDraw(CDC* pDC); // 重写以绘制该视图 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); protected: virtual BOOL OnPreparePrinting(CPrintInfo* pInfo); virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo); virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo); // 实现 public: virtual ~CNumSkipView(); #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif protected: // 生成的消息映射函数 protected: afx_msg void OnFilePrintPreview(); afx_msg void OnRButtonUp(UINT nFlags, CPoint point); afx_msg void OnContextMenu(CWnd* pWnd, CPoint point); DECLARE_MESSAGE_MAP() public: afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnNewGame(); afx_msg void OnChoose(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnExit(); afx_msg void OnBack(); afx_msg void OnRepeat(); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); }; #ifndef _DEBUG // NumSkipView.cpp 中的调试版本 inline CNumSkipDoc* CNumSkipView::GetDocument() const { return reinterpret_cast<CNumSkipDoc*>(m_pDocument); } #endif //******************** NumSkipView.cpp // NumSkipView.cpp : CNumSkipView 类的实现 // #include "stdafx.h" // SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的 // ATL 项目中进行定义,并允许与该项目共享文档代码。 #ifndef SHARED_HANDLERS #include "NumSkip.h" #endif #include "NumSkipDoc.h" #include "NumSkipView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CNumSkipView IMPLEMENT_DYNCREATE(CNumSkipView, CView) BEGIN_MESSAGE_MAP(CNumSkipView, CView) // 标准打印命令 ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CNumSkipView::OnFilePrintPreview) ON_COMMAND(ID_GAME_NEW, &CNumSkipView::OnNewGame) ON_COMMAND(ID_CHOOSE,&CNumSkipView::OnChoose) ON_WM_CONTEXTMENU() ON_WM_RBUTTONUP() ON_WM_KEYDOWN() ON_WM_CREATE() ON_WM_SYSCOMMAND() ON_COMMAND(ID_EXIT, &CNumSkipView::OnExit) ON_COMMAND(IDC_BACK, &CNumSkipView::OnBack) ON_COMMAND(IDC_REPEAT, &CNumSkipView::OnRepeat) ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() END_MESSAGE_MAP() // CNumSkipView 构造/析构 CNumSkipView::CNumSkipView() { // TODO: 在此处添加构造代码 BackroundColor=RGB(176,224,230); White=RGB(176,224,230); Red=RGB(255,0,0); Green=RGB(127,255,0); Black=RGB(0,0,0); Yellow=RGB(50,205,50); } CNumSkipView::~CNumSkipView() { } BOOL CNumSkipView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: 在此处通过修改 // CREATESTRUCT cs 来修改窗口类或样式 return CView::PreCreateWindow(cs); } // CNumSkipView 绘制 void CNumSkipView::OnDraw(CDC* pDC) { CNumSkipDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; CBrush BackColor(BackroundColor); CBrush *OldBack=pDC->SelectObject(&BackColor); CRect FullRect; GetClientRect(&FullRect); //获得客户区 pDC->FillRect(FullRect,&BackColor); pDC->SelectObject(OldBack); switch(pDoc->GS.m_radio_leveal) //选中不同的单选按钮 { case 0: pDoc->order=7; break; case 1: pDoc->order=11; break; case 2: pDoc->order=15; break; case 3: pDoc->order=19; break; case 4: pDoc->order=23; break; case 5: pDoc->order=27; break; case 6: pDoc->order=31; } pDoc->Path_Long=pDoc->order/3; //矩阵的路径长度 pDoc->So.row=pDoc->order-2; //矩阵的行数 pDoc->So.column=pDoc->order-2; //矩阵的列数 if(pDoc->OverTag==1) { while(1) //随机选出矩阵中数字不超过9的矩阵 { pDoc->So.Input(pDoc->order-3); for(int i=0;i!=pDoc->order-2;i++) { for(int j=0;j!=pDoc->order-2;j++) { if(pDoc->So.matrix[i][j]->elem>9) { continue; } } } if(pDoc->GS.m_radio_modol==1) //单路径模式 { int ShortPath; //矩阵中最短的路径 int CenterX; //矩阵起点横坐标 int CenterY; //矩阵起点纵坐标 CenterX=pDoc->So.row/2; CenterY=pDoc->So.column/2; pDoc->So.Check(CenterX,CenterY,ShortPath); pDoc->So.SinglePath(pDoc->Path_Long); // } break; } pDoc->CurrentPositionX=pDoc->order/2;//起点位置,刚开始为中心 pDoc->CurrentPositionY=pDoc->order/2; pDoc->PrePositionX=0; //上一位置横坐标,刚开始为0 pDoc->PrePositionY=0; //上一位置纵坐标 pDoc->segment=(pDoc->yy-95)/pDoc->order; pDoc->OverTag=0; } for(int i=0,x=0;i!=pDoc->order*pDoc->segment;i+=pDoc->segment,x++) { for(int j=20,y=0;j!=pDoc->order*pDoc->segment+20;j+=pDoc->segment,y++) { if((x==0&&y==0)||(x==pDoc->order-1&&y==pDoc->order-1)||(x==0&&y==pDoc->order-1)||(x==pDoc->order-1&&y==0)) { //四个角为空 } else if(x==0||y==0||x==pDoc->order-1||y==pDoc->order-1) { //将边上的位置全部换成边界终止图 pDC->Rectangle(i,j,i+pDoc->segment,j+pDoc->segment);//保持黑边框 CBrush newcb(Black); CBrush *oldcb=pDC->SelectObject(&newcb); //画圆 pDC->Ellipse((i+i+pDoc->segment)/2-pDoc->segment/3,(j+j+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(j+j+pDoc->segment)/2+pDoc->segment/3); pDC->SelectObject(oldcb); } else if((x+y)%2!=0) { CString s; s.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1]->elem);//将整数转换为字符串 CBrush newBrush(Yellow); CBrush *oldBrush=pDC->SelectObject(&newBrush); pDC->Rectangle(i,j,i+pDoc->segment,j+pDoc->segment); pDC->SelectObject(oldBrush); pDC->SetBkColor(Yellow); //设置字体背景颜色 CFont newcf; newcf.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);//设置字体大小 CFont *oldcf=pDC->SelectObject(&newcf); pDC->SetTextAlign(TA_CENTER);//字体居中 pDC->TextOutW((i+i+pDoc->segment)/2,(j+j+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 pDC->SelectObject(oldcf); } else if(x==pDoc->order/2&&y==pDoc->order/2) { //起点位置图案不同 //Position First; //可要可不要 //First.elem=pDoc->So.matrix[x-1][y-1]->elem; CString s; s.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1]->elem);//将整数转换为字符串 CBrush newBrush1(Yellow); CBrush *oldBrush1=pDC->SelectObject(&newBrush1); pDC->Rectangle(i,j,i+pDoc->segment,j+pDoc->segment); pDC->SelectObject(oldBrush1); //画圆 CBrush newBrush(Red); //起点为红色 CBrush *oldBrush=pDC->SelectObject(&newBrush); // pDC->Rectangle(i,j,i+pDoc->segment,j+pDoc->segment); pDC->Ellipse((i+i+pDoc->segment)/2-pDoc->segment/3,(j+j+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(j+j+pDoc->segment)/2+pDoc->segment/3); //First.x=(i+i+pDoc->segment)/2; //First.y=(j+j+pDoc->segment)/2; //p.push_back(First); pDC->SelectObject(oldBrush); //填字 pDC->SetBkColor(White); //设置字体背景颜色为白色 CFont newcf; newcf.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);//设置字体大小 CFont *oldcf=pDC->SelectObject(&newcf); pDC->SetTextAlign(TA_CENTER);//字体居中 pDC->TextOutW((i+i+pDoc->segment)/2,(j+j+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 pDC->SelectObject(oldcf); } else { CString s; s.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1]->elem);//将整数转换为字符串 CBrush newBrush(White); //矩形为白色 CBrush *oldBrush=pDC->SelectObject(&newBrush); pDC->Rectangle(i,j,i+pDoc->segment,j+pDoc->segment); pDC->SelectObject(oldBrush); pDC->SetBkColor(White); //设置字体背景颜色为白色 CFont newcf; newcf.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);//设置字体大小 CFont *oldcf=pDC->SelectObject(&newcf); pDC->SetTextAlign(TA_CENTER);//字体居中 pDC->TextOutW((i+i+pDoc->segment)/2,(j+j+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 pDC->SelectObject(oldcf); } } } if(pDoc->GS.m_Show!=TRUE) { if(p.size()>0) { for(int i=0;i<=p.size()-1;i++) //恢复路径 { if(i==0) //只挪动了一下,便最小化了 { CBrush Again(Red); CBrush *AgainOldB=pDC->SelectObject(&Again); pDC->Ellipse(p[i].x-pDoc->segment/3,p[i].y-pDoc->segment/3,p[i].x+pDoc->segment/3,p[i].y+pDoc->segment/3); int centx;//圆心x int centy;//圆心y centx=(pDoc->order/2)*pDoc->segment+(pDoc->segment/2); centy=(pDoc->order/2)*pDoc->segment+(pDoc->segment/2)+20; //pDC->Ellipse(centx-pDoc->segment/3,centy-pDoc->segment/3,centx+pDoc->segment/3,centy+pDoc->segment/3); pDC->SelectObject(AgainOldB); CPen AgainL(PS_SOLID,pDoc->segment/16,Red);//从一点到另一点所使用的线 CPen *AgainOldP=pDC->SelectObject(&AgainL); pDC->MoveTo(centx,centy); pDC->LineTo(p[i].x,p[i].y); pDC->SelectObject(AgainOldP); CString ss; CFont AgainFont; AgainFont.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); CFont *AgainOldF=pDC->SelectObject(&AgainFont); pDC->SetTextAlign(TA_CENTER);//字体居中 pDC->SetBkColor(Green); ss.Format(TEXT("%d"),p[i].elem); pDC->TextOutW(p[i].x,p[i].y-(pDoc->segment/4),ss); pDC->SelectObject(AgainOldF); } else { CBrush Again(Red); CBrush *AgainOldB=pDC->SelectObject(&Again); pDC->Ellipse(p[i-1].x-pDoc->segment/3,p[i-1].y-pDoc->segment/3,p[i-1].x+pDoc->segment/3,p[i-1].y+pDoc->segment/3); pDC->Ellipse(p[i].x-pDoc->segment/3,p[i].y-pDoc->segment/3,p[i].x+pDoc->segment/3,p[i].y+pDoc->segment/3); pDC->SelectObject(AgainOldB); CPen AgainL(PS_SOLID,pDoc->segment/16,Red);//从一点到另一点所使用的线 CPen *AgainOldP=pDC->SelectObject(&AgainL); pDC->MoveTo(p[i-1].x,p[i-1].y); pDC->LineTo(p[i].x,p[i].y); pDC->SelectObject(AgainOldP); CString ss; CFont AgainFont; AgainFont.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); CFont *AgainOldF=pDC->SelectObject(&AgainFont); pDC->SetTextAlign(TA_CENTER);//字体居中 ss.Format(TEXT("%d"),p[i-1].elem); pDC->TextOutW(p[i-1].x,p[i-1].y-(pDoc->segment/4),ss);//输出字符串 if(i==p.size()-1) { pDC->SetBkColor(Green); } ss.Format(TEXT("%d"),p[i].elem); pDC->TextOutW(p[i].x,p[i].y-(pDoc->segment/4),ss); pDC->SelectObject(AgainOldF); } } if(pDoc->OverTag==1) { p.clear(); //清空p } } } else { if(p.size()>0) { CBrush Again(Red); CBrush *AgainOldB=pDC->SelectObject(&Again); pDC->Ellipse(p[p.size()-1].x-pDoc->segment/3,p[p.size()-1].y-pDoc->segment/3,p[p.size()-1].x+pDoc->segment/3,p[p.size()-1].y+pDoc->segment/3); pDC->SelectObject(AgainOldB); CString ss; pDC->SetBkColor(Green); CFont AgainFont; AgainFont.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); CFont *AgainOldF=pDC->SelectObject(&AgainFont); pDC->SetTextAlign(TA_CENTER);//字体居中 ss.Format(TEXT("%d"),p[p.size()-1].elem); pDC->TextOutW(p[p.size()-1].x,p[p.size()-1].y-(pDoc->segment/4),ss); pDC->SelectObject(AgainOldF); if(pDoc->OverTag==1) //如果连续多次最小化,则不清空,否则只有新游戏时才刷新 { p.clear(); //清空p } } } // TODO: 在此处为本机数据添加绘制代码 } // CNumSkipView 打印 void CNumSkipView::OnFilePrintPreview() { #ifndef SHARED_HANDLERS AFXPrintPreview(this); #endif } BOOL CNumSkipView::OnPreparePrinting(CPrintInfo* pInfo) { // 默认准备 return DoPreparePrinting(pInfo); } void CNumSkipView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加额外的打印前进行的初始化过程 } void CNumSkipView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/) { // TODO: 添加打印后进行的清理过程 } void CNumSkipView::OnRButtonUp(UINT /* nFlags */, CPoint point) { //ClientToScreen(&point); //OnContextMenu(this, point); } void CNumSkipView::OnContextMenu(CWnd* /* pWnd */, CPoint point) { #ifndef SHARED_HANDLERS theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE); #endif } // CNumSkipView 诊断 #ifdef _DEBUG void CNumSkipView::AssertValid() const { CView::AssertValid(); } void CNumSkipView::Dump(CDumpContext& dc) const { CView::Dump(dc); } CNumSkipDoc* CNumSkipView::GetDocument() const // 非调试版本是内联的 { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CNumSkipDoc))); return (CNumSkipDoc*)m_pDocument; } #endif //_DEBUG // CNumSkipView 消息处理程序 void CNumSkipView::OnNewGame() //点击菜单新游戏 { CNumSkipDoc* pDoc = GetDocument(); pDoc->OverTag=1; p.clear(); InvalidateRect(NULL,FALSE); //刷新界面 } void CNumSkipView::OnChoose() //点击菜单游戏选项 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } void CNumSkipView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CNumSkipDoc* pDoc = GetDocument(); int TemElem; //存储当前位置中的元素 int x; //当前位置横坐标 int y; //当前位置纵坐标 x=pDoc->CurrentPositionX; y=pDoc->CurrentPositionY; TemElem=pDoc->So.matrix[pDoc->CurrentPositionX-1][pDoc->CurrentPositionY-1]->elem; int i; //当前图案的像素横坐标 int j; //当前图案的像素纵坐标 i=pDoc->CurrentPositionX*pDoc->segment; j=pDoc->CurrentPositionY*pDoc->segment+20; CClientDC Dc(this); CString ss; //当前位置元素 CString s; //将要跳到的元素 ss.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1]->elem);//将整数转换为字符串 if(pDoc->GS.m_Show!=TRUE) //显示路径 { Dc.SetBkColor(White); } else //隐藏路径 { if((x+y)%2!=0) { Dc.SetBkColor(Yellow); } else { Dc.SetBkColor(White); } CRect CR(i,j,i+pDoc->segment,j+pDoc->segment); InvalidateRect(CR,FALSE); } //当按下方向键时,将当前元素状态变为已走过状态 //Dc.SetBkColor(White); //设置字体背景颜色 CFont PreFont; PreFont.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); CFont *Preoldcf=Dc.SelectObject(&PreFont); Dc.SetTextAlign(TA_CENTER);//字体居中 Dc.TextOutW((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),ss);//输出字符串 Dc.SelectObject(Preoldcf); CBrush NextBackround(Red);//将要跳到的元素所使用的背景色 CBrush *oldBrush=Dc.SelectObject(&NextBackround); CPen Line(PS_SOLID,pDoc->segment/16,Red);//从一点到另一点所使用的线 CPen *OldPen=Dc.SelectObject(&Line); Dc.SetBkColor(Green); //设置字体背景颜色 Dc.SetTextAlign(TA_CENTER);//字体居中 CFont NextFont; NextFont.CreateFontW(pDoc->segment/2,pDoc->segment/4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);//设置字体大小 CFont *oldcf=Dc.SelectObject(&NextFont); switch(nChar) { case VK_DOWN: //向下 if(y-1+TemElem<pDoc->order-2) //未跳出矩阵 { Position First; //可要可不要 First.elem=pDoc->So.matrix[x-1][y-1+TemElem]->elem;//保存经过的元素值 s.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1+TemElem]->elem);//将整数转换为字符串 //画圆 Dc.Ellipse((2*i+pDoc->segment)/2-pDoc->segment/3,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3); First.x=(2*i+pDoc->segment)/2; //圆心x坐标 First.y=(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2;//圆心y坐标 p.push_back(First);//进容器 Dc.SelectObject(oldBrush); //划线 if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2+pDoc->segment/16*5); Dc.LineTo((i+i+pDoc->segment)/2,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2-(pDoc->segment/4)); Dc.SelectObject(OldPen); } //填字 Dc.TextOutW((i+i+pDoc->segment)/2,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 Dc.SelectObject(oldcf); pDoc->CurrentPositionY+=TemElem; if(pDoc->So.matrix[x-1][y-1+TemElem]->elem==0||(x-1-pDoc->So.matrix[x-1][y-1+TemElem]->elem<-1&&x-1+pDoc->So.matrix[x-1][y-1+TemElem]->elem>pDoc->order-2&&y-1+TemElem-pDoc->So.matrix[x-1][y-1+TemElem]->elem<-1&&y-1+TemElem+pDoc->So.matrix[x-1][y-1+TemElem]->elem>pDoc->order-2)) { int r=pDoc->L.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else if(r==IDC_BACK1) { p.pop_back(); pDoc->CurrentPositionY-=TemElem; Invalidate(); } else PostQuitMessage(0); } } else if(y-1+TemElem==pDoc->order-2)//刚好跳出矩阵 { if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2+pDoc->segment/16*5); Dc.LineTo((i+i+pDoc->segment)/2,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2-(pDoc->segment/4)); Dc.SelectObject(OldPen); } //画圆 Dc.Ellipse((i+i+pDoc->segment)/2-pDoc->segment/3,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(2*(j+TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3); Dc.SelectObject(oldBrush); pDoc->CurrentPositionX=pDoc->order/2; //回到起点 pDoc->CurrentPositionY=pDoc->order/2; int r=pDoc->W.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else PostQuitMessage(0); //新游戏 } else //超出矩阵 { Dc.TextOutW((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),ss);//输出字符串 Dc.SelectObject(oldcf); MessageBox(_T("下方已无路可走")); } break; case VK_LEFT: //向左 if(x-1-TemElem>=0) //未跳出矩阵 { Position First; //可要可不要 First.elem=pDoc->So.matrix[x-1-TemElem][y-1]->elem; s.Format(TEXT("%d"),pDoc->So.matrix[x-1-TemElem][y-1]->elem);//将整数转换为字符串 //画圆 Dc.Ellipse((2*(i-TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(2*j+pDoc->segment)/2-pDoc->segment/3,(2*(i-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3,(2*j+pDoc->segment)/2+pDoc->segment/3); First.x=(2*(i-TemElem*pDoc->segment)+pDoc->segment)/2; First.y=(2*j+pDoc->segment)/2; p.push_back(First); Dc.SelectObject(oldBrush); //划线 if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2-pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.LineTo((2*(i-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/8,(2*j+pDoc->segment)/2); Dc.SelectObject(OldPen); } //填字 Dc.TextOutW((2*(i-TemElem*pDoc->segment)+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 Dc.SelectObject(oldcf); pDoc->CurrentPositionX-=TemElem; if(pDoc->So.matrix[x-1-TemElem][y-1]->elem==0||(x-1-TemElem-pDoc->So.matrix[x-1-TemElem][y-1]->elem<-1&&x-1-TemElem+pDoc->So.matrix[x-1-TemElem][y-1]->elem>pDoc->order-2&&y-1-pDoc->So.matrix[x-1-TemElem][y-1]->elem<-1&&y-1+pDoc->So.matrix[x-1-TemElem][y-1]->elem>pDoc->order-2)) { int r=pDoc->L.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else if(r==IDC_BACK1) { p.pop_back(); pDoc->CurrentPositionX+=TemElem; Invalidate(); } else PostQuitMessage(0); } } else if(x-1-TemElem==-1)//刚好跳出矩阵 { if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2-pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.LineTo((2*(i-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/8,(2*j+pDoc->segment)/2); Dc.SelectObject(OldPen); } //画圆 Dc.Ellipse((2*(i-TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(2*j+pDoc->segment)/2-pDoc->segment/3,(2*(i-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3,(2*j+pDoc->segment)/2+pDoc->segment/3); Dc.SelectObject(oldBrush); pDoc->CurrentPositionX=pDoc->order/2; //回到起点 pDoc->CurrentPositionY=pDoc->order/2; int r=pDoc->W.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else PostQuitMessage(0); //新游戏 } else //超出矩阵 { Dc.TextOutW((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),ss);//输出字符串 Dc.SelectObject(oldcf); MessageBox(_T("左方已无路可走")); } break; case VK_RIGHT: //向右 if(x-1+TemElem<pDoc->order-2) //未跳出矩阵 { Position First; //可要可不要 First.elem=pDoc->So.matrix[x-1+TemElem][y-1]->elem; s.Format(TEXT("%d"),pDoc->So.matrix[x-1+TemElem][y-1]->elem);//将整数转换为字符串 //画圆 Dc.Ellipse((2*(i+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(2*j+pDoc->segment)/2-pDoc->segment/3,(2*(i+TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3,(2*j+pDoc->segment)/2+pDoc->segment/3); First.x=(2*(i+TemElem*pDoc->segment)+pDoc->segment)/2; First.y=(2*j+pDoc->segment)/2; p.push_back(First); Dc.SelectObject(oldBrush); //划线 if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2+pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.LineTo((2*(i+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.SelectObject(OldPen); } //填字 Dc.TextOutW((2*(i+TemElem*pDoc->segment)+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 Dc.SelectObject(oldcf); pDoc->CurrentPositionX+=TemElem; if(pDoc->So.matrix[x-1+TemElem][y-1]->elem==0||(x-1+TemElem-pDoc->So.matrix[x-1+TemElem][y-1]->elem<-1&&x-1+TemElem+pDoc->So.matrix[x-1+TemElem][y-1]->elem>pDoc->order-2&&y-1-pDoc->So.matrix[x-1+TemElem][y-1]->elem<-1&&y-1+pDoc->So.matrix[x-1+TemElem][y-1]->elem>pDoc->order-2)) { int r=pDoc->L.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else if(r==IDC_BACK1) { p.pop_back(); pDoc->CurrentPositionX-=TemElem; Invalidate(); } else PostQuitMessage(0); } } else if(x-1+TemElem==pDoc->order-2)//刚好跳出矩阵 { if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2+pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.LineTo((2*(i+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/4,(2*j+pDoc->segment)/2); Dc.SelectObject(OldPen); } //画圆 Dc.Ellipse((2*(i+TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(2*j+pDoc->segment)/2-pDoc->segment/3,(2*(i+TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3,(2*j+pDoc->segment)/2+pDoc->segment/3); Dc.SelectObject(oldBrush); pDoc->CurrentPositionX=pDoc->order/2; //回到起点 pDoc->CurrentPositionY=pDoc->order/2; int r=pDoc->W.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else PostQuitMessage(0); //退出游戏 } else //超出矩阵 { Dc.TextOutW((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),ss);//输出字符串 Dc.SelectObject(oldcf); MessageBox(_T("右方已无路可走")); } break; case VK_UP: //向上 if(y-1-TemElem>=0) //未跳出矩阵 { Position First; //可要可不要 First.elem=pDoc->So.matrix[x-1][y-1-TemElem]->elem; s.Format(TEXT("%d"),pDoc->So.matrix[x-1][y-1-TemElem]->elem);//将整数转换为字符串 //画圆 Dc.Ellipse((2*i+pDoc->segment)/2-pDoc->segment/3,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3); First.x=(2*i+pDoc->segment)/2; First.y=(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2; p.push_back(First); Dc.SelectObject(oldBrush); //划线 if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-pDoc->segment/16*5); Dc.LineTo((i+i+pDoc->segment)/2,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2+(pDoc->segment/4)); Dc.SelectObject(OldPen); } //填字 Dc.TextOutW((i+i+pDoc->segment)/2,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2-(pDoc->segment/4),s);//输出字符串 Dc.SelectObject(oldcf); pDoc->CurrentPositionY-=TemElem; if(pDoc->So.matrix[x-1][y-1-TemElem]->elem==0||(x-1-pDoc->So.matrix[x-1][y-1-TemElem]->elem<-1&&x-1+pDoc->So.matrix[x-1][y-1-TemElem]->elem>pDoc->order-2&&y-1-TemElem-pDoc->So.matrix[x-1][y-1-TemElem]->elem<-1&&y-1-TemElem+pDoc->So.matrix[x-1][y-1-TemElem]->elem>pDoc->order-2)) { int r=pDoc->L.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else if(r==IDC_BACK1) { p.pop_back(); pDoc->CurrentPositionY+=TemElem; Invalidate(); } else PostQuitMessage(0); } } else if(y-1-TemElem==-1)//刚好跳出矩阵 { if(pDoc->GS.m_Show!=TRUE) { Dc.MoveTo((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-pDoc->segment/16*5); Dc.LineTo((i+i+pDoc->segment)/2,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2+(pDoc->segment/4)); Dc.SelectObject(OldPen); } //画圆 Dc.Ellipse((i+i+pDoc->segment)/2-pDoc->segment/3,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2-pDoc->segment/3,(i+i+pDoc->segment)/2+pDoc->segment/3,(2*(j-TemElem*pDoc->segment)+pDoc->segment)/2+pDoc->segment/3); Dc.SelectObject(oldBrush); pDoc->CurrentPositionX=pDoc->order/2; //回到起点 pDoc->CurrentPositionY=pDoc->order/2; int r=pDoc->W.DoModal(); if(r==IDC_AGAIN) //再来一局 { pDoc->OverTag=1; p.clear(); Invalidate(); } else if(r==IDOK) //新游戏 { CNumSkipDoc* pDoc = GetDocument(); int result=pDoc->GS.DoModal(); if(result==IDOK) //读取对话框中的信息并刷新 { UpdateData(TRUE); pDoc->OverTag=1; p.clear(); Invalidate(); } else { UpdateData(FALSE); } } else PostQuitMessage(0); //退出游戏 } else //超出矩阵 { Dc.TextOutW((i+i+pDoc->segment)/2,(2*j+pDoc->segment)/2-(pDoc->segment/4),ss);//输出字符串 Dc.SelectObject(oldcf); MessageBox(_T("上方已无路可走")); } } CView::OnKeyDown(nChar, nRepCnt, nFlags); } int CNumSkipView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: 在此添加您专用的创建代码 return 0; } void CNumSkipView::OnSysCommand(UINT nID, LPARAM lParam) { // TODO: 在此添加消息处理程序代码和/或调用默认值 /*if(nID==SC_MINIMIZE) { CRect r(0,0,1,1); InvalidateRect(r,FALSE); } else if(nID==SC_MAXIMIZE) { CRect r(0,0,1,1); InvalidateRect(r,FALSE); }*/ CView::OnSysCommand(nID, lParam); } void CNumSkipView::OnExit() { // TODO: 在此添加命令处理程序代码 PostQuitMessage(0); //退出游戏 } void CNumSkipView::OnBack() { // TODO: 在此添加命令处理程序代码 CNumSkipDoc* pDoc = GetDocument(); if(p.size()>1) { p.pop_back(); pDoc->CurrentPositionX=(p[p.size()-1].x-pDoc->segment/2)/pDoc->segment;//将当前位置更改 pDoc->CurrentPositionY=(p[p.size()-1].y-pDoc->segment/2-20)/pDoc->segment; } else { p.pop_back(); pDoc->CurrentPositionX=pDoc->order/2;//起点位置,刚开始为中心 pDoc->CurrentPositionY=pDoc->order/2; } Invalidate(); } void CNumSkipView::OnRepeat() { // TODO: 在此添加命令处理程序代码 CNumSkipDoc* pDoc = GetDocument(); p.clear(); pDoc->CurrentPositionX=pDoc->order/2;//起点位置,刚开始为中心 pDoc->CurrentPositionY=pDoc->order/2; Invalidate(); } void CNumSkipView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CNumSkipDoc* pDoc = GetDocument(); if((point.x<pDoc->segment&&point.y<pDoc->segment+20)||(point.x>(pDoc->order-1)*pDoc->segment&&point.x<pDoc->order*pDoc->segment&&point.y<pDoc->segment+20&&point.y>20))//排除上面两个角 {} else if((point.x<pDoc->segment&&point.y<(pDoc->order*pDoc->segment)+20&&point.y>(pDoc->order-1)*pDoc->segment+20)||(point.x>(pDoc->order-1)*pDoc->segment&&point.x<pDoc->order*pDoc->segment&&point.y<pDoc->order*pDoc->segment+20&&point.y>20+(pDoc->order-1)*pDoc->segment)) {} //排除下面两个角 else if(point.x<=pDoc->order*pDoc->segment&&point.y<=pDoc->order*pDoc->segment+20&&point.y>20)//鼠标点击了游戏区域,将此区域用黑圆代替 { node2 Area; Area.i1=(2*((point.x/pDoc->segment)*pDoc->segment)+pDoc->segment)/2; Area.j1=(2*(((point.y-15)/pDoc->segment)*pDoc->segment)+pDoc->segment)/2+20; pp.push_back(Area); CClientDC DC(this); CBrush cb(Black); CBrush *oldcb=DC.SelectObject(&cb); DC.Ellipse(Area.i1-pDoc->segment/3,Area.j1-pDoc->segment/3,Area.i1+pDoc->segment/3,Area.j1+pDoc->segment/3); DC.SelectObject(oldcb); } CView::OnLButtonDown(nFlags, point); } void CNumSkipView::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CNumSkipDoc* pDoc = GetDocument(); if((point.x<pDoc->segment&&point.y<pDoc->segment+20)||(point.x>(pDoc->order-1)*pDoc->segment&&point.x<pDoc->order*pDoc->segment&&point.y<pDoc->segment+20&&point.y>20))//排除上面两个角 {} else if((point.x<pDoc->segment&&point.y<(pDoc->order*pDoc->segment)+20&&point.y>(pDoc->order-1)*pDoc->segment+20)||(point.x>(pDoc->order-1)*pDoc->segment&&point.x<pDoc->order*pDoc->segment&&point.y<pDoc->order*pDoc->segment+20&&point.y>20+(pDoc->order-1)*pDoc->segment)) {} //排除下面两个角 else if(point.x<=pDoc->order*pDoc->segment&&point.y<=pDoc->order*pDoc->segment+20&&point.y>20)//鼠标点击了游戏区域,将此区域用黑圆代替 { node2 Area; Area.i1=(2*(((point.x)/pDoc->segment)*pDoc->segment)+pDoc->segment)/2; Area.j1=(2*((((point.y-15))/pDoc->segment)*pDoc->segment)+pDoc->segment)/2+20; pp.push_back(Area); CClientDC DC(this); CBrush cb(Red); CBrush *oldcb=DC.SelectObject(&cb); DC.Ellipse(Area.i1-pDoc->segment/3,Area.j1-pDoc->segment/3,Area.i1+pDoc->segment/3,Area.j1+pDoc->segment/3); DC.SelectObject(oldcb); } CView::OnRButtonDown(nFlags, point); } //******************* SkipOut.h #pragma once #include<stdlib.h> #include<time.h> #include<vector> using namespace std; typedef struct node { int i,j; int pre; }*ptrn; typedef struct node1 //矩阵中每个元素的结构 { int elem; bool tag; }*ptrnelse; struct node2 { int i1; //横坐标 int j1; //纵坐标 }; class SkipOut { private: vector<ptrn> temlist; //vector<int> array; vector<node2> path; //将随机生成的路径存入 ptrn *quelist; //元素入栈 public: ptrnelse **matrix; //矩阵 int count_bool; int count; int rear; //代表所走过的点数 int front; //栈顶同时其值代表着栈中元素个数 int row; //矩阵之行数 int column; //矩阵之列数 SkipOut(void); void Input(int n2) ; //生成路径长度为n2的矩阵 void Check(int &nnrow,int mmcolumn,int &num); void SinglePath(int &num); //将矩阵中长度不是num的路径封死只留一条长度为num的路径 ~SkipOut(void); }; //************************** SkipOut.cpp #include "StdAfx.h" #include "SkipOut.h" SkipOut::SkipOut(void) { } void SkipOut::Input(int n2) //生成路径长度为n2的矩阵 { count_bool=0; matrix=(ptrnelse **)new ptrnelse*[row]; //动态分配矩阵的行数 for(int i=0;i!=row;i++) //定义矩阵的列数 { matrix[i]=new ptrnelse[column]; } srand((int)time(0)); //初始随机函数 for(int i=0;i!=row;i++) { for(int j=0;j!=column;j++) { matrix[i][j]=new node1; matrix[i][j]->elem=-2; //用以区分其值有没有已经被分配 matrix[i][j]->tag=true; //矩阵中每个元素的初始状态为true } } int temx; //当前位置的x值 int temy; //当前位置的y值 temx=row/2; temy=column/2; while(count_bool<n2) { int n3; //随机产生一个元素值 int n4; //方向 n4=1+rand()%4; //随机产生一个方向 switch(n4) {//1 case 1: //代表上 while(1) //循环用以选出合适的数字 {//2 n3=1+rand()%9; //矩阵中的元素最大值为9 if(count_bool==n2-1) //当为路径中最后一点时 {//3 if(temx-n3==-1) //如果向上正好走出边界 { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; //跳出循环 } else if(temx>8) //如果不论n3为何值都不可能跳出矩阵 { matrix[temx][temy]->elem=temx+1; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else //如果可以跳出矩阵则继续循环直至选出符合条件的值 { continue; } }//3 else if(temx-n3>=0||temx==0) {//4 int count_true; //可走的点数 int count_false; //不可走的点数 count_true=0; count_false=0; for(int k=0;k!=temx;k++) { if(matrix[k][temy]->tag==true) count_true++; else count_false++; } if(count_true>0&&count_false<9) //如果当前位置上方9个点有未访问过的点则正常执行 { //5 //防止上面有超过9个位置且与其上方连续9个都被访问过***************** while(1) { //6 if(matrix[temx-n3][temy]->tag==true) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); matrix[temx][temy]->tag=false; temx=temx-n3; count_bool++; break; } else { while(1) { n3=1+rand()%9; if(temx-n3>=0) { break; } else { continue; } } } }//6 }//5 else //如果当前位置上方所有的点都访问过了则转向 { break; } }//4 else { continue; } }//2 break; case 2: //代表右 while(1) { n3=1+rand()%9; //当行数大于等于10时,矩阵中的元素最大值为9 if(count_bool==n2-1) { if(temy+n3==column) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else if(temy+9<column) { matrix[temx][temy]->elem=column-temy; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else { continue; } } else if(temy+n3<column||temy==column-1) { int count_true; //可走的点数 int count_false; //不可走的点数 count_true=0; count_false=0; for(int k=temy+1;k!=column;k++) { if(matrix[temx][k]->tag==true) { count_true++; } else { count_false++; } } if(count_true>0&&count_false<9) //如果当前位置上方9个点有未访问过的点则正常执行 { //防止上面有超过9个位置且与其上方连续9个都被访问过***************** while(1) { if(matrix[temx][temy+n3]->tag==true) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); matrix[temx][temy]->tag=false; temy=temy+n3; count_bool++; break; } else { while(1) { n3=1+rand()%9; if(temy+n3<column) { break; } else { continue; } } } } } else //如果当前位置上方所有的点都访问过了则转向 { break; } } else { continue; //继续循环直至找出符合条件的数字 } } break; case 3: //代表下 while(1) { n3=1+rand()%9; //当行数大于等于10时,矩阵中的元素最大值为9 if(count_bool==n2-1) { if(temx+n3==row) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else if(temx+9<row) { matrix[temx][temy]->elem=row-temx; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else { continue; } } else if(temx+n3<=row-1||temx==row-1) { int count_true; //可走的点数 int count_false; //不可走的点数 count_true=0; count_false=0; for(int k=temx+1;k!=row;k++) { if(matrix[k][temy]->tag==true) { count_true++; } else { count_false++; } } if(count_true>0&&count_false<9) //如果当前位置上方9个点有未访问过的点则正常执行 { //防止上面有超过9个位置且与其上方连续9个都被访问过***************** while(1) { if(matrix[temx+n3][temy]->tag==true) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); matrix[temx][temy]->tag=false; temx=temx+n3; count_bool++; break; } else { while(1) { n3=1+rand()%9; if(temx+n3<row) { break; } else { continue; } } } } } else //如果当前位置上方所有的点都访问过了则转向 { break; } } else { continue; //继续循环直至找出符合条件的数字 } } break; case 4: //代表左 while(1) { n3=1+rand()%9; //当行数大于等于10时,矩阵中的元素最大值为9 if(count_bool==n2-1) { if(temy-n3==-1) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else if(temy-9>=0) { matrix[temx][temy]->elem=temy+1; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); count_bool++; break; } else { continue; } } else if(temy-n3>=0||temy==0) { int count_true; //可走的点数 int count_false; //不可走的点数 count_true=0; count_false=0; for(int k=0;k!=temy;k++) { if(matrix[temx][k]->tag==true) { count_true++; } else { count_false++; } } if(count_true>0&&count_false<9) //如果当前位置上方9个点有未访问过的点则正常执行 { //防止上面有超过9个位置且与其上方连续9个都被访问过***************** while(1) { if(matrix[temx][temy-n3]->tag==true) { matrix[temx][temy]->elem=n3; node2 point; //将此点的位置信息存入容器 point.i1=temx; point.j1=temy; path.push_back(point); matrix[temx][temy]->tag=false; temy=temy-n3; count_bool++; break; } else { while(1) { n3=1+rand()%9; if(temy-n3>=0) { break; } else { continue; } } } } } else //如果当前位置上方所有的点都访问过了则转向 { break; } } else { continue; //继续循环直至找出符合条件的数字 } } } } for(int i=0;i!=row;i++) { for(int j=0;j!=column;j++) { int n5; n5=1+rand()%9; //当行数大于等于10时,矩阵中的元素最大值为9 if(matrix[i][j]->elem==-2) { matrix[i][j]->elem=n5; //为那些没有被分配元素的位置分配元素 } else { matrix[i][j]->tag=true; } } } } void SkipOut::Check(int &nnrow,int mmcolumn,int &num) {//1 front=0; //初始值 count=row*column; quelist=new ptrn[row*column]; //分配存储空间 quelist[front]=new node; quelist[front]->i=nnrow; //起点入栈 quelist[front]->j=mmcolumn; quelist[front]->pre=-2; for(int ii=0;ii!=row;ii++) {//2 for(int jj=0;jj!=column;jj++) {//3 int temcount; temcount=0; front=1; rear=0; for(int iii=0;iii!=row;iii++) {//4 for(int jjj=0;jjj!=column;jjj++) {//5 matrix[iii][jjj]->tag=true;//将矩阵matrix中的元素状态还原 }//5 }//4 matrix[nnrow][mmcolumn]->tag=false;//将起点的状态设置成已访问 if(ii-matrix[ii][jj]->elem==-1||jj+matrix[ii][jj]->elem==column||ii+matrix[ii][jj]->elem==row||jj-matrix[ii][jj]->elem==-1) {//6 若当前点可以作为终点的话 while(1) {//7 从起点开始搜索路径 int nelem; //当前位置的元素值 nelem=matrix[quelist[rear]->i][quelist[rear]->j]->elem; if(quelist[rear]->i-nelem<-1&&quelist[rear]->j+nelem>column&&quelist[rear]->i+nelem>row&&quelist[rear]->j-nelem<-1) {//如果当前位置的周围均不可走 if(rear==0) {//如果第一步就不可走 break; } else { if(front!=rear+1) rear++; } } else {//8 如果当前位置周围有可走路径 if(rear==0) { if(quelist[rear]->i-nelem==-1||quelist[rear]->j+nelem==column||quelist[rear]->i+nelem==row||quelist[rear]->j-nelem==-1) break; } if(quelist[rear]->i!=ii||quelist[rear]->j!=jj) {//如果没有到达终点则继续扫描 if(quelist[rear]->i-nelem>=0) //当前位置的上部位置可走 { int ni=quelist[rear]->i; int nj=quelist[rear]->j; if(matrix[ni-nelem][nj]->tag==true) { //当前位置上方的路径可走 matrix[ni-nelem][nj]->tag=false; quelist[front]=new node; quelist[front]->i=ni-nelem; quelist[front]->j=nj; quelist[front]->pre=rear; front++; } } if(quelist[rear]->j+nelem<column) //当前位置的右边可走 { int ni=quelist[rear]->i; int nj=quelist[rear]->j; if(matrix[ni][nj+nelem]->tag==true)//******************** { matrix[ni][nj+nelem]->tag=false; quelist[front]=new node; quelist[front]->i=ni; quelist[front]->j=nj+nelem; quelist[front]->pre=rear; front++; } } if(quelist[rear]->i+nelem<row) //当前位置的下方可走 { if(matrix[quelist[rear]->i+nelem][quelist[rear]->j]->tag==true) { int ni=quelist[rear]->i; int nj=quelist[rear]->j; matrix[ni+nelem][nj]->tag=false; quelist[front]=new node; quelist[front]->i=ni+nelem; quelist[front]->j=nj; quelist[front]->pre=rear; front++; } } if(quelist[rear]->j-nelem>=0) { //当前位置的左方可走 if(matrix[quelist[rear]->i][quelist[rear]->j-nelem]->tag==true) { int ni=quelist[rear]->i; int nj=quelist[rear]->j; matrix[ni][nj-nelem]->tag=false; quelist[front]=new node; quelist[front]->i=ni; quelist[front]->j=nj-nelem; quelist[front]->pre=rear; front++; } } rear++; } else {//如果到达终点 while(1) {//对路径计长 if(quelist[rear]->pre==-2) { temlist.push_back(quelist[rear]); temcount++; break; } else { temlist.push_back(quelist[rear]); temcount++; } rear=quelist[rear]->pre; } if(temcount<count) { //如果此路径较短 交换 count=temcount; num=count; } break;//跳出while } }//8 if(front==rear+1) {//无路径 break; } }//7 }//6 else { //如果当前点不能做终点的话继续用下一点 continue; } }//3 }//2 }//1 void SkipOut::SinglePath(int &num) { //temlist中存放的数据形式为[3,2,1,6,3,5,2,1,8,6,4,5,1] int cc; //倒序着看其中1为起点,两个1之间是经过的路径,上述temlist存放了3条路径 int size; //temlist中元素个数 size=temlist.size(); cc=1; // 当前路径起始长度为0 int k; //temlist元素的下标 k=size-2; //下标范围 bool AlreadyFind; //找出标志,如果已找出指定路径长度则为true否则为false; AlreadyFind=false; /*for(int i=size-1;i!=-1;i--) { cout<<"["<<temlist[i]->i<<","<<temlist[i]->j<<"] "<<' '; //输出所有路径 }*/ while(1) { //每循环一次下标k减一 if(temlist[size-1]->i==temlist[k]->i&&temlist[size-1]->j==temlist[k]->j&&k!=0) { //当所访问的点与起点相同时,则说明这两个位置之间存有一条路径 if(cc==num) //判断此路径与所要求的路径长度是否相同 { //如果相同,则不做操作 AlreadyFind=true; cc=1; } else if(cc!=1) //如果不同,则封死此路径,即将此路径最后一点置为零 { int co; //计数 co=0; for(int n5=0;n5!=path.size()-1;n5++) //防止封死的那个点在随机产生的那条路径上 { if(temlist[k+1]->i==path[n5].i1&&temlist[k+1]->j==path[n5].j1) { co++; } } if(co==0) { matrix[temlist[k+1]->i][temlist[k+1]->j]->elem=0; } // matrix[temlist[k+1]->i][temlist[k+1]->j]->elem=0; cc=1; //并将路径长度置为1,从新计算路径长度 } } else if(k==0)//访问到第一个点时 { if(AlreadyFind==true)//表示在前方搜索时已找出所指定路径 { //matrix[temlist[k]->i][temlist[k]->j]->elem=0;//将此路径封死 int co; //计数 co=0; for(int n5=0;n5!=path.size()-1;n5++) //防止封死的那个点在随机产生的那条路径上 { if(temlist[k]->i==path[n5].i1&&temlist[k]->j==path[n5].j1) { co++; } } if(co==0) { matrix[temlist[k]->i][temlist[k]->j]->elem=0; } } //否则不问 ,说明最后一个路径长度即为指定路径 break; //跳出while循环 } else { cc++; //路径长度增加 } k--; //下标前移 } } SkipOut::~SkipOut(void) { /*delete []matrix; delete []quelist;*/ } //************************ Win.h #pragma once // Win 对话框 class Win : public CDialog { DECLARE_DYNAMIC(Win) public: Win(CWnd* pParent = NULL); // 标准构造函数 virtual ~Win(); // 对话框数据 enum { IDD = IDD_WIN }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() public: afx_msg void OnBnClickedAgain(); afx_msg void OnBnClickedOk(); afx_msg void OnBnClickedCancel(); }; //********************* Win.cpp // Win.cpp : 实现文件 // #include "stdafx.h" #include "NumSkip.h" #include "Win.h" #include "afxdialogex.h" #include"GameSet.h" // Win 对话框 IMPLEMENT_DYNAMIC(Win, CDialog) Win::Win(CWnd* pParent /*=NULL*/) : CDialog(Win::IDD, pParent) { } Win::~Win() { } void Win::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(Win, CDialog) ON_BN_CLICKED(IDC_AGAIN, &Win::OnBnClickedAgain) ON_BN_CLICKED(IDOK, &Win::OnBnClickedOk) ON_BN_CLICKED(IDCANCEL, &Win::OnBnClickedCancel) END_MESSAGE_MAP() // Win 消息处理程序 void Win::OnBnClickedAgain() { // TODO: 在此添加控件通知处理程序代码 EndDialog(IDC_AGAIN); } void Win::OnBnClickedOk() { // TODO: 在此添加控件通知处理程序代码 CDialog::OnOK(); } void Win::OnBnClickedCancel() { // TODO: 在此添加控件通知处理程序代码 CDialog::OnCancel(); }