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.


