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

📄 minecrackdlg.cpp

📁 Windows XP/2000/NT 中扫雷的外挂程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if ( m_nWidth == 30 && m_nHeight == 16 )
			m_nMineNum = 99;
		else if ( m_nWidth == 16 && m_nHeight == 16 )
			m_nMineNum = 40;
		else if ( m_nWidth == 9 && m_nHeight == 9 )
			m_nMineNum = 10;
		else{
			MessageBox("本程序不支持自定义雷区!", NULL, MB_OK | MB_ICONINFORMATION);
			return;
		}

	}
	
	if (m_map) {
		delete m_map;
		m_map = NULL;
	}
	m_map = new BYTE[ m_nWidth*m_nHeight ];
	ZeroMemory(m_map, m_nWidth*m_nHeight);
	
	::PostMessage(hWinMineWnd,WM_KEYDOWN,VK_F2,0);
	m_nMineCurNum = 0;
	m_bStart = TRUE;

	m_hook.StartMouseHook( GetSafeHwnd() );
}

void CMineCrackDlg::OnBtstart() 
{
	// TODO: Add your control notification handler code here
	StartGame();
}

BOOL CMineCrackDlg::ScanTheMap()
{
	int i, j, ret;
	CPoint pt; 
	BOOL finish = FALSE;

	for (i=0; i<m_nHeight; i++)
	{
		for(j=0; j<m_nWidth; j++)
		{
			if (m_map[ i*m_nWidth + j ] != 0) continue;
			pt = CPoint( 12 + j*BMPWIDTH, 55 + i*BMPHEIGHT + 7 );	//坐标从上至下;
			ret = GetColorSample(pt);
			switch(ret) 
			{
			case 0:	m_map[ i*m_nWidth + j ] = NOMINE; break;
			case 1:	m_map[ i*m_nWidth + j ] = NEIGHBOR_1; break;
			case 2:	m_map[ i*m_nWidth + j ] = NEIGHBOR_2; break;
			case 3:	m_map[ i*m_nWidth + j ] = NEIGHBOR_3; break;
			case 4:	m_map[ i*m_nWidth + j ] = NEIGHBOR_4; break;
			case 5:	m_map[ i*m_nWidth + j ] = NEIGHBOR_5; break;
			case 6:	m_map[ i*m_nWidth + j ] = NEIGHBOR_6; break;
			case 7:	m_map[ i*m_nWidth + j ] = NEIGHBOR_7; break;
			case 8:	m_map[ i*m_nWidth + j ] = NEIGHBOR_8; break;
			case 9:	m_map[ i*m_nWidth + j ] = NOMINE; break;
			case 10: finish = TRUE; break;
			case 11: finish = TRUE; break;
			case 12: finish = TRUE; break;
			case 13: m_map[ i*m_nWidth + j ] = UNKNOW; break;
			case 14: m_map[ i*m_nWidth + j ] = ISMINE; break;	
			case 15: m_map[ i*m_nWidth + j ] = UNKNOW; break;
			}
		}
	}
	if ( finish ) return FALSE;
	else return TRUE;
}

BOOL CMineCrackDlg::ScanTheMap98()
{
	return FALSE;
}

int CMineCrackDlg::GetColorSample(CPoint pt)
{
	BYTE ptrColor[8];
	COLORREF colorref1,colorref2;
	int i;
	
	HDC	hDC = ::GetDC(NULL);

	memset(ptrColor, 0, 8);
	::ClientToScreen(hWinMineWnd,&pt);

	for(i=0; i<8; i++)
	{
		colorref1=::GetPixel(hDC, pt.x+i*2, pt.y);
		colorref2=::GetPixel(hDC, pt.x+i*2+1, pt.y);
		BYTE tmp1 = Color256To16(colorref1);
		BYTE tmp2 = Color256To16(colorref2);
		ptrColor[i] = tmp1<<4 | tmp2;
	}

	::ReleaseDC(NULL,hDC);	

	for(i=0; i<16; i++)
		if ( m_ColorSample[i][0] == ptrColor[0] && 
			 m_ColorSample[i][1] == ptrColor[1] && 
			 m_ColorSample[i][2] == ptrColor[2] && 
			 m_ColorSample[i][3] == ptrColor[3] &&
			 m_ColorSample[i][4] == ptrColor[4] && 
			 m_ColorSample[i][5] == ptrColor[5] && 
			 m_ColorSample[i][6] == ptrColor[6] && 
			 m_ColorSample[i][7] == ptrColor[7] ) 
		{
			return i; //返回匹配值
		}
		
		return -1;	//没有匹配
		
}

