I. Introduction▲
Code d'un Mastermind en pure Windows API.
II. Code complet▲
Sélectionnez
#include <windows.h>
#include <stdlib.h>
#include <time.h>
#define LARG 32 // Largeur cases
#define ESP 8 // Espace entre cases
#define EP_TRAIS 2 // Epaisseur du trais
#define NB_COLOR 8 // 6 ou 8 couleurs
#define NB_CASE 4 // Nombre de cases
#define NB_LINE 10 // Nombre max d'essais
#define PAS (LARG+ESP)
#define HT_BTN PAS // Hauteur du bouton
// Position de la palette
#define POS_PAL_X ((NB_CASE+2)*PAS)
#define POS_PAL_Y PAS
// Position du tableau
#define POS_TAB_X PAS
#define POS_TAB_Y (PAS*(NB_LINE+1)+ESP)
// Position des indices
#define POS_IDC_X POS_PAL_X
#define POS_IDC_Y POS_TAB_Y
// Position des résultats
#define POS_RES_X POS_TAB_X
#define POS_RES_Y POS_PAL_Y
// ID de menu
#define IDM_QUIT 1
#define IDM_NEW 2
#define ID_BTN 3
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#if NB_COLOR != 6 && NB_COLOR != 8
#error NB_COLOR value must be 6 or 8 !
#endif
HINSTANCE hinst;
LRESULT CALLBACK MainWndProc
(
HWND, UINT, WPARAM, LPARAM);
int
WINAPI WinMain
(
HINSTANCE hinstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int
nCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
HMENU hMenu, hSousMenu;
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_STRING, IDM_QUIT, "
Quitter
"
);
hMenu =
CreateMenu
(
);
AppendMenu
(
hMenu,MF_POPUP,(
UINT)hSousMenu,"
Fichier
"
);
hwnd =
CreateWindow
(
"
MaWinClass
"
, "
MasterMind
"
,
WS_SYSMENU |
WS_CAPTION |
WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
(
NB_CASE+
3
)*
PAS+
NB_COLOR*
PAS, (
NB_LINE+
3
)*
PAS+
HT_BTN+
36
,
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;
}
/**
***************************************************************************
*/
LRESULT CALLBACK MainWndProc
(
HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static
HWND hButton;
static
int
tab[NB_LINE][NB_CASE]; // Tableau
static
int
TabRand[NB_CASE]; // Tableau du tirage en cours
static
int
TabRed[NB_LINE]; // Tableau des indices rouge TabRes
static
int
TabWhite[NB_LINE]; // Tableau des indices blanc
static
int
CurentLine; // Ligne en cours
static
HBRUSH color[NB_COLOR+
2
];
static
int
btndown; // Drag on
static
int
AffRes; // Affiche le résultat
static
int
xPos;
static
int
yPos;
static
int
SelColor; // Drag color
switch
(
uMsg)
{
case
WM_CREATE :
{
int
i;
color[0
] =
CreateSolidBrush
(
0x008F8F8F
); //Cases inactives grises
color[1
] =
CreateSolidBrush
(
0x000000FF
); // Les 6 couleurs
color[2
] =
CreateSolidBrush
(
0x0000FF00
);
color[3
] =
CreateSolidBrush
(
0x00FF4F4F
);
color[4
] =
CreateSolidBrush
(
0x00CF00CF
);
color[5
] =
CreateSolidBrush
(
0x0000FFFF
);
color[6
] =
CreateSolidBrush
(
0x00FFFF00
);
#if(NB_COLOR==8)
color[7
] =
CreateSolidBrush
(
0x00008F00
);
color[8
] =
CreateSolidBrush
(
0x00FFCFFF
);
#endif //Cases actives blanches
color[NB_COLOR+
1
] =
CreateSolidBrush
(
0x00FFFFFF
);
hButton =
CreateWindow
(
"
button
"
, "
Valider
"
, WS_CHILD |
WS_VISIBLE,
0
, 0
, 0
, 0
, hwnd, (
HMENU)ID_BTN, hinst, NULL
);
srand
(
time
(
0
));
for
(
i=
0
; i<
NB_CASE; i++
)
{
TabRand[i] =
rand
(
)%
NB_COLOR+
1
;
tab[CurentLine][i] =
NB_COLOR+
1
;
}
return
0
;
}
case
WM_COMMAND:
if
(
LOWORD
(
wParam) ==
IDM_QUIT) PostMessage
(
hwnd, WM_CLOSE,0
,0
);
if
(
LOWORD
(
wParam) ==
IDM_NEW)
{
int
i;
AffRes =
0
;
CurentLine =
0
;
EnableWindow
(
hButton, TRUE);
for
(
i=
0
; i<
NB_CASE; i++
) TabRand[i] =
rand
(
)%
NB_COLOR+
1
;
ZeroMemory
(
tab, sizeof
(
tab));
ZeroMemory
(
TabRed, sizeof
(
TabRed));
ZeroMemory
(
TabWhite, sizeof
(
TabWhite));
for
(
i=
0
; i<
NB_CASE; i++
) tab[CurentLine][i] =
NB_COLOR+
1
;
InvalidateRect
(
hwnd, NULL
, FALSE);
}
if
(
LOWORD
(
wParam) ==
ID_BTN)
{
int
i;
int
TabCptR[NB_COLOR+
2
]={
0
}
;
int
TabCptJ[NB_COLOR+
2
]={
0
}
;
for
(
i=
0
; i<
NB_CASE; i++
)
{
if
(
TabRand[i] ==
tab[CurentLine][i]) TabRed[CurentLine]++
;
TabCptR[TabRand[i]]++
;
TabCptJ[tab[CurentLine][i]]++
;
}
for
(
i=
1
; i<
NB_COLOR+
1
; i++
)
TabWhite[CurentLine] +=
TabCptR[i] <
TabCptJ[i]
? TabCptR[i] : TabCptJ[i];
if
(
CurentLine==(
NB_LINE-
1
) ||
TabRed[CurentLine]==
NB_CASE)
{
AffRes =
1
;
EnableWindow
(
hButton, FALSE);
}
else
{
CurentLine++
;
for
(
i=
0
; i<
NB_CASE; i++
) tab[CurentLine][i] =
NB_COLOR+
1
;
}
InvalidateRect
(
hwnd, NULL
, FALSE);
}
return
0
;
case
WM_SIZE:
MoveWindow
(
hButton, 0
, HIWORD
(
lParam)-
HT_BTN,
LOWORD
(
lParam), HT_BTN, TRUE);
return
0
;
case
WM_PAINT :
{
HPEN hp2px;
HGDIOBJ hobjold;
RECT rect;
PAINTSTRUCT ps;
HDC hdc, hdcDB;
HBITMAP bmDB;
int
j, k;
hp2px =
CreatePen
(
PS_SOLID, EP_TRAIS, 0x00000000
);
GetClientRect
(
hwnd, &
rect);
rect.bottom -=
HT_BTN;
hdc =
BeginPaint
(
hwnd, &
ps);
hdcDB =
CreateCompatibleDC
(
hdc);
bmDB =
CreateCompatibleBitmap
(
hdc, rect.right, rect.bottom);
hobjold =
SelectObject
(
hdcDB, bmDB);
SelectObject
(
hdcDB,hp2px);
SelectObject
(
hdcDB,color[0
]);
FillRect
(
hdcDB, &
rect, (
HBRUSH)(
COLOR_WINDOW+
1
));
for
(
j=
0
; j<
NB_CASE; j++
) // Affichage tableau
for
(
k=
0
; k<
NB_LINE; k++
)
{
SelectObject
(
hdcDB, color[tab[k][j]]);
Rectangle
(
hdcDB, POS_TAB_X+
j*
PAS, POS_TAB_Y-
k*
PAS,
POS_TAB_X+
LARG+
j*
PAS , POS_TAB_Y+
LARG-
k*
PAS);
}
for
(
j=
0
; j<
NB_LINE; j++
) // Affichage des indices
{
SelectObject
(
hdcDB, color[1
]);
for
(
k=
0
; k<
TabRed[j]; k++
)
Ellipse
(
hdcDB, POS_IDC_X+
k*
PAS/
2
, POS_IDC_Y-
j*
PAS+
LARG/
4
,
POS_IDC_X+
LARG/
2
+
k*
PAS/
2
, POS_IDC_Y-
j*
PAS+
LARG/
2
+
LARG/
4
);
SelectObject
(
hdcDB, color[NB_COLOR+
1
]);
for
(
; k<
TabWhite[j]; k++
)
Ellipse
(
hdcDB, POS_IDC_X+
k*
PAS/
2
, POS_IDC_Y-
j*
PAS+
LARG/
4
,
POS_IDC_X+
LARG/
2
+
k*
PAS/
2
, POS_IDC_Y-
j*
PAS+
LARG/
2
+
LARG/
4
);
}
for
(
j=
0
; j<
NB_CASE; j++
) // Affichage de la solution
{
if
(
AffRes)SelectObject
(
hdcDB,color[TabRand[j]]);
else
SelectObject
(
hdcDB,color[0
]);
Rectangle
(
hdcDB, POS_RES_X+
j*
PAS, POS_RES_Y,
POS_RES_X+
LARG+
j*
PAS , POS_RES_Y+
LARG);
}
for
(
j=
0
; j<
NB_COLOR; j++
) // Affichage palette
{
SelectObject
(
hdcDB,color[j+
1
]);
Rectangle
(
hdcDB, POS_PAL_X+
j*
PAS, POS_PAL_Y,
POS_PAL_X+
LARG+
j*
PAS , POS_PAL_Y+
LARG);
}
SelectObject
(
hdcDB,color[1
]);
if
(
btndown==
1
) // Drag
{
SelectObject
(
hdcDB, color[SelColor]);
Rectangle
(
hdcDB, xPos-
LARG/
2
, yPos-
LARG/
2
, xPos+
LARG/
2
, yPos+
LARG/
2
);
}
BitBlt
(
hdc, 0
, 0
, rect.right, rect.bottom, hdcDB, 0
, 0
, SRCCOPY);
SelectObject
(
hdcDB,hobjold);
DeleteDC
(
hdcDB);
DeleteObject
(
bmDB);
EndPaint
(
hwnd, &
ps);
DeleteObject
(
hp2px);
return
0
;
}
case
WM_LBUTTONDOWN:
{
int
j;
xPos =
GET_X_LPARAM
(
lParam);
yPos =
GET_Y_LPARAM
(
lParam);
j =
(
xPos-
POS_PAL_X)/
PAS;
if
(
yPos>=
POS_PAL_Y &&
yPos<
POS_PAL_Y+
LARG &&
xPos>=
POS_PAL_X+
j*
PAS
&&
xPos<
POS_PAL_X+
LARG+
j*
PAS &&
j<
NB_COLOR &&
AffRes==
0
)
{
SelColor =
j+
1
;
btndown =
1
;
}
}
// pas de return, on execute le code de WM_MOUSEMOVE
case
WM_MOUSEMOVE:
if
(
btndown==
1
)
{
xPos =
GET_X_LPARAM
(
lParam);
yPos =
GET_Y_LPARAM
(
lParam);
InvalidateRect
(
hwnd, NULL
, FALSE);
}
return
0
;
case
WM_LBUTTONUP:
if
(
btndown==
1
)
{
int
j, k;
j =
(
xPos-
POS_TAB_X)/
PAS;
k =
(
POS_TAB_Y+
PAS-
yPos)/
PAS;
if
(
yPos>=
POS_TAB_Y-
k*
PAS &&
yPos<
POS_TAB_Y+
LARG-
k*
PAS &&
xPos>=
POS_TAB_X+
j*
PAS &&
xPos<
POS_TAB_X+
LARG+
j*
PAS &&
j<
NB_CASE &&
k==
CurentLine) tab[k][j] =
SelColor;
btndown =
0
;
InvalidateRect
(
hwnd, NULL
, FALSE);
}
return
0
;
case
WM_DESTROY:
{
int
i;
for
(
i=
0
; i<
NB_COLOR+
2
; i++
) DeleteObject
(
color[i]);
PostQuitMessage
(
0
);
return
0
;
}
default
:
return
DefWindowProc
(
hwnd, uMsg, wParam, lParam);
}
}
À vos compilateurs.