I. Introduction▲
Code d'un démineur en pure Windows API.

II. Code complet▲
Sélectionnez
#include <windows.h>
#include <time.h>
#include <stdio.h>
#define LARG 32
#define NBC_X 16
#define NBC_Y 12
#define NB_MINE 20
/* ID de menu */
#define IDM_QUIT 1
#define IDM_NEW 2
#define IDM_ABOUT 3
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
HINSTANCE hinst;
LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
int Demine(int tab[NBC_Y][NBC_X], int y, int x);
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
HMENU hMenu, hSousMenu;
RECT winRect;
hinst = hinstance;
wc.style = 0;
wc.lpfnWndProc = MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MaWinClass";
if(!RegisterClass(&wc)) return FALSE;
hSousMenu = CreateMenu();
AppendMenu(hSousMenu, MF_STRING, IDM_NEW, "Nouvelle partie");
AppendMenu(hSousMenu, MF_MENUBREAK, -1, NULL);
AppendMenu(hSousMenu, MF_STRING, IDM_ABOUT, "A propos");
AppendMenu(hSousMenu, MF_STRING, IDM_QUIT, "Quitter");
hMenu = CreateMenu();
AppendMenu(hMenu,MF_POPUP,(UINT)hSousMenu,"Fichier");
SetRect(&winRect, 0, 0, LARG*NBC_X, LARG*NBC_Y);
AdjustWindowRect(&winRect, WS_CAPTION, TRUE);
hwnd = CreateWindow("MaWinClass", "DMine",
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
winRect.right-winRect.left, winRect.bottom-winRect.top,
NULL, hMenu, hinstance, NULL);
if (!hwnd) return FALSE;
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************************/
int Demine(int tab[NBC_Y][NBC_X], int y, int x)
{
if(tab[y][x]&0x00010000) tab[y][x]=tab[y][x]&0xFFFEFFFF;
else return 0;
if(tab[y][x]&0x100) return 1; /* Si mine --> Perdu */
if(tab[y][x]&0x0000000F) return 0; /* case comporte un nb */
if(y!=0&&x!=0) Demine(tab, y-1, x-1); /* traitement des cases adjacentes */
if(y!=0) Demine(tab, y-1, x);
if(y!=0&&x!=NBC_X-1) Demine(tab, y-1, x+1);
if(x!=0) Demine(tab, y, x-1);
if(x!=NBC_X-1) Demine(tab, y, x+1);
if(y!=NBC_Y-1&&x!=0) Demine(tab, y+1, x-1);
if(y!=NBC_Y-1) Demine(tab, y+1, x);
if(y!=NBC_Y-1&&x!=NBC_X-1) Demine(tab, y+1, x+1);
return 0;
}
/******************************************************************************/
void Showtab(int tab[NBC_Y][NBC_X])
{
int x, y;
for(y=0; y<NBC_Y; y++)
for(x=0; x<NBC_X; x++)
{
tab[y][x]=tab[y][x]&0xFFFEFFFF;
}
}
/******************************************************************************/
int Test(int tab[NBC_Y][NBC_X])
{
int x, y;
int result = 1;
for(y=0; y<NBC_Y; y++)
for(x=0; x<NBC_X; x++)
{
if(tab[y][x]&0x00010000 && !(tab[y][x]&0x00000100)) result=0;
}
return result;
}
/******************************************************************************/
void Init(int tab[NBC_Y][NBC_X])
{
int x, y;
for(x=0; x<NB_MINE; x++) /* Pose les mines */
{
int mineX, mineY;
mineX = rand()%NBC_X;
mineY = rand()%NBC_Y;
if(tab[mineY][mineX]&0x100) x--;
else tab[mineY][mineX] = 0x100;
}
for(y=0; y<NBC_Y; y++) /* Init les cases */
for(x=0; x<NBC_X; x++)
{
if(tab[y][x]&0x100)
{
if(y!=0&&x!=0) tab[y-1][x-1]++;
if(y!=0) tab[y-1][x]++;
if(y!=0&& x!=NBC_X-1) tab[y-1][x+1]++;
if(x!=0) tab[y][x-1]++;
if(x!=NBC_X-1) tab[y][x+1]++;
if(y!=NBC_Y-1&&x!=0) tab[y+1][x-1]++;
if(y!=NBC_Y-1) tab[y+1][x]++;
if(y!=NBC_Y-1&&x!=NBC_X-1) tab[y+1][x+1]++;
}
tab[y][x]=tab[y][x]|0x00010000;
}
}
/******************************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static int tab[NBC_Y][NBC_X];
static int end;
switch (uMsg)
{
case WM_CREATE:
srand((unsigned int)time(0));
Init(tab);
return 0;
case WM_COMMAND:
if(LOWORD(wParam) == IDM_QUIT) PostMessage(hwnd, WM_CLOSE,0,0);
if(LOWORD(wParam) == IDM_ABOUT)
MessageBox(NULL, "Démineur code de CGi !", "A Propos !", MB_OK);
if(LOWORD(wParam) == IDM_NEW)
{
ZeroMemory(tab, sizeof(tab));
Init(tab);
end=0;
InvalidateRect(hwnd, NULL, FALSE);
}
return 0;
case WM_LBUTTONUP:
{
int x, y;
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
if(end) return 0;
x = xPos/LARG;
y = yPos/LARG;
InvalidateRect(hwnd, NULL, FALSE);
if(y<NBC_Y && x<NBC_X && Demine(tab, y, x))
{
Showtab(tab);
MessageBox(NULL, "Désolé ! Vous avez Perdu !", "DMine", MB_OK);
end=1;
}
else
if(Test(tab))
{
MessageBox(NULL, "Bravo ! Vous avez Gagné !", "DMine", MB_OK);
end=1;
}
return 0;
}
case WM_PAINT:
{
int i, j;
HPEN hpen;
HDC hdc, hdcDB;
HBITMAP bmDB;
HGDIOBJ hobjold;
PAINTSTRUCT ps;
RECT rect, caserect;
HBRUSH hbcase = CreateSolidBrush(0x00FF8080);
hpen = CreatePen(PS_SOLID, 1, 0x00AFAFAF);
GetClientRect(hwnd, &rect);
hdc = BeginPaint(hwnd, &ps);
hdcDB = CreateCompatibleDC(hdc);
bmDB = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
hobjold = SelectObject(hdcDB, bmDB);
SelectObject(hdcDB,hpen);
FillRect(hdcDB, &rect, (HBRUSH)(COLOR_3DFACE+1));
for(j=0; j<NBC_Y; j++)
for(i=0; i<NBC_X; i++)
{
int value = tab[j][i];
caserect.left = i*LARG+1;
caserect.right = i*LARG+LARG;
caserect.top = j*LARG+1;
caserect.bottom = j*LARG+LARG;
Rectangle(hdcDB, i*LARG+0, j*LARG+0,
i*LARG+LARG+1 , j*LARG+LARG+1);
SetTextColor(hdcDB,0x00000000);
if(value&0x100) /* mine */
DrawText(hdcDB,"M",1,&caserect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
if(value>0 && value<9) /* les nombres */
{
char st[16];
sprintf(st, "%i", value);
if(value==1) SetTextColor(hdcDB,0x00FF0000);
if(value==2) SetTextColor(hdcDB,0x00008F00);
if(value==3) SetTextColor(hdcDB,0x000000FF);
if(value>=4) SetTextColor(hdcDB,0x00FF00FF);
DrawText(hdcDB, st, 1, &caserect,
DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
if(value&0x00010000) /* cache les cases */
{
caserect.left++;
caserect.right--;
caserect.top++;
caserect.bottom--;
FillRect(hdcDB, &caserect, hbcase);
}
}
BitBlt(hdc, 0, 0, rect.right, rect.bottom, hdcDB, 0, 0, SRCCOPY);
DeleteDC(hdcDB);
DeleteObject(bmDB);
EndPaint(hwnd, &ps);
DeleteObject(hbcase);
DeleteObject(hpen);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
À vos compilateurs.


