#include "stdafx.h"
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>
//---------------------------------------------------------------------------------------------------
HANDLE consoleHandle;
enum eColor : int
{
clBlack,
clBlue,
clGreen,
clCyan,
clRed,
clPurple,
clYellow,
clWhite,
clBright,
};
void initVideo()
{
CONSOLE_CURSOR_INFO info;
info.bVisible = false;
info.dwSize = 1;
consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(consoleHandle, &info);
}
void gotoxy(int x, int y)
{
COORD p;
p.X = x;
p.Y = y;
SetConsoleCursorPosition(consoleHandle, p);
}
void putTile(int x, int y, int color)
{
gotoxy(x * 2, y);
SetConsoleTextAttribute(consoleHandle, (color != 0) * ((clBright | color) << 4));
putchar(' ');
putchar(' ');
}
void putString(int x, int y, int color, const char* s)
{
gotoxy(x, y);
SetConsoleTextAttribute(consoleHandle, clBright | color);
puts(s);
}
void putStringValue(int x, int y, int colorS, int colorV, const char* s, int value)
{
gotoxy(x, y);
SetConsoleTextAttribute(consoleHandle, clBright | colorS);
printf(s);
SetConsoleTextAttribute(consoleHandle, clBright | colorV);
printf("d", value);
}
//---------------------------------------------------------------------------------------------------
const int blockPatterns[7][4][4] =
{
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 },
{ 0, 0, 1, 1 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 1, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 1, 1 },
{ 0, 0, 0, 1 },
{ 0, 0, 0, 0 },
},
{
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
},
};
//---------------------------------------------------------------------------------------------------
#define MAP_WIDTH 14
#define MAP_HEIGHT 29
#define LEVEL_LINES 20
#define LEVEL_MAX 18
#define UPPER_MARGIN 3
#define SCAN_COUNT 20
int map[MAP_HEIGHT][MAP_WIDTH];
int currentBlock[4][4];
int currentBlockIndex, nextBlockIndex;
int blockX, blockY;
int score, hiScore;
int level;
int lines;
void initStage();
void putCurrentBlock(int draw = 1)
{
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
if (currentBlock[y][x] && blockY + y >= UPPER_MARGIN)
putTile(13 + blockX + x, blockY + y - UPPER_MARGIN, (currentBlockIndex + 1) * draw);
}
void putNextBlock()
{
putString(61, 1, clRed, "Next Block");
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
putTile(31 + x, 3 + y, blockPatterns[nextBlockIndex][y][x] * (nextBlockIndex + 1));
}
bool isBlocked()
{
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
if (currentBlock[y][x] && map[blockY + y][blockX + x])
return true;
return false;
}
void rotate(int isCW = 1)
{
int tempBlock[4][4];
memmove(tempBlock, currentBlock, sizeof(tempBlock));
if (isCW) putCurrentBlock(0);
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
if (isCW) currentBlock[x][3 - y] = tempBlock[y][x];
else currentBlock[3 - x][y] = tempBlock[y][x];
if (isBlocked())
rotate(!isCW);
else putCurrentBlock();
}
void bringNext()
{
blockX = 5;
blockY = 0;
memmove(currentBlock, blockPatterns[currentBlockIndex = nextBlockIndex], sizeof(currentBlock));
nextBlockIndex = rand() % 7;
putNextBlock();
if (isBlocked())
{
putString(35, 11, clRed, " ");
putString(35, 12, clRed, " Game Over ");
putString(35, 13, clRed, " ");
Sleep(3000);
initStage();
}
}
void drawMap()
{
putStringValue(5, 1, clRed, clYellow, "HiScore", hiScore);
putStringValue(5, 2, clRed, clYellow, " Score", score);
putStringValue(5, 3, clRed, clYellow, " Level", level);
for (int y = UPPER_MARGIN; y < MAP_HEIGHT - 1; ++y)
for (int x = 1; x < MAP_WIDTH - 1; ++x)
putTile(13 + x, y - UPPER_MARGIN, map[y][x]);
}
void release()
{
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
if (currentBlock[y][x]) map[blockY + y][blockX + x] = currentBlockIndex + 1;
int combo = 0;
for (int y = 3; y >= combo; --y)
{
if (blockY + y < MAP_HEIGHT - 2)
{
int sum = 0;
for (int x = 2; x < 12; ++x)
sum += map[blockY + y][x] != 0;
if (sum == 10)
{
combo++;
score += 25 * combo;
if (score > hiScore) hiScore = score;
for (int yy = blockY + y; yy > 0; --yy)
for (int xx = 2; xx < 12; ++xx)
map[yy][xx] = map[yy - 1][xx];
for (int xx = 2; xx < 12; ++xx)
map[0][xx] = 0;
if (++lines / LEVEL_LINES > level && level < LEVEL_MAX) level++;
drawMap();
y++;
}
}
}
bringNext();
}
void move(int dx, int dy)
{
putCurrentBlock(0);
blockX += dx;
if (dx && isBlocked()) blockX -= dx;
for (int y = 0; y < dy; y++)
{
blockY++;
if (isBlocked())
{
blockY--;
putCurrentBlock();
release();
return;
}
}
putCurrentBlock();
}
void initStage()
{
lines = 0;
level = 1;
srand((unsigned)time(NULL));
for (int y = 0; y < MAP_HEIGHT; ++y)
for (int x = 0; x < MAP_WIDTH; ++x)
map[y][x] = (x < 2) || (x > 11) || (y > MAP_HEIGHT - 3);
drawMap();
bringNext();
bringNext();
putCurrentBlock();
}
//---------------------------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
initVideo();
initStage();
while (1)
{
for (int i = 0; i < SCAN_COUNT - level; ++i)
{
int isKey = false;
for (; i < SCAN_COUNT - level && !(isKey = _kbhit()); ++i) Sleep(15);
if (isKey)
{
switch (int key = _getch())
{
case 72: // UP
rotate();
break;
case 75: // LEFT
move(-1, 0);
break;
case 77: // RIGHT
move(1, 0);
break;
case 80: // DOWN
move(0, 1);
i = -1;
break;
case 32: // SPACE
move(0, MAP_HEIGHT);
i = -1;
break;
}
}
if (i < SCAN_COUNT - level) Sleep(15);
}
move(0, 1);
}
return 0;
}
//---------------------------------------------------------------------------------------------------
내가 너무 초라해지네요 글내려주십쇼
으앙 ㅠ
워 밤새고 점심시간에 짬내서 짰더니 짜면서 졸려 죽는줄...
수고했긔
신기하다 ㄷㄷ
우와 고수시네요.