반응형
출처
soen.kr
#include "Turboc.h"
#define LEFT 75
#define RIGHT 77
#define UP 72
#define DOWN 80
#define ESC 27
#define BX 5
#define BY 1
#define BW 10
#define BH 20
void DrawScreen();
void DrawBoard();
bool ProcessKey();
void PrintBrick(bool show);
int GetAround(int x, int y, int b, int r);
bool MoveDown();
void TestFull();
struct Point {
int x, y;
};
Point Shape[][4][4] = {
{ {0,0,1,0,2,0,-1,0}, {0,0,0,1,0,-1,0,-2}, {0,0,1,0,2,0,-1,0}, {0,0,0,1,0,-1,0,-2} },
{ {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1}, {0,0,1,0,0,1,1,1} },
{ {0,0,-1,0,0,-1,1,-1}, {0,0,0,1,-1,0,-1,-1}, {0,0,-1,0,0,-1,1,-1}, {0,0,0,1,-1,0,-1,-1} },
{ {0,0,-1,-1,0,-1,1,0}, {0,0,-1,0,-1,1,0,-1}, {0,0,-1,-1,0,-1,1,0}, {0,0,-1,0,-1,1,0,-1} },
{ {0,0,-1,0,1,0,-1,-1}, {0,0,0,-1,0,1,-1,1}, {0,0,-1,0,1,0,1,1}, {0,0,0,-1,0,1,1,-1} },
{ {0,0,1,0,-1,0,1,-1}, {0,0,0,1,0,-1,-1,-1}, {0,0,1,0,-1,0,-1,1}, {0,0,0,-1,0,1,1,1} },
{ {0,0,-1,0,1,0,0,1}, {0,0,0,-1,0,1,1,0}, {0,0,-1,0,1,0,0,-1}, {0,0,-1,0,0,-1,0,1} },
};
enum {EMPTY, BRICK, WALL};
const char* arTile[] = { ". ","■", "□" };
int board[BW + 2][BH + 2];
int nx, ny;
int brick, rot;
int main() {
int nFrame, nStay;
setcursortype(NOCURSOR);
randomize();
clrscr();
for (int x = 0; x < BW + 2; x++) {
for (int y = 0; y < BH + 2; y++) {
board[x][y] = (y == 0 || y == BH + 1 || x == 0 || x == BW + 1) ? WALL : EMPTY;
}
}
DrawScreen();
nFrame = 20;
while (true) {
brick = random(sizeof(Shape) / sizeof(Shape[0]));
nx = BW / 2;
ny = 3;
rot = 0;
PrintBrick(true);
if (GetAround(nx, ny, brick, rot) != EMPTY) break;
nStay = nFrame;
while (true) {
if (--nStay == 0) {
nStay = nFrame;
if (MoveDown()) break;
}
if (ProcessKey()) break;
delay(1000 / 20);
}
}
clrscr();
gotoxy(30, 12); puts(" G A M E O V E R");
setcursortype(NORMALCURSOR);
}
void DrawScreen()
{
for (int x = 0; x < BW + 2; x++) {
for (int y = 0; y < BH + 2; y++) {
gotoxy(BX + x * 2, BY + y);
puts(arTile[board[x][y]]);
}
}
gotoxy(50, 3); puts("Tetris Ver 1.0");
gotoxy(50, 5); puts("좌우:이동, 위:회전, 아래:내림");
gotoxy(50, 6); puts("공백: 전부 내림");
}
void DrawBoard()
{
for (int x = 1; x < BW + 1; x++) {
for (int y = 1; y < BH + 1; y++) {
gotoxy(BX + x * 2, BY + y);
puts(arTile[board[x][y]]);
}
}
}
bool ProcessKey()
{
int trot;
if (_kbhit()) {
int ch = _getch();
if (ch == 0xE0 || ch == 0) {
ch = _getch();
switch (ch) {
case LEFT:
if (GetAround(nx - 1, ny, brick, rot) == EMPTY) {
PrintBrick(false);
nx--;
PrintBrick(true);
}
break;
case RIGHT:
if (GetAround(nx + 1, ny, brick, rot) == EMPTY) {
PrintBrick(false);
nx++;
PrintBrick(true);
}
break;
case UP:
trot = (rot == 3 ? 0 : rot + 1);
if (GetAround(nx, ny, brick, rot) == EMPTY) {
PrintBrick(false);
rot = trot;
PrintBrick(true);
}
break;
case DOWN:
if (MoveDown()) {
return true;
}
break;
}
} else {
switch (ch) {
case ' ':
while (MoveDown() == false) { ; }
return true;
}
}
}
return false;
}
void PrintBrick(bool Show)
{
for (int i = 0; i < 4; i++) {
gotoxy(BX + (Shape[brick][rot][i].x + nx) * 2, BY + Shape[brick][rot][i].y + ny);
puts(arTile[Show ? BRICK : EMPTY]);
}
}
int GetAround(int x, int y, int b, int r)
{
int k = EMPTY;
for (int i = 0; i < 4; i++) {
k = max(k, board[x + Shape[b][r][i].x][y + Shape[b][r][i].y]);
}
return k;
}
bool MoveDown()
{
if (GetAround(nx, ny + 1, brick, rot) != EMPTY) {
TestFull();
return true;
}
PrintBrick(false);
ny++;
PrintBrick(true);
return false;
}
void TestFull() {
for (int i = 0; i < 4; i++) {
board[nx + Shape[brick][rot][i].x][ny + Shape[brick][rot][i].y] = BRICK;
}
int x, y;
for (y = 1; y < BH + 1; y++) {
for (x = 1; x < BW + 1; x++) {
if (board[x][y] != BRICK) break;
}
if (x == BW + 1) {
for (int ty = y; ty > 1; ty--) {
for (x = 1; x < BW + 1; x++) {
board[x][ty] = board[x][ty - 1];
}
}
DrawBoard();
delay(200);
}
}
}
■ 이번 예제는 기능이 함수들로 좀 쪼개져 있어서 나은 편이다.
■ 테트리스는 누구나 아는 게임이라 재밌다.
반응형