| CMinerBitmapAnalyzer | 비트맵을 분석, 데이터화한다. |
| CMinerController | 지뢰찾기 프로그램에 대한 화면 캡쳐, 모드변환, 버튼 클릭 등의 제어를 한다 |
| CMineSweeper | 실질적인 두뇌에 해당되는 부분. CMinerController 와 CMinerBitampAnalyzer 를 멤버로 가지며, 이를 이용하여 게임상황분석, 지뢰찾기관련 판단 등을 한다 |
~cpp
void CMinerFinderDlg::OnButtonStart()
{
// TODO: Add your control notification handler code here
m_mineSweeper.Start ();
SetTimer (1000, 100, NULL);
}
void CMinerFinderDlg::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
int nRet = Excute ();
if (nRet == MINERMODE_CLEAR)
KillTimer (1000);
CDialog::OnTimer(nIDEvent);
}
void CMinerFinderDlg::OnButtonStop()
{
// TODO: Add your control notification handler code here
KillTimer (1000);
}
int CMinerFinderDlg::Excute ()
{
return m_mineSweeper.Excute ();
}
~cpp
int CMineSweeper::Excute ()
{
CBitmap* pBitmap = CaptureClient ();
ConvertBitmapToGameMode (pBitmap);
ConvertBitmapToData (pBitmap);
if (m_nCurrentGameMode == MINERMODE_GAMEOVER) {
Start ();
return m_nCurrentGameMode;
}
// Todo : Matrix 를 근거로 하여 할 일의 설정.
// 할 일 :
int nRet = 0;
CMinerFinderDlg* pDlg = (CMinerFinderDlg*)m_pDlg;
// Flag 의 체크. 횟수세기.
nRet = CheckFlag ();
if (nRet) {
pDlg->PrintStatus ("Action : CheckFlag - %d rn", nRet);
return m_nCurrentGameMode;
}
// Open. 횟수세기.
nRet = OpenBlocks ();
if (nRet) {
pDlg->PrintStatus ("Action : OpenBlocks - %d rn", nRet);
return m_nCurrentGameMode;
}
// 찍기. --;
RandomOpen ();
pDlg->PrintStatus ("Action : Random Open rn");
return m_nCurrentGameMode;
}
~cpp
Profile: Function timing, sorted by time
Date: Tue Feb 26 19:16:26 2002
Program Statistics
------------------
Command line at 2002 Feb 26 19:00: "F:WorkingTempMinerFinderDebugMinerFinder"
Total time: 223521.679 millisecond
Time outside of functions: 28.613 millisecond
Call depth: 23
Total functions: 660
Total hits: 37532338
Function coverage: 52.1%
Overhead Calculated 5
Overhead Average 5
Module Statistics for minerfinder.exe
-------------------------------------
Time in module: 223493.066 millisecond
Percent of time in module: 100.0%
Functions in module: 660
Hits in module: 37532338
Module function coverage: 52.1%
Func Func+Child Hit
Time % Time % Count Function
---------------------------------------------------------
86270.513 38.6 86270.513 38.6 18252086 CDC::GetPixel(int,int) (mfc42d.dll)
53966.631 24.1 223296.921 99.9 855 CWinThread::PumpMessage(void) (mfc42d.dll)
28819.313 12.9 150892.058 67.5 93243 CMinerBitmapAnalyzer::CompareBitmapBlock(class CDC *,class CDC *,int,int,int,int,class CDC *,int,int) (minerbitmapanalyzer.obj)
18225.064 8.2 61776.601 27.6 9126043 CMinerBitmapAnalyzer::CompareBitmapPixel(class CDC *,class CDC *,int,int,unsigned long) (minerbitmapanalyzer.obj)
17577.168 7.9 17577.168 7.9 9126043 CDC::SetPixel(int,int,unsigned long) (mfc42d.dll)
5146.101 2.3 53721.330 24.0 104 CMineSweeper::CheckFlag(void) (minesweeper.obj)
4748.690 2.1 4974.806 2.2 74 CMineSweeper::OpenBlocks(void) (minesweeper.obj)
2496.582 1.1 2506.333 1.1 27 CMineSweeper::RandomOpen(void) (minesweeper.obj)
1504.775 0.7 1504.775 0.7 85245 CDC::DeleteDC(void) (mfc42d.dll)
944.596 0.4 944.596 0.4 85245 CDC::CreateCompatibleDC(class CDC *) (mfc42d.dll)
492.930 0.2 111257.841 49.8 32492 CMinerBitmapAnalyzer::ConvertBitmapToBlock(int,int) (minerbitmapanalyzer.obj)
383.392 0.2 383.392 0.2 85245 CDC::SelectObject(class CBitmap *) (mfc42d.dll)
348.243 0.2 348.243 0.2 42702 CWnd::ReleaseDC(class CDC *) (mfc42d.dll)
326.552 0.1 326.552 0.1 221 CWnd::SetWindowTextA(char const *) (mfc42d.dll)
294.378 0.1 295.578 0.1 2619 CWnd::DefWindowProcA(unsigned int,unsigned int,long) (mfc42d.dll)
251.949 0.1 251.949 0.1 42702 CWnd::GetDC(void) (mfc42d.dll)
201.741 0.1 225.112 0.1 221 CEdit::LineScroll(int,int) (mfc42d.dll)
184.900 0.1 184.900 0.1 208404 CMineSweeper::GetData(int,int) (minesweeper.obj)
155.178 0.1 42649.225 19.1 9944 CMinerBitmapAnalyzer::ConvertBitmapToNumber(int,int) (minerbitmapanalyzer.obj)
134.201 0.1 154139.803 69.0 157 CMineSweeper::ConvertBitmapToData(class CBitmap *) (minesweeper.obj)
~cpp Searching for 'GetPixel'... F:WorkingTempMinerFinderMinerBitmapAnalyzer.cpp(65): if (bmpdc->GetPixel (bmpStartX,bmpStartY) != rgbColor) F:WorkingTempMinerFinderMinerBitmapAnalyzer.cpp(135): rgb = screendc->GetPixel (nX+nBi,nY+nBj); 2 occurrence(s) have been found.
~cpp
BOOL CMinerBitmapAnalyzer::CompareBitmapPixel (CDC* pDC, CDC* bmpdc, int bmpStartX, int bmpStartY, COLORREF rgbColor)
{
if (bmpdc->GetPixel (bmpStartX,bmpStartY) != rgbColor)
return FALSE;
else
return TRUE;
}
BOOL CMinerBitmapAnalyzer::CompareBitmapBlock (CDC* pDC, CDC* screendc, int nX, int nY, int nWidth, int nHeight, CDC* bmpdc, int nSrcX, int nSrcY)
{
int nBi, nBj;
COLORREF rgb;
for (nBi=0;nBi<nWidth;nBi++) {
for (nBj=0;nBj<nHeight;nBj++) {
rgb = screendc->GetPixel (nX+nBi,nY+nBj);
pDC->SetPixel (nX+nBi,nY+nBj,rgb);
if (!CompareBitmapPixel (pDC, bmpdc, nSrcX + nBi, nSrcY + nBj, rgb)) return FALSE;
}
}
return TRUE;
}
즉, 저 함수들을 최적화 시키던지, 아니면 저 함수들이 호출되는 횟수를 줄여야 하는 것이다.
~cpp
BOOL CMinerBitmapAnalyzer::CompareBitmapCenterLine (CDC* screendc, int nX, int nY, int nWidth, int nHeight, CDC* bmpdc, int nSrcX, int nSrcY)
{
int nBi, nBj;
COLORREF rgb;
nBj = int(nHeight / 2);
// for optimizing...
for (nBi=int(nWidth / 4);nBi<nWidth-int(nWidth / 4);nBi++) {
rgb = screendc->GetPixel (nX+nBi,nY+nBj);
if (!CompareBitmapPixel (bmpdc, nSrcX + nBi, nSrcY + nBj, rgb)) return FALSE;
}
return TRUE;
}
~cpp
int CMineSweeper::CheckFlag ()
{
int nCount = 0;
int nCheckCount = 0;
CMinerFinderDlg* pDlg = (CMinerFinderDlg*)m_pDlg;
for (int i=0;i<m_nArrMaxY;i++) {
for (int j=0;j<m_nArrMaxX;j++) {
if (IsNumber (GetData (j,i))) {
// 숫자인 경우.
nCount = GetAroundClosedCount (j,i) + GetAroundFlagCount (j,i);
if (nCount == GetData(j,i) && GetAroundClosedCount (j,i)) {
SetFlagsAround (j,i);
// CBitmap* pBitmap = CaptureClient ();
// ConvertBitmapToData (pBitmap);
nCheckCount ++;
}
}
}
}
return nCheckCount;
}
제가 한 비트맵 데이터 추출 방법은 일반적인 윈도우 캡처 프로그램의 원리와 비슷합니다. FindWindow 를 이용, 지뢰찾기 프로그램의 윈도우 핸들을 얻은뒤, 이를 가지고 해당 윈도우의 비트맵을 얻어내는 것이지요. 기타 제작 과정과 아이디어는 MineFinder 페이지에 서술해놓았습니다. --1002
(좀 노가다 틱하지만 가장 간단한 해결책이 아닐까 하는 생각. 2년전 일이여서 정확히 기억 안나지만 95용 지뢰찾기와 2000용 지뢰찾기 2번 작업했었을겁니다. 약간 그림이 다르고 이미지좌표도 조금은 달라서. ^^)--1002
(혹시 전에 지뢰찾기 어셈레벨에서 분석하여 MineFinder 만드신 분이신가요? 저는 인간까지만 모델링 했지만, 신을 모델링한. ^^;) --1002
--동우