当前位置:首页 » 《随便一记》 » 正文

Visual C++实现连连看游戏项目实战三:核心算法设计与实现(附源码和资源 可用于大作业)

13 人参与  2023年03月29日 12:25  分类 : 《随便一记》  评论

点击全文阅读


需要源码和资源请点赞关注收藏后评论区留言私信~~~

一、主对话框类的设计

连连看的主对话框类,主要负责显示游戏界面,等级,时间显示以及快捷键调用等等。主要有以下几个处理模块

1:主菜单处理模块

2:连接提示处理模块

3:换盘处理模块

4:初始化棋盘数据模块

5:游戏信息化处理模块

主对话框类声明代码如下

其中包含连接提示,显示棋盘,显示数据,换盘,初始化游戏以及棋盘数据函数等

// llkDlg.h : header file//#if !defined(AFX_LLKDLG_H__BCB1D0A0_D08E_42B3_B138_E0F4345D7AAC__INCLUDED_)#define AFX_LLKDLG_H__BCB1D0A0_D08E_42B3_B138_E0F4345D7AAC__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/// CLlkDlg dialog#include "LineStatic.h"#include "ChessMan.h"class CLlkDlg : public CDialog{// Constructionpublic:void RefreshMap();void Exchange(int map[MAXX][MAXY]);void CallHint();void CallExchange();void ShowMap(int map[MAXX][MAXY]);void InitMap(int map[MAXX][MAXY]);void ShowMsg(CRgn * rgn);void Start(int nlevel);void PlayBackMusic(BOOL bflag);void isHighLevel();CLlkDlg(CWnd* pParent = NULL);// standard constructorCChessMan * m_p;//棋子指针int map[MAXX][MAXY];//棋盘数组BOOLm_bStart;//游戏开始状态intm_nLevel;//当前等级限制intm_timePoint;//时间限制CRgnm_MsgRgn;//信息区范围CPtrArray m_cmGroup;//棋子数组intm_hintNum;//提示次数限制intm_exchangeNum;//换盘次数限制int     m_nHighLevel;//最高等级// Dialog Data//{{AFX_DATA(CLlkDlg)enum { IDD = IDD_LLK_DIALOG };CStaticm_method;CLineStaticm_line;CStaticm_bkPic;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CLlkDlg)public:virtual BOOL PreTranslateMessage(MSG* pMsg);protected:virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;CMenu m_main_menu;int m_hintP2;//第2个转折点int m_hintP1;//第1个转折点// Generated message map functions//{{AFX_MSG(CLlkDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnAbout();afx_msg void OnExitGame();afx_msg void OnHelp();afx_msg void OnHeroList();afx_msg void OnPlayMusic();afx_msg void OnStartGame();afx_msg void OnTimer(UINT nIDEvent);//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LLKDLG_H__BCB1D0A0_D08E_42B3_B138_E0F4345D7AAC__INCLUDED_)

主对话框类实现如下,其中包含基本的初始化对话框函数,游戏开始处理函数以及背景音乐播放功能函数等等

