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

📄 main.c

📁 从rectos源码中提取的rectos版本的扫雷。是Win32 Application类型的C++源码。全面模仿了Windows扫雷
💻 C
📖 第 1 页 / 共 3 页
字号:

    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 + -