BYTE CMineCrackDlg::Color256To16(COLORREF colorref)
{
	BYTE ret;
	switch( colorref )
	{
	case RGB(  0,   0,   0): ret = 0x00; break;
	case RGB(128,   0,   0): ret = 0x01; break;
	case RGB(  0, 128,   0): ret = 0x02; break;
	case RGB(128, 128,   0): ret = 0x03; break;
	case RGB(  0,   0, 128): ret = 0x04; break;
	case RGB(128,   0, 128): ret = 0x05; break;
	case RGB(  0, 128, 128): ret = 0x06; break;
	case RGB(128, 128, 128): ret = 0x07; break;
	case RGB(192, 192, 192): ret = 0x08; break;
	case RGB(255,   0,   0): ret = 0x09; break;
	case RGB(  0, 255,   0): ret = 0x0A; break;
	case RGB(255, 255,   0): ret = 0x0B; break;
	case RGB(  0,   0, 255): ret = 0x0C; break;
	case RGB(255,   0, 255): ret = 0x0D; break;
	case RGB(  0, 255, 255): ret = 0x0E; break;
	case RGB(255, 255, 255): ret = 0x0F; break;
	}
	return ret;
}

BOOL CMineCrackDlg::MakeDecision(BOOL * bSign, BOOL * bStatus)
{
	int i, j, k, curMineCount = 0;
	
	for ( i=0; i<m_nHeight; i++ )
	{
		for ( j=0; j<m_nWidth; j++ )
		{
			if ( m_map[i*m_nWidth + j] == ISMINE ) { curMineCount++; continue; }
			if ( m_map[i*m_nWidth + j] < NEIGHBOR_1 || m_map[i*m_nWidth + j] > NEIGHBOR_8 ) continue;
			
			//计算数字方格(i,j)周围的8个方格中,有多少个未标记的方格;
			CArray < CPoint, CPoint > ArrayOfCenPt; 
			int isMineNumOfCenPt = 0; 
			
			LookAroundDot(i, j, &ArrayOfCenPt, &isMineNumOfCenPt);
			
			if ( ! ArrayOfCenPt.GetSize() ) continue;

			//如果方格(i,j)周围的未标记方格数 = 方格(i,j)本身显示雷数值 - 周围已标记是雷的方格数
			if ( ArrayOfCenPt.GetSize() == m_map[i*m_nWidth + j] - isMineNumOfCenPt )
			{
				for ( k=0; k<ArrayOfCenPt.GetSize(); k++ )
				{
					//从数组中将点取出,给每个点标记“是雷”的标志
					::PostMessage( hWinMineWnd, WM_RBUTTONDOWN, MK_RBUTTON,
						MAKELPARAM(12+ArrayOfCenPt[k].y*BMPWIDTH+8, 55+ArrayOfCenPt[k].x*BMPHEIGHT+8) );
					m_map[ ArrayOfCenPt[k].x * m_nWidth + ArrayOfCenPt[k].y ] = ISMINE;
				}
				( *bSign ) = TRUE;
			}
			
			if ( m_map[i*m_nWidth + j] == isMineNumOfCenPt )
			{
				::PostMessage( hWinMineWnd, WM_LBUTTONDOWN, MK_LBUTTON | MK_RBUTTON,
					MAKELPARAM(12+j*BMPWIDTH+8, 55+i*BMPHEIGHT+8) );
				::PostMessage( hWinMineWnd, WM_RBUTTONUP, 0,
					MAKELPARAM(12+j*BMPWIDTH+8, 55+i*BMPHEIGHT+8) );
				( *bStatus ) = TRUE;
			}
		}	
	}

	if ( m_nMineNum == curMineCount )
	{
		for ( i=0; i<m_nHeight; i++ )
		{
			for ( j=0; j<m_nWidth; j++ )
			{
				if ( m_map[i*m_nWidth + j] == UNKNOW )
				{
					::PostMessage( hWinMineWnd, WM_LBUTTONDOWN, MK_LBUTTON,
						MAKELPARAM(12+j*BMPWIDTH+8, 55+i*BMPHEIGHT+8) );
					::PostMessage( hWinMineWnd, WM_LBUTTONUP, 0,
						MAKELPARAM(12+j*BMPWIDTH+8, 55+i*BMPHEIGHT+8) );
				}
			}
		}
		return TRUE;
	} else m_nMineCurNum = curMineCount;
	
	return FALSE;
}

//在普通决策(bSign == FALSE && bStatus == FALSE)条件下调用高级决策
BOOL CMineCrackDlg::AdvanceDecision(BOOL * bSign, BOOL * bStatus)
{
	int i, j, i1, j1, k, curMineCount = 0;
	
	for ( i=0; i<m_nHeight; i++ )
	{
		for ( j=0; j<m_nWidth; j++ )
		{
			if ( m_map[i*m_nWidth + j] < NEIGHBOR_1 || m_map[i*m_nWidth + j] > NEIGHBOR_8 ) continue;

			//计算方格(i, j)周围3×3区域中有多少个雷区和未标示区
			CArray < CPoint, CPoint > ArrayOfCenPt; 
			int isMineNumOfCenPt = 0; 

			LookAroundDot(i, j, &ArrayOfCenPt, &isMineNumOfCenPt);
			
			if ( ArrayOfCenPt.GetSize() == 0 ) continue;  //周围没有未标示区
			
			ASSERT( ArrayOfCenPt.GetSize() != 1 );	//在高级决策下这种情况不存在

			if ( ArrayOfCenPt.GetSize() == 2 )	//如果周围只有两个未标示区,则无法进行高级决策
			{
				ASSERT( m_map[i*m_nWidth + j] == isMineNumOfCenPt + 1 );
				continue;
			}

/*……得到了方格(i, j)周围已标示雷区点的个数isMineNumOfCenPt和
	  未标示区点的数组ArrayOfCenPt后,对方格(i, j)周围5×5区域进行扫描……*/
			
			int xx1, xx2, yy1, yy2;
			
			if ( i-2 >= 0 ) xx1 = i-2;
			else if ( i-1 >= 0 ) xx1 = i-1;
			else xx1 = i;
			
			if ( i+2 <= m_nHeight-1 ) xx2 = i+2;
			else if ( i+1 <= m_nHeight-1 ) xx2 = i+1;
			else xx2 = i;
			
			if ( j-2 >= 0 ) yy1 = j-2;
			else if ( j-1 >= 0 ) yy1 = j-1;
			else yy1 = j;
			
			if ( j+2 <= m_nWidth-1 ) yy2 = j+2;
			else if ( j+1 <= m_nWidth-1 ) yy2 = j+1;
			else yy2 = j;
			
			for ( i1=xx1; i1<=xx2; i1++ )
			{
				for ( j1=yy1; j1<=yy2; j1++ )
				{
					//对方格(i, j)自身不考察
					if ( i1==i && j1==j ) continue;	
					//对方格(i, j)周围5×5区域中标示为非数字方块不考察
					if ( m_map[i1*m_nWidth + j1] < NEIGHBOR_1 || m_map[i1*m_nWidth + j1] > NEIGHBOR_8 ) continue;
					
					CArray < CPoint, CPoint > ArrayOfArdPt; 
					int isMineNumOfArdPt = 0; 
					LookAroundDot( i1, j1, &ArrayOfArdPt, &isMineNumOfArdPt);
					
					if ( !ArrayOfArdPt.GetSize() ) continue; //若该点周围没有未标示方块

					CArray < int ,int > indexArray;
					BOOL haveOther = FALSE;
					for (k=0; k<ArrayOfArdPt.GetSize(); k++)
					{
						int retindex = LookUpFromArray( &ArrayOfCenPt, ArrayOfArdPt.GetAt(k) );
						if ( retindex >= 0 ) indexArray.Add(retindex);
						else if ( retindex == -1 ) haveOther = TRUE;
					}

					if ( !haveOther ) 
						ASSERT( indexArray.GetSize() != 1 );	//等于1的情况在MakeDecision()函数中处理过了
					if ( indexArray.GetSize() < 2 ) continue;	//若没有或有一个共同的未标示方格
					
					//CommonMineNum:两个点之间公共的未标示区域中包括的雷数
					int CommonMineNum = m_map[i1*m_nWidth + j1] - isMineNumOfArdPt;
					
					int leaveUnknowDot = ArrayOfCenPt.GetSize() - indexArray.GetSize();

					if ( !leaveUnknowDot ) continue;

					if (m_map[i*m_nWidth + j] - isMineNumOfCenPt - CommonMineNum == leaveUnknowDot)
					{	//剩下的未标示方格全为雷,标记
						for ( k=0; k<ArrayOfCenPt.GetSize(); k++ )
						{
							int retindex = LookUpFromArray( &ArrayOfArdPt, ArrayOfCenPt.GetAt(k) );
							if ( retindex == -1 )
							{
								::PostMessage( hWinMineWnd, WM_RBUTTONDOWN, MK_RBUTTON,
									MAKELPARAM(12+ArrayOfCenPt[k].y*BMPWIDTH+8, 55+ArrayOfCenPt[k].x*BMPHEIGHT+8) );
								m_map[ ArrayOfCenPt[k].x * m_nWidth + ArrayOfCenPt[k].y ] = ISMINE;
							}
						}
						( *bSign ) = TRUE;
						return TRUE;
					}
						
					if (m_map[i*m_nWidth + j] - isMineNumOfCenPt == CommonMineNum && haveOther == FALSE )	
					{	//剩下的方格全不是雷,点开		ps:haveOther=FALSE,必然事件;haveOther=TRUE,最大可能事件
						for ( k=0; k<ArrayOfCenPt.GetSize(); k++ )
						{
							int retindex = LookUpFromArray( &ArrayOfArdPt, ArrayOfCenPt.GetAt(k) );
							if ( retindex == -1 )
							{
								::PostMessage( hWinMineWnd, WM_LBUTTONDOWN, MK_LBUTTON,
									MAKELPARAM(12+ArrayOfCenPt[k].y*BMPWIDTH+8, 55+ArrayOfCenPt[k].x*BMPHEIGHT+8) );
								::PostMessage( hWinMineWnd, WM_LBUTTONUP, 0,
									MAKELPARAM(12+ArrayOfCenPt[k].y*BMPWIDTH+8, 55+ArrayOfCenPt[k].x*BMPHEIGHT+8) );
							}
						}
						( *bStatus ) = TRUE;
						return TRUE;
					}
				}
			}
		}
	}

	return FALSE;
}