// llkDlg.cpp : implementation file//#include "stdafx.h"#include "llk.h"#include "llkDlg.h"#include "HeroDlg.h"#include "HelpDlg.h"#include <mmsystem.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif#define IDC_BLOCK 2000 /// CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CLlkDlg dialogCLlkDlg::CLlkDlg(CWnd* pParent /*=NULL*/): CDialog(CLlkDlg::IDD, pParent){//{{AFX_DATA_INIT(CLlkDlg)//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CLlkDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CLlkDlg)DDX_Control(pDX, IDC_METHOD, m_method);DDX_Control(pDX, IDC_LINE, m_line);DDX_Control(pDX, IDC_BKPIC, m_bkPic);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CLlkDlg, CDialog)//{{AFX_MSG_MAP(CLlkDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_COMMAND(IDR_ABOUT, OnAbout)ON_COMMAND(IDR_EXIT_GAME, OnExitGame)ON_COMMAND(IDR_HELP, OnHelp)ON_COMMAND(IDR_HERO_LIST, OnHeroList)ON_COMMAND(IDR_PLAY_MUSIC, OnPlayMusic)ON_COMMAND(IDR_START_GAME, OnStartGame)ON_WM_TIMER()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CLlkDlg message handlersBOOL CLlkDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}SetIcon(m_hIcon, TRUE);// Set big iconSetIcon(m_hIcon, FALSE);// Set small iconm_main_menu.LoadMenu(IDR_MAIN_MENU);SetMenu(&m_main_menu);m_nLevel = 1;SetWindowPos(NULL, 100, 100, 800, 600, SWP_SHOWWINDOW|SWP_NOZORDER);m_method.SetWindowPos(NULL, 300, 500, 200, 25, SWP_SHOWWINDOW|SWP_NOZORDER);m_bkPic.SetWindowPos(NULL, 130, 70, 480, 280, SWP_SHOWWINDOW|SWP_NOZORDER);m_line.SetWindowPos(NULL, 90, 30, 560, 360, SWP_SHOWWINDOW|SWP_NOZORDER);m_MsgRgn.CreateRectRgn(150, 20, 550, 40);m_bStart = false;return TRUE;  // return TRUE  unless you set the focus to a control}void CLlkDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialog::OnSysCommand(nID, lParam);}}void CLlkDlg::OnPaint() {CDialog::OnPaint();}HCURSOR CLlkDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}void CLlkDlg::OnAbout() {CAboutDlg dlg;dlg.DoModal();}void CLlkDlg::OnExitGame() {CDialog::OnCancel();}void CLlkDlg::OnHelp() {CHelpDlg dlg;dlg.DoModal();}void CLlkDlg::OnHeroList() {CHeroDlg dlg;dlg.DoModal();}void CLlkDlg::OnPlayMusic() {//判断播放音乐菜单当前状态BOOL bCheck = (BOOL)m_main_menu.GetMenuState(IDR_PLAY_MUSIC, MF_CHECKED);if(m_bStart){//游戏如果开始才允许播放音乐if(bCheck){m_main_menu.CheckMenuItem(IDR_PLAY_MUSIC,MF_BYCOMMAND | MF_UNCHECKED);}else{m_main_menu.CheckMenuItem(IDR_PLAY_MUSIC, MF_BYCOMMAND | MF_CHECKED);}PlayBackMusic(!bCheck);//调用播放背景音乐功能函数}}void CLlkDlg::OnStartGame() {char pszTmp[128] = {0};m_hintNum = 3;m_exchangeNum = 3;m_line.m_lineNum = 0;m_method.SetWindowText("开 始 游 戏!");Start(1);GetPrivateProfileString("HERO", "level", "1", pszTmp, 127, ".\\setup.ini");m_nHighLevel = atoi(pszTmp);}////播放背景音乐//void CLlkDlg::PlayBackMusic(BOOL bflag){//指定文件并播放if(bflag){//播放音乐sndPlaySound("music.wav",SND_ASYNC); }else{//停止播放sndPlaySound(NULL,SND_PURGE); }}////游戏开始//void CLlkDlg::Start(int level){CString str;m_nLevel = level;m_timePoint = 130 - level * 10;//设置每个等级的限制时间//随机设置背景图片srand((unsigned int)time(NULL));str.Format("res\\b%d.bmp", m_nLevel);m_bkPic.ModifyStyle(0,SS_BITMAP|SS_CENTERIMAGE);    HBITMAP m_bkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE); m_bkPic.SetBitmap(m_bkBmp);InitMap(map);ShowMap(map);m_p = NULL;CRgn rgn;rgn.CreateRectRgn(420, 0, 560, 160);m_MsgRgn.CopyRgn(&rgn);ShowMsg(&m_MsgRgn);//设置计时器KillTimer(1);SetTimer(1, 1000, NULL);m_bStart = true;}////信息显示//void CLlkDlg::ShowMsg(CRgn *rgn){CClientDC *pDC = (CClientDC *)GetDC();//int nOldDC = pDC->SaveDC();CFont font; CString str;//设置字体if(0==font.CreatePointFont(150,"Comic Sans MS")){AfxMessageBox("Can't Create Font");}pDC->SelectObject(&font);//设置字体颜色及其背景颜色pDC->SetTextColor(RGB(39,244,10));pDC->SetBkColor(RGB(0,0,0));    //输出数字str.Format("游戏等级: %d",m_nLevel);pDC->TextOut(650,420,str);str.Format("剩余时间: %03d", m_timePoint);pDC->TextOut(650, 450, str);str.Format("提示次数: %d",m_hintNum);pDC->TextOut(650,480,str);str.Format("换盘次数: %d", m_exchangeNum);pDC->TextOut(650, 510, str);}////初始化棋盘数组//void CLlkDlg::InitMap(int map[][MAXY]){int i, j;int x, y;//初始化边界for(i=0; i<MAXX; i++){for(j=0; j<MAXY; j++){if((i==0) || (i==MAXX-1) || (j==0) || (j==MAXY-1)){map[i][j] = -1;}else{map[i][j] = 0;}}}srand((unsigned int)time(NULL));//随机数种子//初始化地图for(i=0; i<SAME; i++){for(j=1; j<=TYPENUM; j++){x = rand()%MAXX;y = rand()%MAXY;if(map[x][y]){j--;}else{map[x][y] = j;}}}}////转换棋盘数组的中数据为棋子并显示出来//void CLlkDlg::ShowMap(int map[][MAXY]){this->Invalidate();int i, j;POINT p;CString str;//清除原有按钮for(i=0; i<m_cmGroup.GetSize(); i++)delete (CChessMan *)m_cmGroup.GetAt(i);m_cmGroup.RemoveAll();for(i=1; i<MAXX-1; i++){for(j=1; j<MAXY-1; j++){p.x = i;p.y = j;m_cmGroup.Add(new CChessMan(map[i][j], p));}}for(i=0; i<(MAXX-2)*(MAXY-2); i++){CChessMan *btn = (CChessMan *)m_cmGroup.GetAt(i);btn->Create(str, WS_CHILD|BS_BITMAP, //注意属性!!!CRect(130+(i%(MAXY-2))*40, 70+(i/(MAXY-2))*40, 170+(i%(MAXY-2))*40, 110+(i/(MAXY-2))*40), this, IDC_BLOCK+i);if(btn->m_id)//如果为0则不显示{str.Format("res\\%d.bmp", btn->m_id);HBITMAP m_fkBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), str, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);if(m_fkBmp == NULL) {if(MessageBox("缺少图片资源!", "错误", MB_ICONERROR|MB_OK) == IDOK){CDialog::OnCancel();return;}}btn->SetBitmap(m_fkBmp);btn->ShowWindow(SW_SHOW);}else{btn->ShowWindow(SW_HIDE);}}}////换盘接口成员函数//void CLlkDlg::CallExchange(){if(m_exchangeNum){doExchange(map);while(!CChessMan::Hint(map));//至少有一个可消去ShowMap(map);m_exchangeNum--;}}////提示连接接口成员函数//void CLlkDlg::CallHint(){if(m_hintNum){if(CChessMan::Hint(map, &m_hintP1, &m_hintP2)){CChessMan *temp;temp = (CChessMan *)m_cmGroup.GetAt(m_hintP1);temp->SetButtonStyle(BS_DEFPUSHBUTTON);temp = (CChessMan *)m_cmGroup.GetAt(m_hintP2);temp->SetButtonStyle(BS_DEFPUSHBUTTON);m_hintNum--;}}}////换盘函数//void CLlkDlg::Exchange(int map[][MAXY]){int i, j;int k = 0;int temp[(MAXX-2)*(MAXY-2)+1] = {0};//比格子数多一个,防止数组越界!!!for(i=1; i<MAXX-1; i++){for(j=1; j<MAXY-1; j++){if(map[i][j]){temp[k++] = map[i][j];map[i][j] = 0;}}}srand((unsigned int)time(NULL));k = 0;while(temp[k]){i = rand()%MAXX;j = rand()%MAXY;if(map[i][j])k--;elsemap[i][j] = temp[k];k++;}}////更新棋盘数组//void CLlkDlg::RefreshMap(){CRgn resultRgn;resultRgn.CreateRectRgn(90,30,690,430);CRgn tmpRgn;tmpRgn.CreateRectRgn(0,0,0,0);for(int i=0; i<MAXX; i++){for(int j=0; j<MAXY; j++){CRect rect;CRgn srcRgn;if(map[i][j]==-1 || map[i][j]==0){rect.top = 30 + i*40;rect.bottom = 70 + i*40;rect.left = 90 + j*40;rect.right = 130 + j*40;srcRgn.CreateRectRgnIndirect(&rect);//把消去的区域加进来(覆盖原有区域),以便刷新resultRgn.CombineRgn(&srcRgn,&tmpRgn,RGN_OR);tmpRgn.CopyRgn(&resultRgn);}}}//只刷新被消去的区域,防止界面闪烁this->InvalidateRgn(&resultRgn);}////定时器//void CLlkDlg::OnTimer(UINT nIDEvent) {m_timePoint -= 1;if(m_timePoint <= 0){KillTimer(1);int nRet = MessageBox("限 制 时 间 到!", "闯 关 失 败", MB_YESNO|MB_ICONINFORMATION);if(IDYES == nRet){OnStartGame();}else{isHighLevel();CDialog::OnCancel();}return;}InvalidateRgn(&m_MsgRgn);ShowMsg(&m_MsgRgn);}////截获用户消息//BOOL CLlkDlg::PreTranslateMessage(MSG* pMsg) {//键盘按下消息if(pMsg->message==WM_KEYDOWN){switch((int)pMsg->wParam){case VK_F5://快捷键F5CallHint();m_line.m_lineNum = 0;RefreshMap();m_line.Invalidate();break;case VK_F6://快捷键F6CallExchange();m_line.m_lineNum = 0;RefreshMap();m_line.Invalidate();break;default:break;}}return CDialog::PreTranslateMessage(pMsg);}void CLlkDlg::isHighLevel(){if(m_nHighLevel<m_nLevel){CHeroDlg dlg;dlg.m_level = m_nLevel;dlg.SetWriteFlg(TRUE);dlg.DoModal();}}

二、棋子类的设计

棋子类包含如下几个功能函数

1:游戏胜负判断处理

2:游戏升级处理

3:查找处理

4:提示处理

棋子类声明如下,包含两个构造函数,查找接口函数,判断棋子为空函数以及鼠标左键响应函数,代码如下

#if !defined(AFX_CHESSMAN_H__EB414A5E_D02A_4F89_ACE0_2187863ECEAD__INCLUDED_)#define AFX_CHESSMAN_H__EB414A5E_D02A_4F89_ACE0_2187863ECEAD__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// ChessMan.h : header file///// CChessMan windowclass CChessMan : public CButton{// Constructionpublic:CChessMan();CChessMan(int id, POINT pos);public:static BOOL FindTwoCorner(int map[][MAXY], POINT p1, POINT p2, POINT  *cross1, POINT *cross2);static BOOL FindCorner(int map[][MAXY], POINT p1, POINT p2, POINT *cross1);static BOOL Hint(int map[][MAXY], int* a1, int *a2);static BOOL Hint(int map[MAXX][MAXY]);static BOOL FindLine(int map[][MAXY], POINT p1, POINT p2);BOOL IsEmpty(int map[][MAXY]);BOOL Find(int map[MAXX][MAXY], POINT p1, POINT p2);BOOL Find(int map[MAXX][MAXY], POINT p1, POINT p2, POINT cross1, POINT cross2);static BOOL FindTwoCorner(int map[MAXX][MAXY], POINT p1, POINT p2);static BOOL FindCorner(int map[MAXX][MAXY], POINT p1, POINT p2);POINT m_pos;int m_id;virtual ~CChessMan();// Generated message map functionsprotected://{{AFX_MSG(CChessMan)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);//}}AFX_MSGDECLARE_MESSAGE_MAP()};///{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_LLKBUTTON_H__EB414A5E_D02A_4F89_ACE0_2187863ECEAD__INCLUDED_)

