📄 main.c
字号:
RegCloseKey(hKey);
}
void SaveBoard( BOARD *pBoard )
{
DWORD dwValue;
HKEY hKey;
UCHAR i;
TCHAR szData[16];
TCHAR szKeyName[8];
if( RegCreateKeyEx( HKEY_CURRENT_USER, szWineMineRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL ) != ERROR_SUCCESS)
return;
RegSetValueEx( hKey, TEXT("Xpos"), 0, REG_DWORD, (LPBYTE) &pBoard->Pos.x, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Ypos"), 0, REG_DWORD, (LPBYTE) &pBoard->Pos.y, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Difficulty"), 0, REG_DWORD, (LPBYTE) &pBoard->Difficulty, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Height"), 0, REG_DWORD, (LPBYTE) &pBoard->uRows, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Width"), 0, REG_DWORD, (LPBYTE) &pBoard->uCols, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Mines"), 0, REG_DWORD, (LPBYTE) &pBoard->uMines, sizeof(DWORD) );
RegSetValueEx( hKey, TEXT("Mark"), 0, REG_DWORD, (LPBYTE) &pBoard->bMark, sizeof(DWORD) );
for( i = 0; i < 3; i++ )
{
// As we write to the same registry key as MS WinMine does, we have to start at 1 for the registry keys
wsprintf( szKeyName, TEXT("Name%u"), i + 1);
_tcsncpy( szData, pBoard->szBestName[i], sizeof(szData) / sizeof(TCHAR) );
RegSetValueEx( hKey, szKeyName, 0, REG_SZ, (LPBYTE)szData, (_tcslen(szData) + 1) * sizeof(TCHAR) );
}
for( i = 0; i < 3; i++ )
{
wsprintf( szKeyName, TEXT("Time%u"), i + 1);
dwValue = pBoard->uBestTime[i];
RegSetValueEx( hKey, szKeyName, 0, REG_DWORD, (LPBYTE)(LPDWORD)&dwValue, sizeof(DWORD) );
}
RegCloseKey(hKey);
}
void DestroyBoard( BOARD *pBoard )
{
DeleteObject( pBoard->hFacesBMP );
DeleteObject( pBoard->hLedsBMP );
DeleteObject( pBoard->hMinesBMP );
}
void SetDifficulty( BOARD *pBoard, DIFFICULTY Difficulty )
{
HMENU hMenu;
switch(Difficulty)
{
case BEGINNER:
pBoard->uCols = BEGINNER_COLS;
pBoard->uRows = BEGINNER_ROWS;
pBoard->uMines = BEGINNER_MINES;
break;
case ADVANCED:
pBoard->uCols = ADVANCED_COLS;
pBoard->uRows = ADVANCED_ROWS;
pBoard->uMines = ADVANCED_MINES;
break;
case EXPERT:
pBoard->uCols = EXPERT_COLS;
pBoard->uRows = EXPERT_ROWS;
pBoard->uMines = EXPERT_MINES;
break;
case CUSTOM:
if( DialogBoxParam( pBoard->hInst, MAKEINTRESOURCE(IDD_CUSTOM), pBoard->hWnd, CustomDlgProc, (LPARAM) pBoard) != IDOK )
return;
break;
}
hMenu = GetMenu(pBoard->hWnd);
CheckMenuItem( hMenu, IDM_BEGINNER + pBoard->Difficulty, MF_UNCHECKED );
pBoard->Difficulty = Difficulty;
CheckMenuItem( hMenu, IDM_BEGINNER + Difficulty, MF_CHECKED );
}
void CreateBoard( BOARD *pBoard )
{
ULONG uLeft, uTop, uBottom, uRight, uWndX, uWndY, uWndWidth, uWndHeight;
pBoard->uBoxesLeft = pBoard->uCols * pBoard->uRows - pBoard->uMines;
pBoard->uNumFlags = 0;
CreateBoxes( pBoard );
pBoard->uWidth = pBoard->uCols * MINE_WIDTH + BOARD_WMARGIN * 2;
pBoard->uHeight = pBoard->uRows * MINE_HEIGHT + LED_HEIGHT
+ BOARD_HMARGIN * 3;
uWndX = pBoard->Pos.x - GetSystemMetrics( SM_CXFIXEDFRAME );
uWndY = pBoard->Pos.y - GetSystemMetrics( SM_CYMENU )
- GetSystemMetrics( SM_CYCAPTION )
- GetSystemMetrics( SM_CYFIXEDFRAME );
uWndWidth = pBoard->uWidth + GetSystemMetrics( SM_CXFIXEDFRAME ) * 2;
uWndHeight = pBoard->uHeight
+ GetSystemMetrics( SM_CYMENU )
+ GetSystemMetrics( SM_CYCAPTION )
+ GetSystemMetrics( SM_CYFIXEDFRAME ) * 2;
/* setting the mines rectangle boundary */
uLeft = BOARD_WMARGIN;
uTop = BOARD_HMARGIN * 2 + LED_HEIGHT;
uRight = uLeft + pBoard->uCols * MINE_WIDTH;
uBottom = uTop + pBoard->uRows * MINE_HEIGHT;
SetRect( &pBoard->MinesRect, uLeft, uTop, uRight, uBottom );
/* setting the face rectangle boundary */
uLeft = pBoard->uWidth / 2 - FACE_WIDTH / 2;
uTop = BOARD_HMARGIN;
uRight = uLeft + FACE_WIDTH;
uBottom = uTop + FACE_HEIGHT;
SetRect( &pBoard->FaceRect, uLeft, uTop, uRight, uBottom );
/* setting the timer rectangle boundary */
uLeft = BOARD_WMARGIN;
uTop = BOARD_HMARGIN;
uRight = uLeft + LED_WIDTH * 3;
uBottom = uTop + LED_HEIGHT;
SetRect( &pBoard->CounterRect, uLeft, uTop, uRight, uBottom );
/* setting the counter rectangle boundary */
uLeft = pBoard->uWidth - BOARD_WMARGIN - LED_WIDTH * 3;
uTop = BOARD_HMARGIN;
uRight = pBoard->uWidth - BOARD_WMARGIN;
uBottom = uTop + LED_HEIGHT;
SetRect( &pBoard->TimerRect, uLeft, uTop, uRight, uBottom );
pBoard->Status = WAITING;
pBoard->FaceBmp = SMILE_BMP;
pBoard->uTime = 0;
MoveWindow( pBoard->hWnd, uWndX, uWndY, uWndWidth, uWndHeight, TRUE );
RedrawWindow( pBoard->hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE );
}
void CheckLevel( BOARD *pBoard )
{
if( pBoard->uRows < BEGINNER_ROWS )
pBoard->uRows = BEGINNER_ROWS;
if( pBoard->uRows > MAX_ROWS )
pBoard->uRows = MAX_ROWS;
if( pBoard->uCols < BEGINNER_COLS )
pBoard->uCols = BEGINNER_COLS;
if( pBoard->uCols > MAX_COLS )
pBoard->uCols = MAX_COLS;
if( pBoard->uMines < BEGINNER_MINES )
pBoard->uMines = BEGINNER_MINES;
if( pBoard->uMines > pBoard->uCols * pBoard->uRows - 1 )
pBoard->uMines = pBoard->uCols * pBoard->uRows - 1;
}
void CreateBoxes( BOARD *pBoard )
{
LONG i, j;
ULONG uCol, uRow;
srand( (unsigned int)time( NULL ) );
/* Create the boxes...
* We actually create them with an empty border,
* so special care doesn't have to be taken on the edges
*/
for( uCol = 0; uCol <= pBoard->uCols + 1; uCol++ )
{
for( uRow = 0; uRow <= pBoard->uRows + 1; uRow++ )
{
pBoard->Box[uCol][uRow].bIsPressed = FALSE;
pBoard->Box[uCol][uRow].bIsMine = FALSE;
pBoard->Box[uCol][uRow].uFlagType = NORMAL;
pBoard->Box[uCol][uRow].uNumMines = 0;
}
}
/* create mines */
i = 0;
while( (ULONG)i < pBoard->uMines )
{
uCol = (ULONG)(pBoard->uCols * (float)rand() / RAND_MAX + 1);
uRow = (ULONG)(pBoard->uRows * (float)rand() / RAND_MAX + 1);
if( !pBoard->Box[uCol][uRow].bIsMine )
{
i++;
pBoard->Box[uCol][uRow].bIsMine = TRUE;
}
}
/*
* Now we label the remaining boxes with the
* number of mines surrounding them.
*/
for( uCol = 1; uCol < pBoard->uCols + 1; uCol++ )
{
for( uRow = 1; uRow < pBoard->uRows + 1; uRow++ )
{
for( i = -1; i <= 1; i++ )
{
for( j = -1; j <= 1; j++ )
{
if( pBoard->Box[uCol + i][uRow + j].bIsMine )
{
pBoard->Box[uCol][uRow].uNumMines++;
}
}
}
}
}
}
void DrawMines ( HDC hdc, HDC hMemDC, BOARD *pBoard )
{
HGDIOBJ hOldObj;
ULONG uCol, uRow;
hOldObj = SelectObject (hMemDC, pBoard->hMinesBMP);
for( uRow = 1; uRow <= pBoard->uRows; uRow++ )
{
for( uCol = 1; uCol <= pBoard->uCols; uCol++ )
{
DrawMine( hdc, hMemDC, pBoard, uCol, uRow, FALSE );
}
}
SelectObject( hMemDC, hOldObj );
}
void DrawMine( HDC hdc, HDC hMemDC, BOARD *pBoard, ULONG uCol, ULONG uRow, BOOL bIsPressed )
{
MINEBMP_OFFSET offset = BOX_BMP;
if( uCol == 0 || uCol > pBoard->uCols || uRow == 0 || uRow > pBoard->uRows )
return;
if( pBoard->Status == GAMEOVER )
{
if( pBoard->Box[uCol][uRow].bIsMine )
{
switch( pBoard->Box[uCol][uRow].uFlagType )
{
case FLAG:
offset = FLAG_BMP;
break;
case COMPLETE:
offset = EXPLODE_BMP;
break;
case QUESTION:
/* fall through */
case NORMAL:
offset = MINE_BMP;
}
}
else
{
switch( pBoard->Box[uCol][uRow].uFlagType )
{
case QUESTION:
offset = QUESTION_BMP;
break;
case FLAG:
offset = WRONG_BMP;
break;
case NORMAL:
offset = BOX_BMP;
break;
case COMPLETE:
/* Do nothing */
break;
default:
DEBUG("Unknown FlagType during game over in DrawMine\n");
break;
}
}
}
else
{ /* WAITING or PLAYING */
switch( pBoard->Box[uCol][uRow].uFlagType )
{
case QUESTION:
if( !bIsPressed )
offset = QUESTION_BMP;
else
offset = QPRESS_BMP;
break;
case FLAG:
offset = FLAG_BMP;
break;
case NORMAL:
if( !bIsPressed )
offset = BOX_BMP;
else
offset = MPRESS_BMP;
break;
case COMPLETE:
/* Do nothing */
break;
default:
DEBUG("Unknown FlagType while playing in DrawMine\n");
break;
}
}
if( pBoard->Box[uCol][uRow].uFlagType == COMPLETE && !pBoard->Box[uCol][uRow].bIsMine )
offset = (MINEBMP_OFFSET) pBoard->Box[uCol][uRow].uNumMines;
BitBlt( hdc,
(uCol - 1) * MINE_WIDTH + pBoard->MinesRect.left,
(uRow - 1) * MINE_HEIGHT + pBoard->MinesRect.top,
MINE_WIDTH, MINE_HEIGHT,
hMemDC, 0, offset * MINE_HEIGHT, SRCCOPY );
}
void DrawLeds( HDC hDC, HDC hMemDC, BOARD *pBoard, LONG nNumber, LONG x, LONG y )
{
HGDIOBJ hOldObj;
UCHAR i;
ULONG uLED[3];
LONG nCount;
nCount = nNumber;
if( nCount < 1000 )
{
if( nCount >= 0 )
{
uLED[0] = nCount / 100 ;
nCount -= uLED[0] * 100;
}
else
{
uLED[0] = 10; /* negative sign */
nCount = -nCount;
}
uLED[1] = nCount / 10;
nCount -= uLED[1] * 10;
uLED[2] = nCount;
}
else
{
for( i = 0; i < 3; i++ )
uLED[i] = 10;
}
/* use unlit led if not playing */
/* if( pBoard->Status == WAITING )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -