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

II. Code complet▲
Sélectionnez
#include <windows.h>
#include <time.h>
#define WIDTH 128
#define TABSIZE 4
#define ID_TIMER 1
#define TIMER_TIME 250
/* ID de menu */
#define IDM_QUIT 1
#define IDM_NEW 2
#define IDM_ABOUT 3
HINSTANCE hinst;
BOOL gameOver;
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;
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";
RegisterClass(&wc);
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_PTR)hSousMenu,"Fichier");
winRect.top = 0;
winRect.left = 0;
winRect.right = WIDTH*TABSIZE;
winRect.bottom = WIDTH*TABSIZE;
AdjustWindowRect(&winRect, WS_CAPTION, TRUE);
hwnd = CreateWindow("MaWinClass", "2048",
WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
winRect.right-winRect.left, winRect.bottom-winRect.top,
NULL, hMenu, hinstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
/******************************************************************************/
BOOL PlayUp(int tab[TABSIZE][TABSIZE])
{
int result = FALSE;
for(int k=0; k<TABSIZE; k++)
{
for(int i=0; i<TABSIZE-1; i++)
{
int j=i+1;
if(tab[i][k]==0)
{
while(j<TABSIZE && tab[j][k]==0) j++;
if(j<TABSIZE)
{
tab[i][k]=tab[j][k];
tab[j][k]=0;
i--;
result=TRUE;
}
}
else
{
while(j<TABSIZE && tab[j][k]==0) j++;
if(j<TABSIZE && tab[j][k]==tab[i][k])
{
tab[i][k]*=2;
tab[j][k]=0;
result=TRUE;
}
}
}
}
return result;
}
/******************************************************************************/
BOOL PlayLeft(int tab[TABSIZE][TABSIZE])
{
int result = FALSE;
for(int k=0; k<TABSIZE; k++)
{
for(int i=0; i<TABSIZE-1; i++)
{
int j=i+1;
if(tab[k][i]==0)
{
while(j<TABSIZE && tab[k][j]==0) j++;
if(j<TABSIZE)
{
tab[k][i]=tab[k][j];
tab[k][j]=0;
i--;
result=TRUE;
}
}
else
{
while(j<TABSIZE && tab[k][j]==0) j++;
if(j<TABSIZE && tab[k][j]==tab[k][i])
{
tab[k][i]*=2;
tab[k][j]=0;
result=TRUE;
}
}
}
}
return result;
}
/******************************************************************************/
BOOL PlayRight(int tab[TABSIZE][TABSIZE])
{
int result = FALSE;
for(int k=0; k<TABSIZE; k++)
{
for(int i=TABSIZE-1; i>0; i--)
{
int j=i-1;
if(tab[k][i]==0)
{
while(j>=0 && tab[k][j]==0) j--;
if(j>=0)
{
tab[k][i]=tab[k][j];
tab[k][j]=0;
i++;
result=TRUE;
}
}
else
{
while(j>=0 && tab[k][j]==0) j--;
if(j>=0 && tab[k][j]==tab[k][i])
{
tab[k][i]*=2;
tab[k][j]=0;
result=TRUE;
}
}
}
}
return result;
}
/******************************************************************************/
BOOL PlayDown(int tab[TABSIZE][TABSIZE])
{
int result = FALSE;
for(int k=0; k<TABSIZE; k++)
{
for(int i=TABSIZE-1; i>0; i--)
{
int j=i-1;
if(tab[i][k]==0)
{
while(j>=0 && tab[j][k]==0) j--;
if(j>=0)
{
tab[i][k]=tab[j][k];
tab[j][k]=0;
i++;
result=TRUE;
}
}
else
{
while(j>=0 && tab[j][k]==0) j--;
if(j>=0 && tab[j][k]==tab[i][k])
{
tab[i][k]*=2;
tab[j][k]=0;
result=TRUE;
}
}
}
}
return result;
}
/******************************************************************************/
BOOL tabBlocked(int tab[TABSIZE][TABSIZE])
{
for(int j=0; j<TABSIZE; j++)
for(int i=0; i<TABSIZE; i++)
if(tab[j][i]==0) return FALSE;
for(int i=0; i<TABSIZE; i++)
for(int j=0; j<TABSIZE-1; j++)
if(tab[i][j]==tab[i][j+1]) return FALSE;
for(int i=0; i<TABSIZE; i++)
for(int j=0; j<TABSIZE-1; j++)
if(tab[j][i]==tab[j+1][i]) return FALSE;
return TRUE;
}
/******************************************************************************/
void newNumber(int tab[TABSIZE][TABSIZE])
{
int x, y;
int randtab[10]={2,2,2,2,2,4,2,2,2,2};
do
{
x=rand()%TABSIZE;
y=rand()%TABSIZE;
}
while(tab[y][x]!=0);
tab[y][x]=randtab[rand()%10];
}
/******************************************************************************/
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static int tab[TABSIZE][TABSIZE];
switch (uMsg)
{
case WM_CREATE:
{
srand((unsigned int)time(0));
gameOver=FALSE;
newNumber(tab);
newNumber(tab);
return 0;
}
case WM_COMMAND:
if(LOWORD(wParam) == IDM_QUIT)
PostMessage(hwnd, WM_CLOSE,0,0);
if(LOWORD(wParam) == IDM_ABOUT)
MessageBox(NULL, "Copyright 2020 CGi !", "2048", MB_OK);
if(LOWORD(wParam) == IDM_NEW)
{
ZeroMemory(tab, sizeof(tab));
gameOver=FALSE;
newNumber(tab);
newNumber(tab);
InvalidateRect(hwnd, NULL, FALSE);
}
return 0;
case WM_TIMER:
if(wParam == ID_TIMER)
{
newNumber(tab);
InvalidateRect(hwnd, NULL, FALSE);
KillTimer(hwnd,ID_TIMER);
}
return 0;
case WM_KEYDOWN:
if(!gameOver)
{
if(wParam==VK_DOWN)
{
if(PlayDown(tab)) SetTimer(hwnd, ID_TIMER, TIMER_TIME, NULL);
InvalidateRect(hwnd, NULL, FALSE);
}
if(wParam==VK_UP)
{
if(PlayUp(tab)) SetTimer(hwnd, ID_TIMER, TIMER_TIME, NULL);
InvalidateRect(hwnd, NULL, FALSE);
}
if(wParam==VK_LEFT)
{
if(PlayLeft(tab)) SetTimer(hwnd, ID_TIMER, TIMER_TIME, NULL);
InvalidateRect(hwnd, NULL, FALSE);
}
if(wParam==VK_RIGHT)
{
if(PlayRight(tab)) SetTimer(hwnd, ID_TIMER, TIMER_TIME, NULL);
InvalidateRect(hwnd, NULL, FALSE);
}
if(tabBlocked(tab))
{
MessageBox(NULL, "Game over !", "2048", MB_OK);
gameOver = TRUE;
}
}
return 0;
case WM_PAINT:
{
int i, j;
HPEN hpen;
HDC hdc, hdcDB;
HBITMAP bmDB;
PAINTSTRUCT ps;
RECT rect, caserect;
LOGFONT lf= {0};
ZeroMemory(&lf, sizeof(LOGFONT));
lstrcpy(lf.lfFaceName, "Arial");
lf.lfHeight = 64;
lf.lfWeight = FW_BOLD;
HFONT nbfont = CreateFontIndirect(&lf);
HBRUSH hbcase = CreateSolidBrush(0x00000000);
hpen = CreatePen(PS_SOLID, 3, 0x00000000);
GetClientRect(hwnd, &rect);
hdc = BeginPaint(hwnd, &ps);
hdcDB = CreateCompatibleDC(hdc);
bmDB = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
SelectObject(hdcDB, bmDB);
SelectObject(hdcDB,hpen);
SelectObject(hdcDB, nbfont);
FillRect(hdcDB, &rect, (HBRUSH)(COLOR_3DFACE+1));
for(j=0; j<TABSIZE; j++)
for(i=0; i<TABSIZE; i++)
{
int value = tab[j][i];
caserect.left = i*WIDTH+1;
caserect.right = i*WIDTH+WIDTH;
caserect.top = j*WIDTH+1;
caserect.bottom = j*WIDTH+WIDTH;
Rectangle(hdcDB, i*WIDTH, j*WIDTH,
i*WIDTH+WIDTH+1, j*WIDTH+WIDTH+1);
char str[5]="";
if(value!=0) wsprintf(str, "%d", value);
int strlenght = strlen(str);
DrawText(hdcDB, str, strlenght, &caserect,
DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
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_ERASEBKGND:
// not drawing the background.
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}À vos compilateurs.


