#include <windows.h>
#define WIN32_LEAN_AND_MEAN
#define ID_STARTBTN 8000
#define ID_TIMER 8001
const LPCWSTR g_szClassName = TEXT("SNAKEGAME");
const LPCWSTR g_szWindowName = TEXT("Snake Game");
HINSTANCE mhInst;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void PlaceSnakeCell(HDC hdc, int x_square, int y_square);
void ClearSnakeCell(HDC hdc, int x_square, int y_square);
void MoveSnakeCell(HDC hdc, int direction);
int gridcells[40][44] = {0};
int m_gridcells[40][44] = {0};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
mhInst = hInstance;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
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 = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("Window Registration Failed"), TEXT("Error"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
g_szWindowName,
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 451, 480,
NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
MessageBox(NULL, TEXT("Window Creation Failed"), TEXT("Error"),
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
int i, j;
switch(msg)
{
case WM_CREATE:
CreateWindowEx(0,
TEXT("BUTTON"),
TEXT("Start"),
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
370,
410,
70,
25,
hWnd,
(HMENU) ID_STARTBTN,
mhInst,
NULL);
SetTimer(hWnd, ID_TIMER, 1000, NULL);
break;
case WM_COMMAND:
switch(wParam)
{
case ID_STARTBTN:
hDC = GetDC(hWnd);
SetBkMode(hDC, TRANSPARENT);
PlaceSnakeCell(hDC, 2, 40); // place start cell (2,40)
ReleaseDC(hWnd, hDC);
break;
}
break;
case WM_TIMER: // NEVER EXECUTED
// move cell accordingly
MessageBox(hWnd, TEXT("timer code"), TEXT("timer code"), NULL);
break;
case WM_PAINT:
hDC = GetDC(hWnd);
SetBkMode(hDC, TRANSPARENT);
// draw horizontal grid 44x40
for(i=10; i < 400; i = i+10)
{
MoveToEx(hDC, 0, i, NULL);
LineTo(hDC, 440, i);
}
// draw verticle grid 44x40
for(i=10; i<450; i=i+10)
{
MoveToEx(hDC, i, 0, NULL);
LineTo(hDC, i, 400);
}
// control line
MoveToEx(hDC, 0, 400, NULL);
LineTo(hDC, 480, 400);
// update filled cells
for (i=1; i<44; i++)
{
for(j=1; j<40; j++)
{
if(gridcells[i][j] == 1)
{
PlaceSnakeCell(hDC, j, i);
}
}
}
ReleaseDC(hWnd, hDC);
break;
case WM_KEYDOWN:
hDC = GetDC(hWnd);
switch(wParam)
{
case VK_UP:
MoveSnakeCell(hDC, 1);
break;
case VK_RIGHT:
MoveSnakeCell(hDC, 2);
break;
case VK_DOWN:
MoveSnakeCell(hDC, 3);
break;
case VK_LEFT:
MoveSnakeCell(hDC, 4);
break;
}
ReleaseDC(hWnd, hDC);
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
void PlaceSnakeCell(HDC hdc, int x_square, int y_square)
{
int c_top;
int c_left;
if(y_square == 1)
{
c_top = (y_square * 10) - 10;
}
else
{
c_top = (y_square * 10) - 9;
}
if(x_square == 1)
{
c_left = (x_square * 10) - 10;
}
else
{
c_left = (x_square * 10) - 9;
}
RECT gridbox;
gridbox.top = c_top;
gridbox.left = c_left;
gridbox.right = (x_square * 10);
gridbox.bottom = y_square * 10;
HBRUSH hbr;
hbr = CreateSolidBrush(RGB(0,255,0));
FillRect(hdc, &gridbox, hbr);
DeleteObject(hbr);
// update cell index
gridcells[y_square][x_square] = 1;
}
void ClearSnakeCell(HDC hdc, int x_square, int y_square)
{
int c_top;
int c_left;
if(y_square == 1)
{
c_top = (y_square * 10) - 10;
}
else
{
c_top = (y_square * 10) - 9;
}
if(x_square == 1)
{
c_left = (x_square * 10) - 10;
}
else
{
c_left = (x_square * 10) - 9;
}
RECT gridbox;
gridbox.top = c_top;
gridbox.left = c_left;
gridbox.right = (x_square * 10);
gridbox.bottom = y_square * 10;
HBRUSH hbr;
hbr = CreateSolidBrush(RGB(255,255,255));
FillRect(hdc, &gridbox, hbr);
DeleteObject(hbr);
// update cell index
gridcells[y_square][x_square] = 0;
}
void MoveSnakeCell(HDC hdc, int direction)
{
/*
direction 1: UP
direction 2: RIGHT
direction 3: DOWN
direction 4: LEFT
*/
int temp = 0;
switch(direction)
{
case 1:
for(int i=1; i < 45; i++)
{
for(int j=1; j<41; j++)
{
if(gridcells[j][i] == 1)
{
if(j == 1) // prevent cell movement above top line
{ break; }
else
{
ClearSnakeCell(hdc, i, j);
PlaceSnakeCell(hdc, i, j-1);
}
}
}
}
break;
case 2:
for(int i=1; i < 45; i++)
{
for(int j=1; j<41; j++)
{
if(gridcells[j][i] == 1 && m_gridcells[j][i] != 1)
{
if(i == 44)
{ break; }
else
{
ClearSnakeCell(hdc, i, j);
PlaceSnakeCell(hdc, i+1, j);
m_gridcells[j][i+1] = 1;
}
}
}
}
break;
case 4:
for(int i=1; i < 45; i++)
{
for(int j=1; j<41; j++)
{
if(gridcells[j][i] == 1)
{
if(i == 1)
{ break; }
else
{
ClearSnakeCell(hdc, i, j);
PlaceSnakeCell(hdc, i-1, j);
}
}
}
}
break;
case 3:
for(int i=1; i < 45; i++)
{
for(int j=1; j<41; j++)
{
if(gridcells[j][i] == 1 && m_gridcells[j][i] != 1)
{
if(j == 40) // prevent cell movement below base line
{ break; }
else
{
ClearSnakeCell(hdc, i, j);
PlaceSnakeCell(hdc, i, j+1);
m_gridcells[j+1][i] = 1;
}
}
}
}
break;
}
// reset moved cell array
for(int i=1; i < 45; i++)
{
for(int j=1; j<41; j++)
{
m_gridcells[j][i] = 0;
}
}
}