棋子类实现函数如下,包含基本的构造函数,析构函数,鼠标左键响应函数等等

// CChessMan.cpp : implementation file//#include "stdafx.h"#include "llk.h"#include "ChessMan.h"#include "LlkDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/// CChessManCChessMan::CChessMan(){}CChessMan::CChessMan(int id, POINT pos){m_id = id;m_pos = pos;}CChessMan::~CChessMan(){}BEGIN_MESSAGE_MAP(CChessMan, CButton)//{{AFX_MSG_MAP(CChessMan)ON_WM_LBUTTONDOWN()//}}AFX_MSG_MAPEND_MESSAGE_MAP()/// CChessMan message handlersBOOL CChessMan::FindLine(int map[][MAXY], POINT p1, POINT p2){int max, min;int i;if(p1.x == p2.x){max = (p1.y>p2.y)?p1.y:p2.y;min = (p1.y<p2.y)?p1.y:p2.y;if(max == min+1){return TRUE;//相邻的两个格子}for(i=min+1; i<max; i++){if((map[p1.x][i]!=0) && (map[p1.x][i]!=-1)){return FALSE;}}return TRUE;}if(p1.y == p2.y){max = (p1.x>p2.x)?p1.x:p2.x;min = (p1.x<p2.x)?p1.x:p2.x;if(max == min+1){return TRUE;//相邻的两个格子}for(i=min+1; i<max; i++){if((map[i][p1.y]!=0) && (map[i][p1.y]!=-1)){return FALSE;}}return TRUE;}return FALSE;}BOOL CChessMan::FindCorner(int map[][MAXY], POINT p1, POINT p2){int maxx, maxy, minx, miny;POINT tempPoint = {0};//测试矩形格子maxx = (p1.x>p2.x)?p1.x:p2.x;maxy = (p1.y>p2.y)?p1.y:p2.y;minx = (p1.x<p2.x)?p1.x:p2.x;miny = (p1.y<p2.y)?p1.y:p2.y;if(map[minx][maxy] == 0){tempPoint.x = minx;tempPoint.y = maxy;if((FindLine(map, p1, tempPoint)) &&(FindLine(map, tempPoint, p2))){return TRUE;}}if(map[maxx][miny] == 0){tempPoint.x = maxx;tempPoint.y = miny;if((FindLine(map, p1, tempPoint))&& (FindLine(map, tempPoint, p2))){return TRUE;}}if(map[minx][miny] == 0){tempPoint.x = minx;tempPoint.y = miny;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){return TRUE;}}if(map[maxx][maxy] == 0){tempPoint.x = maxx;tempPoint.y = maxy;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){return TRUE;}}return FALSE;}BOOL CChessMan::FindCorner(int map[][MAXY], POINT p1, POINT p2, POINT *cross1){int maxx, maxy, minx, miny;POINT tempPoint = {0};//测试矩形格子maxx = (p1.x>p2.x)?p1.x:p2.x;maxy = (p1.y>p2.y)?p1.y:p2.y;minx = (p1.x<p2.x)?p1.x:p2.x;miny = (p1.y<p2.y)?p1.y:p2.y;if(map[minx][maxy] == 0){tempPoint.x = minx;tempPoint.y = maxy;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){cross1->x = tempPoint.x;cross1->y = tempPoint.y;return TRUE;}}if(map[maxx][miny] == 0){tempPoint.x = maxx;tempPoint.y = miny;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){cross1->x = tempPoint.x;cross1->y = tempPoint.y;return TRUE;}}if(map[minx][miny] == 0){tempPoint.x = minx;tempPoint.y = miny;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){cross1->x = tempPoint.x;cross1->y = tempPoint.y;return TRUE;}}if(map[maxx][maxy] == 0){tempPoint.x = maxx;tempPoint.y = maxy;if((FindLine(map, p1, tempPoint)) && (FindLine(map, tempPoint, p2))){cross1->x = tempPoint.x;cross1->y = tempPoint.y;return TRUE;}}return FALSE;}BOOL CChessMan::FindTwoCorner(int map[][MAXY], POINT p1, POINT p2){int i;POINT tempPoint = {0};//纵向for(i=0; i<MAXY; i++){if(i == p1.y){continue;}tempPoint.x = p1.x;tempPoint.y = i;if((map[tempPoint.x][tempPoint.y]==0) || (map[tempPoint.x][tempPoint.y]==-1)){if(FindLine(map, tempPoint, p1)){tempPoint.x = p2.x;if((map[tempPoint.x][tempPoint.y]==0) || (map[tempPoint.x][tempPoint.y]==-1)){if(FindLine(map, tempPoint, p2)){return TRUE;}}}}}//横向for(i=0; i<MAXX; i++){if(i == p1.x)continue;tempPoint.x = i;tempPoint.y = p1.y;if((map[tempPoint.x][tempPoint.y]==0) || (map[tempPoint.x][tempPoint.y]==-1)){if(FindLine(map, tempPoint, p1)){tempPoint.y = p2.y;if((map[tempPoint.x][tempPoint.y]==0) || (map[tempPoint.x][tempPoint.y]==-1)){if(FindLine(map, tempPoint, p2)){return TRUE;}}}}}return FALSE;}BOOL CChessMan::FindTwoCorner(int map[][MAXY], POINT p1, POINT p2, POINT *cross1, POINT *cross2){int i;POINT tempPoint1 = {0};POINT tempPoint2 = {0};//横向for(i=0; i<MAXY; i++){if(i == p1.y)continue;tempPoint1.x = p1.x;tempPoint1.y = i;if((map[tempPoint1.x][tempPoint1.y]==0) || (map[tempPoint1.x][tempPoint1.y]==-1)){if(FindLine(map, tempPoint1, p1)){tempPoint2.x = p2.x;tempPoint2.y = i;if((map[tempPoint2.x][tempPoint2.y]==0) || (map[tempPoint2.x][tempPoint2.y]==-1)){if(FindLine(map, tempPoint2, p2)){//判断两个转折点是否连通!!!if(FindLine(map, tempPoint1, tempPoint2)){cross1->x = p1.x;cross1->y = i;cross2->x = p2.x;cross2->y = i;return TRUE;}}}}}}//纵向for(i=0; i<MAXX; i++){if(i == p1.x)continue;tempPoint1.x = i;tempPoint1.y = p1.y;if((map[tempPoint1.x][tempPoint1.y]==0) || (map[tempPoint1.x][tempPoint1.y]==-1)){if(FindLine(map, tempPoint1, p1)){tempPoint2.x = i;tempPoint2.y = p2.y;if((map[tempPoint2.x][tempPoint2.y]==0) || (map[tempPoint2.x][tempPoint2.y]==-1)){if(FindLine(map, tempPoint2, p2)){//判断两个转折点是否连通!!!if(FindLine(map, tempPoint1, tempPoint2)){cross1->x = i;cross1->y = p1.y;cross2->x = i;cross2->y = p2.y;return TRUE;}}}}}}return FALSE;}BOOL CChessMan::Find(int map[MAXX][MAXY], POINT p1, POINT p2){CLlkDlg *parent = (CLlkDlg *)GetParent();CString str;if(FindLine(map, p1, p2)){str.Format("直线:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);return TRUE;}if(FindCorner(map, p1, p2)){str.Format("一拐角:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);return TRUE;}if(FindTwoCorner(map, p1, p2)){str.Format("两拐角:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);return TRUE;}return FALSE;}BOOL CChessMan::Find(int map[][MAXY],  POINT p1, POINT p2,  POINT cross1, POINT cross2){CLlkDlg *parent = (CLlkDlg *)GetParent();parent->m_line.m_src1 = p1;parent->m_line.m_src2 = p2;CString str;if(FindLine(map, p1, p2)){str.Format("直线:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);parent->m_line.m_lineNum = 1;return TRUE;}if(FindCorner(map, p1, p2, &(parent->m_line.m_crossP1))){str.Format("一拐角:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);parent->m_line.m_lineNum = 2;return TRUE;}if(FindTwoCorner(map, p1, p2, &(parent->m_line.m_crossP1), &(parent->m_line.m_crossP2))){str.Format("两拐角:(%d,%d)->(%d,%d)\n", p1.x, p1.y, p2.x, p2.y);parent->m_method.SetWindowText(str);parent->m_line.m_lineNum = 3;return TRUE;}return FALSE;}BOOL CChessMan::IsEmpty(int map[][MAXY]){ int i, j; int sum = 0;  for(i=1; i<MAXX-1; i++) for(j=1; j<MAXY-1; j++) sum += map[i][j]; if(sum) return FALSE; else return TRUE;}BOOL CChessMan::Hint(int map[][MAXY]){int x1, y1, x2, y2;POINT p1 = {0};POINT p2 = {0};for(x1=1; x1<MAXX-1; x1++){for(y1=1; y1<MAXY-1; y1++){for(x2=1; x2<MAXX-1; x2++){for(y2=1; y2<MAXY-1; y2++){p1.x = x1;p1.y = y1;p2.x = x2;p2.y = y2;if((map[x1][y1]==0) || (map[x2][y2]==0)){//空白格子continue;}if(map[x1][y1] != map[x2][y2]){//不相等continue;}if((x1==x2) && (y1==y2)){//同一个点continue;}if(FindLine(map, p1, p2)){return TRUE;}if(FindCorner(map, p1, p2)){return TRUE;}if(FindTwoCorner(map, p1, p2)){return TRUE;}}}}}return FALSE;}BOOL CChessMan::Hint(int map[][MAXY], int *a1, int *a2){int x1, y1, x2, y2;POINT p1 = {0};POINT p2 = {0};for(x1=1; x1<MAXX-1; x1++){for(y1=1; y1<MAXY-1; y1++){for(x2=1; x2<MAXX-1; x2++){for(y2=1; y2<MAXY-1; y2++){p1.x = x1;p1.y = y1;p2.x = x2;p2.y = y2;if((map[x1][y1]==0) || (map[x2][y2]==0)){//空白格子continue;}if(map[x1][y1] != map[x2][y2]){//不相等continue;}if((x1==x2) && (y1==y2)){//同一个点continue;}if(FindLine(map, p1, p2)){*a1 = (x1-1) * (MAXY-2) + y1 - 1;*a2 = (x2-1) * (MAXY-2) + y2 - 1;return TRUE;}if(FindCorner(map, p1, p2)){*a1 = (x1-1) * (MAXY-2) + y1 - 1;*a2 = (x2-1) * (MAXY-2) + y2 - 1;return TRUE;}if(FindTwoCorner(map, p1, p2)){*a1 = (x1-1) * (MAXY-2) + y1 - 1;*a2 = (x2-1) * (MAXY-2) + y2 - 1;return TRUE;}}}}}return FALSE;}void CChessMan::OnLButtonDown(UINT nFlags, CPoint point) //用此事件可以加快响应速度(不用Clicked事件){SetButtonStyle(BS_DEFPUSHBUTTON);//显示黑边框CLlkDlg *parent = (CLlkDlg *)GetParent();if((parent->m_p==NULL) || (parent->m_p->m_id!=m_id)|| ((parent->m_p->m_pos.x==m_pos.x)&&(parent->m_p->m_pos.y==m_pos.y))){parent->m_p = this;if(parent->m_line.m_lineNum != 0){parent->m_line.m_lineNum = 0;parent->RefreshMap();parent->m_line.Invalidate();}}else {if(Find(parent->map, parent->m_p->m_pos, m_pos, parent->m_line.m_crossP1, parent->m_line.m_crossP2)){//消去parent->map[parent->m_p->m_pos.x][parent->m_p->m_pos.y] = 0;parent->map[m_pos.x][m_pos.y] = 0;//不能用delete!!!否则重新开始时无法清除原有按钮parent->m_p->ShowWindow(SW_HIDE);this->ShowWindow(SW_HIDE);parent->RefreshMap();parent->m_line.Invalidate();parent->m_p = NULL;parent->m_timePoint += 3;//增加时间点//画时间条parent->InvalidateRgn(&(parent->m_MsgRgn));if(IsEmpty(parent->map))//是否消完{int ret = MessageBox("过关拉!要挑战下一关吗?", "恭喜你!", MB_ICONINFORMATION|MB_OKCANCEL);if(ret == IDOK){parent->Start(++(parent->m_nLevel));}else{for(int i=0; i<(MAXX-2)*(MAXY-2); i++){delete (CChessMan *)parent->m_cmGroup.GetAt(i);}parent->isHighLevel();//结束游戏时,调用等级判断函数parent->DestroyWindow();}}if(!Hint(parent->map))//是否无处可消{parent->m_exchangeNum++;parent->CallExchange();parent->m_method.SetWindowText("无可用消除!自动切换!");}}else{parent->m_p = this;}}}

实现效果如下 

 

 

 创作不易 觉得有帮助请点赞关注收藏~~~


点击全文阅读


本文链接:http://zhangshiyu.com/post/57018.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1