void CMineCrackDlg::LookAroundDot(int i, int j, void * ptrarr, int * isMine)
{
	CArray < CPoint, CPoint > * ptrArray = ( CArray < CPoint, CPoint > * )ptrarr;
	
	int i1, j1;
	for ( i-1>=0 ? i1=i-1 : i1=i; i+1<=m_nHeight-1 ? i1<=i+1 : i1<=i; i1++ )	
	{
		for ( j-1>=0 ? j1=j-1 : j1=j; j+1<=m_nWidth-1 ? j1<=j+1 : j1<=j; j1++ )
		{
			if ( i1==i && j1==j ) 
			{
				ASSERT( m_map[i*m_nWidth + j] != 0 );
				continue;
			}
			if ( !m_map[i1*m_nWidth + j1] )	
			{
				CPoint pt = CPoint(i1, j1);
				ptrArray->Add(pt);
			} 
			else if ( m_map[i1*m_nWidth + j1] == ISMINE ) (* isMine)++;	
		}
	}
}

int CMineCrackDlg::LookUpFromArray(const void * ptrarr, CPoint pt)
{
	CArray < CPoint, CPoint > * ptrArray = ( CArray < CPoint, CPoint > * )ptrarr;

	for ( int i=0; i<ptrArray->GetSize(); i++ )
		if ( (* ptrArray)[i] == pt ) return i;
	
	return -1;
}

