Last active
June 1, 2021 20:04
-
-
Save Ohjurot/4956635e3e59f12163ff9c4836099349 to your computer and use it in GitHub Desktop.
Win32 Bad Snake | Just a very bad way to programm snake
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if defined(UNICODE) && !defined(_UNICODE) | |
#define _UNICODE | |
#elif defined(_UNICODE) && !defined(UNICODE) | |
#define UNICODE | |
#endif | |
#define _WIN32_WINNT 0x0A00 | |
#define NOMINMAX | |
#include <windows.h> | |
#include <cmath> | |
#include <algorithm> | |
#include <cstdlib> | |
#include <ctime> | |
#define RECT_WIDTH(rc) (rc.right - rc.left) | |
#define RECT_HEIGHT(rc) (rc.bottom - rc.top) | |
volatile bool keepRunning = true; | |
volatile unsigned int playground[40][30] = {}; | |
volatile int appleX = -1; | |
volatile int appleY = -1; | |
const unsigned playfieldX = 800; | |
const unsigned playfieldY = 600; | |
struct snakePosElement{ | |
unsigned int x, y; | |
}; | |
enum Direction{ | |
LEFT, | |
RIGHT, | |
UP, | |
DOWN | |
}; | |
volatile Direction moveDirection = DOWN; | |
LRESULT CALLBACK windowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam){ | |
switch(msg){ | |
case WM_KEYDOWN: | |
switch(wParam){ | |
case VK_UP: | |
if(moveDirection != DOWN) moveDirection = UP; | |
break; | |
case VK_DOWN: | |
if(moveDirection != UP) moveDirection = DOWN; | |
break; | |
case VK_LEFT: | |
if(moveDirection != RIGHT) moveDirection = LEFT; | |
break; | |
case VK_RIGHT: | |
if(moveDirection != LEFT) moveDirection = RIGHT; | |
break; | |
} | |
break; | |
case WM_CLOSE: | |
keepRunning = false; | |
break; | |
case WM_PAINT: | |
HBRUSH brYellow = CreateSolidBrush(RGB(200, 255, 0)); | |
HBRUSH brSnakeHead = CreateSolidBrush(RGB(242, 185, 80)); | |
HBRUSH brSnakeBody = CreateSolidBrush(RGB(242, 200, 148)); | |
HBRUSH brSnakeFood = CreateSolidBrush(RGB(166, 30, 41)); | |
// RECT | |
RECT cr; | |
GetClientRect(wnd, &cr); | |
// PAINT | |
PAINTSTRUCT ps; | |
HDC hdc = BeginPaint(wnd, &ps); | |
// PLAYFIELD | |
RECT playfield = { | |
(RECT_WIDTH(cr) - playfieldX) / 2, | |
(RECT_HEIGHT(cr) - playfieldY) / 2, | |
(RECT_WIDTH(cr) - playfieldX) / 2 + playfieldX, | |
(RECT_HEIGHT(cr) - playfieldY) / 2 + playfieldY | |
}; | |
FillRect(hdc, &playfield, brYellow); | |
// Snake ground | |
for(unsigned int x = 0; x < 40; x++){ | |
for(unsigned int y = 0; y < 30; y++){ | |
RECT drawRect = { | |
playfield.left + (x * 20), playfield.top + (y * 20), | |
playfield.left + (x * 20) + 20, playfield.top + (y * 20) + 20 | |
}; | |
switch(playground[x][y]){ | |
case 1: | |
FillRect(hdc, &drawRect, brSnakeBody); | |
break; | |
case 2: | |
FillRect(hdc, &drawRect, brSnakeHead); | |
break; | |
case 3: | |
FillRect(hdc, &drawRect, brSnakeFood); | |
break; | |
} | |
} | |
} | |
// END PAINT | |
EndPaint(wnd, &ps); | |
DeleteObject(brYellow); | |
DeleteObject(brSnakeHead); | |
DeleteObject(brSnakeBody); | |
DeleteObject(brSnakeFood); | |
break; | |
} | |
return DefWindowProc(wnd, msg, wParam, lParam); | |
} | |
const LPCSTR clsName = "SnakeWin"; | |
bool moveSnake(snakePosElement* snakeArray, unsigned int* tail, unsigned int* length, Direction dir){ | |
unsigned int snakeIndex = (*tail + *length) % 128; | |
snakePosElement head = snakeArray[snakeIndex]; | |
switch(dir){ | |
case LEFT: | |
head.x = (head.x == 0 ? 40 : (head.x - 1) % 40); | |
break; | |
case RIGHT: | |
head.x = (head.x + 1) % 40; | |
break; | |
case UP: | |
head.y = (head.y == 0 ? 30 : (head.y - 1) % 30); | |
break; | |
case DOWN: | |
head.y = (head.y + 1) % 30; | |
break; | |
} | |
unsigned int snakeIndexNext = (snakeIndex + 1)% 128; | |
// Check array | |
unsigned int checkIndex = *tail; | |
for(unsigned int i = 0; i < *length; i++){ | |
if(snakeArray[checkIndex].x == head.x && snakeArray[checkIndex].y == head.y) return false; | |
checkIndex = (checkIndex + 1) % 128; | |
} | |
if(appleX == head.x && appleY == head.y){ | |
appleX = (std::rand() / (float)RAND_MAX) * 40; | |
appleY = (std::rand() / (float)RAND_MAX) * 30; | |
if(*length != 128){ | |
*length = *length +1; | |
} | |
}else{ | |
*tail = (*tail + 1) % 128; | |
} | |
snakeArray[snakeIndexNext] = head; | |
return true; | |
} | |
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow){ | |
// CLS | |
WNDCLASSEX wcex; | |
ZeroMemory(&wcex, sizeof(WNDCLASSEX)); | |
wcex.cbSize = sizeof(WNDCLASSEX); | |
wcex.cbClsExtra = 0; | |
wcex.cbWndExtra = 0; | |
wcex.hbrBackground = CreateSolidBrush(RGB(100, 200, 50)); | |
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wcex.hIcon = NULL; | |
wcex.hIconSm = NULL; | |
wcex.hInstance = hThisInstance; | |
wcex.lpfnWndProc = &windowProc; | |
wcex.lpszClassName = clsName; | |
wcex.lpszMenuName = NULL; | |
wcex.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; | |
RegisterClassEx(&wcex); | |
// WND | |
HWND wnd = CreateWindowEx( | |
NULL, | |
clsName, | |
"Snake 1234", | |
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MAXIMIZE, | |
0, 0, | |
800, 600, | |
NULL, | |
NULL, | |
hThisInstance, | |
NULL | |
); | |
// MEM | |
snakePosElement snake[128] = {}; | |
unsigned int tail = 0; | |
unsigned int length = 0; | |
// DBG | |
appleX = 10; | |
appleY = 10; | |
length = 1; | |
std::srand(std::time(0)); | |
// Time | |
int ctr = 0; | |
// Loop | |
MSG msg = {}; | |
while(keepRunning){ | |
// MSG | |
while(PeekMessage(&msg, wnd, 0, 0, PM_REMOVE)){ | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
// Game loop | |
if(ctr == 5){ | |
ctr = 0; | |
// Clear array | |
ZeroMemory((void*)playground, 40 * 30 * sizeof(unsigned int)); | |
// Fill array | |
for(unsigned int i = length; i > 0; i--){ | |
snakePosElement pos = snake[(tail + i) % 128]; | |
if(i == length){ | |
playground[pos.x][pos.y] = 2; | |
}else{ | |
playground[pos.x][pos.y] = 1; | |
} | |
} | |
// Apple | |
if(appleX >= 0 && appleY >= 0){ | |
playground[appleX][appleY] = 3; | |
} | |
bool gameOk = moveSnake(snake, &tail, &length, moveDirection); | |
RedrawWindow(wnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW); | |
if(!gameOk){ | |
MessageBox(wnd, "Game Over", "Game Over", MB_OK); | |
keepRunning = false; | |
} | |
} | |
ctr++; | |
Sleep(10); | |
} | |
// Cleanup | |
DestroyWindow(wnd); | |
UnregisterClass(clsName, hThisInstance); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment