2024. 11. 7. 16:53ㆍc,c++(cpp)
#include <stdio.h>
#include <windows.h>
#include <time.h>
#define hight 20
#define weight 12
#define BufferWidth 40
#define BufferHeight 24
HANDLE hBuffer[2];
int screenIndex;
int currentBlock;
int block_y = 0;
int block_x = 3;
int rotation = 1;
int map[hight][weight]{
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1}
};
int block1[4][4][4] = {
{
{1,0,0,0},
{1,0,0,0},
{1,0,0,0},
{1,0,0,0}
},
{
{1,1,1,1},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
},
{
{0,0,0,1},
{0,0,0,1},
{0,0,0,1},
{0,0,0,1}
},
{
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{1,1,1,1}
}
};
int block2[4][4][4] = {
{
{1,0,0,0},
{1,0,0,0},
{1,0,0,0},
{1,1,1,0}
},
{
{0,1,1,1},
{0,0,0,1},
{0,0,0,1},
{0,0,0,1}
},
{
{0,0,0,1},
{0,0,0,1},
{0,0,0,1},
{0,1,1,1}
},
{
{0,0,0,0},
{1,0,0,0},
{1,0,0,0},
{1,1,1,1}
}
};
int block3[4][4][4] = {
{
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}
},
{
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}
},
{
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}
},
{
{0,0,0,0},
{0,1,1,0},
{0,1,1,0},
{0,0,0,0}
}
};
int block4[4][4][4] = {
{
{1,1,1,0},
{1,0,1,0},
{1,0,1,0},
{0,0,0,0}
},
{
{0,0,0,0},
{1,0,1,0},
{1,0,1,0},
{1,1,1,0}
},
{
{0,1,1,1},
{0,0,0,1},
{0,1,1,1},
{0,0,0,0}
},
{
{0,1,1,1},
{0,1,0,0},
{0,1,1,1},
{0,0,0,0}
}
};
int block[4][4] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
int(*blocks[4])[4][4] = { block1, block2, block3, block4 };
void MoveCursor(int x, int y);
void MapPlay();
void BlockPlay();
void HideCursor();
void ContRoller();
void CheckLeft();
void CheckSideLeft();
void CheckSideRight();
void CheckRight();
void ChekcBottom();
void Merge();
void CheckLine();
void UpdateBlock();
void GenerateRandomBlock();
#pragma region Double Buffer
//버퍼 초기화
void InitBuffer();
//버퍼 뒤집기
void FlipBuffer();
//버퍼 창 깨끗이
void ClearBuffer();
//버퍼 쓰기
void WriteBuffer(int x, int y, const char* shape, int color);
//버퍼 해제
void ReleaseBuffer();
#pragma endregion
int main() {
InitBuffer();
clock_t curtime = clock();
GenerateRandomBlock();
while (1) {
ClearBuffer();
MapPlay();
BlockPlay();
if (clock() - curtime >= 200) {
block_y++;
curtime = clock();
}
ContRoller();
FlipBuffer();
Sleep(50);
}
ReleaseBuffer();
return 0;
}
void MoveCursor(int x, int y)
{
COORD pos;
pos.X = x * 2;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void MapPlay()
{
for (int y = 0; y < hight; y++) {
for (int x = 0; x < weight; x++) {
if (map[y][x] == 1) {
/*MoveCursor(x, y);
printf("■");*/
WriteBuffer(x, y, "■",7);
}
}
}
}
void BlockPlay()
{
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
/*MoveCursor(x + block_x, y + block_y);
printf("■");*/
WriteBuffer(x + block_x, y + block_y, "■",3);
}
}
}
}
void HideCursor() {
CONSOLE_CURSOR_INFO info;
info.dwSize = 1;
info.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}
void ContRoller()
{
CheckLine();
ChekcBottom();
if (GetAsyncKeyState(VK_LEFT))
{
CheckSideLeft();
CheckLeft();
block_x--;
}
if (GetAsyncKeyState(VK_RIGHT))
{
CheckSideRight();
CheckRight();
block_x++;
}
if (GetAsyncKeyState(VK_UP)) {
rotation = (rotation + 1) % 4;
UpdateBlock();
}
if (GetAsyncKeyState(VK_DOWN)) {
rotation = (rotation - 1 + 4) % 4;
UpdateBlock();
}
if (GetAsyncKeyState(VK_SPACE))
{
block_y++;
}
}
void CheckLeft()
{
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
if (block_x + x <= 1) {
block_x++;
return;
}
}
}
}
}
void CheckRight()
{
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
if (block_x + x >= weight - 2) {
block_x--;
return;
}
}
}
}
}
void ChekcBottom() {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
if (block_y + y >= hight - 1 || map[block_y + y][block_x + x] == 1) {
Merge();
block_x = 3;
block_y = 0;
GenerateRandomBlock();
return;
}
}
}
}
}
void Merge() {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
map[block_y + y - 1][block_x + x] = 1;
}
}
}
}
void CheckSideLeft() {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
if (map[block_y + y][block_x + x - 1] == 1) {
block_x++;
return;
}
}
}
}
}
void CheckSideRight() {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
if (block[y][x] == 1) {
if (map[block_y + y][block_x + x + 1] == 1) {
block_x--;
return;
}
}
}
}
}
void CheckLine() {
for (int y = hight - 2; y >= 0; y--) {
int flag = 1;
for (int x = 1; x < weight - 1; x++) {
if (map[y][x] == 0) {
flag = 0;
break;
}
}
if (flag == 1) {
for (int ty = y; ty > 0; ty--) {
for (int x = 1; x < weight - 1; x++) {
map[ty][x] = map[ty - 1][x];
}
}
for (int x = 1; x < weight - 1; x++) {
map[0][x] = 0;
}
y++;
}
}
}
void UpdateBlock() {
srand((unsigned int)time(NULL));
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
block[y][x] = blocks[currentBlock][rotation][y][x];
}
}
}
void GenerateRandomBlock() {
srand((unsigned int)time(NULL));
currentBlock = rand() % 4;
rotation = 0;
block_x = 3;
block_y = 0;
UpdateBlock();
}
#pragma region Double Buffer
void InitBuffer()
{
screenIndex = 0;
COORD size = { BufferWidth, BufferHeight };
SMALL_RECT rect = { 0, 0, (SHORT)(BufferWidth - 1), (SHORT)(BufferHeight - 1) };
hBuffer[0] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleScreenBufferSize(hBuffer[0], size);
SetConsoleWindowInfo(hBuffer[0], TRUE, &rect);
hBuffer[1] = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleScreenBufferSize(hBuffer[1], size);
SetConsoleWindowInfo(hBuffer[1], TRUE, &rect);
CONSOLE_CURSOR_INFO info;
info.dwSize = 1;
info.bVisible = FALSE;
SetConsoleCursorInfo(hBuffer[0], &info);
SetConsoleCursorInfo(hBuffer[1], &info);
HWND consoleWindow = GetConsoleWindow();
RECT r;
GetWindowRect(consoleWindow, &r);
MoveWindow(consoleWindow, r.left, r.top, BufferWidth * 10, BufferHeight * 20, TRUE);
}
void FlipBuffer()
{
SetConsoleActiveScreenBuffer(hBuffer[screenIndex]);
screenIndex = !screenIndex;
}
void ClearBuffer()
{
COORD pos = { 0, 0 };
DWORD dw;
FillConsoleOutputCharacter(hBuffer[screenIndex],' ', BufferWidth * BufferHeight, pos, &dw);
}
void WriteBuffer(int x, int y, const char* shape, int color)
{
COORD pos = { x * 2, y };
SetConsoleCursorPosition(hBuffer[screenIndex], pos);
SetConsoleTextAttribute(hBuffer[screenIndex], color);
DWORD dw;
WriteFile(hBuffer[screenIndex], shape, strlen(shape), &dw, NULL);
}
void ReleaseBuffer()
{
CloseHandle(hBuffer[0]);
CloseHandle(hBuffer[1]);
}
#pragma endregion
'c,c++(cpp)' 카테고리의 다른 글
테트리스 소스코드 (더블버퍼 적용 x) (0) | 2024.11.07 |
---|---|
c 언어 별로 도형만들기 코드 정리(반복문 연습) (0) | 2024.09.25 |