리눅스 기반 테트리스 급질문입니다. 부디 답변 부탁드립니다.
글쓴이: demetrio / 작성시간: 수, 2010/07/28 - 8:22오후
안녕하세요,
제가 우분투 상에서 테트리스 코드를 짜봤습니다.
기본적인 기능들은 잘 동작하는데 일정 시간이 지나면 블록이 내려가는 기능이 동작을 안하네요.
강제로 내려보내면 잘 내려가는데 혼자선 절대 안내려가요.
일단 증상을 말씀드리면 아무 버튼이나 막 누르고 있으면 한칸씩 내려가는게 보입니다. 그러나 가만히 놔두면 화면상 블록은 내려가질 않네요. 그렇게 잠시 두다가 뭔가 누르면 순간이동하듯이 저 밑에 내려가 있는걸로 봐선 한칸씩 내려가는 기능이 돌아가고 있긴
한건데 이게 출력으로 나타나질 않습니다. 이문제 해결하려고 시간에 맞춰 내려가는 부분만 따로 스레드로 빼서 돌렸는데 역시 안되네요. 코드 첨부합니다. 제발 아시는 분 답변 부탁드려요. 너무 답답합니다.
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<curses.h>
#include<sys/timeb.h>
#include<term.h>
#include<unistd.h>
#include<termios.h>
#include<pthread.h>
#define LEFT 68
#define RIGHT 67
#define UP 65
#define DOWN 66
#define BH 20
#define BW 10
#define TRUE 1
#define FALSE 0
#define EMPTY 0
#define BRICK 1
#define WALL 2
void DrawScreen();
void DrawBoard();
int ProcessKey();
void PrintBrick(int check);
int GetAround(int x, int y, int b, int r);
int MoveDown();
void TestFull();
int kbhit();
void *t_function(void *data);
static struct termios initial_settings, new_settings;
static int peek_character = -1;
struct timeb utm;
struct Point {
int x, y;
};
struct Point Shape[7][4][4] = {
{{{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},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}}, {{0,0},{-1,0},{1,0},{2,0}}, {{0,0},{0,-1},{0,1},{0,2}}},
{{{0,0},{-1,0},{0,-1},{1,-1}}, {{0,0},{-1,0},{-1,-1},{0,1}}, {{0,0},{-1,0},{0,-1},{1,-1}}, {{0,0},{-1,0},{-1,-1},{0,1}}},
{{{0,0},{0,-1},{-1,-1},{1,0}}, {{0,0},{0,1},{1,0},{1,-1}}, {{0,0},{0,-1},{-1,-1},{1,0}}, {{0,0},{0,1},{1,0},{1,-1}}},
{{{0,0},{-1,0},{-1,-1},{1,0}}, {{0,0},{0,-1},{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},{0,1}}, {{0,0},{-1,0},{0,-1},{0,1}}, {{0,0},{-1,0},{0,-1},{1,0}}, {{0,0},{0,-1},{1,0},{0,1}}}
};
char *arTile[] = {". ", "[]", "||"};
int board[BW+2][BH+2];
int nx, ny;
int brick, rot, up, am, tm, gameover;
int main()
{
initscr();
tcgetattr(fileno(stdin), &initial_settings);
new_settings = initial_settings;
new_settings.c_lflag &= ~ICANON;
pthread_t p_thread[1];
int i, j, thr_id, status;
int a = 1;
system("clear");
for(i=0; i<BW+2; i++)
{
for(j=0; j<BH+2; j++)
{
if(i==0 || j==0 || i==BW+1 || j==BH+1)
{
board[i][j] = WALL;
}
else
{
board[i][j] = EMPTY;
}
}
}
DrawScreen();
thr_id = pthread_create(&p_thread[0], NULL, t_function, (void *)&a);
if(thr_id != 0)
{
perror("thread creation failed");
exit(EXIT_FAILURE);
}
while(1)
{
srand(time(NULL));
brick = rand()%7;
nx = BW/2;
ny = 2;
rot = 0;
PrintBrick(TRUE);
if(GetAround(nx, ny, brick, rot) != EMPTY) break;
while(1)
{
if(ProcessKey() == TRUE)
{
PrintBrick(TRUE);
break;
PrintBrick(TRUE);
}
if(gameover == 2)
{
break;
}
}
if(gameover == 2)
{
break;
}
}
pthread_join(p_thread[0], (void **)&status);
exit(EXIT_SUCCESS);
system("clear");
endwin();
}
void DrawScreen()
{
int x, y;
for(x=0; x<BW+2; x++)
{
for(y=0; y<BH+2; y++)
{
move(5 + y, 15 + x*2);
printw(arTile[board[x][y]]);
}
}
}
void DrawBoard()
{
int x, y;
for(x=1; x<BW+1; x++)
{
for(y=1; y<BH+1; y++)
{
move(5 + y, 15 + x*2);
printw(arTile[board[x][y]]);
}
}
}
int ProcessKey()
{
int getkey;
if(kbhit())
{
PrintBrick(TRUE);
getkey = getch();
PrintBrick(TRUE);
switch(getkey)
{
case -1:
break;
case 27:
PrintBrick(TRUE);
getkey = getch();
PrintBrick(TRUE);
if(getkey == -1)
{
gameover = 2;
break;
}
else if(getkey == 91)
{
PrintBrick(TRUE);
getkey = getch();
PrintBrick(TRUE);
if(getkey == LEFT)
{
if(GetAround(nx-1, ny, brick, rot) == EMPTY)
{
PrintBrick(FALSE);
nx--;
PrintBrick(TRUE);
DrawScreen();
DrawBoard();
}
}
if(getkey == RIGHT)
{
if(GetAround(nx+1, ny, brick, rot) == EMPTY)
{
PrintBrick(FALSE);
nx++;
PrintBrick(TRUE);
DrawScreen();
DrawBoard();
}
}
if(getkey == UP)
{
if(GetAround(nx+1, ny, brick, rot) == EMPTY)
{
PrintBrick(FALSE);
rot++;
rot = rot%4;
if(GetAround(nx, ny, brick, rot) == EMPTY)
{
PrintBrick(TRUE);
DrawScreen();
DrawBoard();
}
}
}
if(getkey == DOWN)
{
if(MoveDown())
{
PrintBrick(TRUE);
return TRUE;
}
}
}
break;
case 'q':
gameover = 2;
break;
}
fflush(stdin);
}
return FALSE;
}
int GetAround(int x, int y, int b, int r)
{
int i;
int a = 0;
for(i=0; i<4; i++)
{
if(a > board[x+Shape[b][r][i].x][y+Shape[b][r][i].y])
{
a = a;
}
else
{
a = board[x+Shape[b][r][i].x][y+Shape[b][r][i].y];
}
}
return a;
}
void PrintBrick(int check)
{
int i;
for(i=0; i<4; i++)
{
move(5 + ny + Shape[brick][rot][i].y, 15 + 2*(nx + Shape[brick][rot][i].x));
if(check == 0)
{
printw(arTile[EMPTY]);
}
else if(check == 1)
{
printw(arTile[BRICK]);
}
}
}
int MoveDown()
{
if(GetAround(nx, ny+1, brick, rot) != EMPTY)
{
TestFull();
return TRUE;
}
PrintBrick(FALSE);
ny++;
PrintBrick(TRUE);
DrawScreen();
DrawBoard();
return FALSE;
}
void TestFull()
{
int x, y, i, ty;
for(i=0; i<4; i++)
{
board[nx + Shape[brick][rot][i].x][ny+Shape[brick][rot][i].y] = BRICK;
}
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(ty=y; ty>1; ty--)
{
for(x=1; x<BW+1; x++)
{
board[x][ty] = board[x][ty-1];
}
}
DrawBoard();
}
}
}
int kbhit()
{
char ch;
int nread;
if(peek_character != -1) return TRUE;
new_settings.c_cc[VMIN] = 0;
tcsetattr(0, TCSANOW, &new_settings);
nread = read(0, &ch, 1);
new_settings.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_settings);
if(nread == TRUE || nread != UP)
{
peek_character = ch;
return TRUE;
}
return FALSE;
}
void *t_function(void *data)
{
ftime(&utm);
tm = utm.millitm + utm.time*1000;
am = tm;
while(1)
{
ftime(&utm);
tm = utm.millitm + utm.time*1000;
if(tm >= am + 500)
{
MoveDown();
am = tm;
}
}
}Forums:


댓글 달기