void CMineCrackDlg::OnBtsweepmine() 
{
	// TODO: Add your control notification handler code here
	
	if ( ! m_bStart )
	{
		MessageBox("先点击开始按钮!", NULL, MB_OK | MB_ICONINFORMATION);
		return;
	}

	if(::IsIconic(hWinMineWnd))	::ShowWindow(hWinMineWnd,SW_SHOWNORMAL);
	::BringWindowToTop(hWinMineWnd);
	::SetActiveWindow(hWinMineWnd);
	
	BOOL DoScan = TRUE;
	while ( TRUE )
	{
		Sleep(20); 
		if ( DoScan )
		{
			if( !ScanTheMap() )
			{
				m_bStart = FALSE;
				ASSERT( m_map !=NULL );
				delete m_map;
				m_map = NULL;
				MessageBox("扫雷失败了,GAME OVER!", NULL, MB_OK | MB_ICONINFORMATION);
				break;
			}
		} 
		else DoScan = TRUE;
		
		BOOL bSign = FALSE, bStatus = FALSE;
		
		BOOL bSuccess = MakeDecision( & bSign, & bStatus );
		
		if ( bSuccess )
		{
			m_bStart = FALSE;
			ASSERT( m_map !=NULL );
			delete m_map;
			m_map = NULL;
			MessageBox("恭喜啊,扫雷成功了!", NULL, MB_OK | MB_ICONINFORMATION); 
			break;
		}
		
		if ( bSign == FALSE && bStatus == FALSE ) 
		{
			BOOL improve = AdvanceDecision( & bSign, & bStatus );
			if ( ! improve ) 
			{
				MessageBox("算法不能继续了,自己来吧!", NULL, MB_OK | MB_ICONINFORMATION);
				::BringWindowToTop(hWinMineWnd);
				::SetActiveWindow(hWinMineWnd);
				break;
			}
		}

		if ( bStatus ) continue;
		if ( bSign ) DoScan = FALSE;
	}
}

void CMineCrackDlg::OnOK() 
{
	// TODO: Add extra validation here
	
	CDialog::OnOK();
}

void CMineCrackDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	CDialog::OnCancel();
}

void CMineCrackDlg::OnAbout() 
{
	// TODO: Add your control notification handler code here
	CAboutDlg dlg;
	dlg.DoModal();
}

BOOL CMineCrackDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
	// TODO: Add your message handler code here and/or call default
	static BOOL bDown = FALSE;
	MsgMouse * pMsg;
	pMsg = (MsgMouse *) (pCopyDataStruct->lpData);
	CPoint pt = pMsg->pt;
	::ScreenToClient(hWinMineWnd,&pt);
	
	if (pt.x>239 && pt.x<264 && pt.y>15 && pt.y<40  ) 
	{
		if ( pMsg->KeyValue == WM_LBUTTONDOWN ) bDown = TRUE;
		if ( pMsg->KeyValue == WM_LBUTTONUP && bDown )
		{
			StartGame();
			bDown = FALSE;
		}
	}
	if ( pMsg->KeyValue == WM_LBUTTONUP && bDown )  bDown = FALSE;

	return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}


⌨️ 快捷键说明

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