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.