리눅스 기반 테트리스 급질문입니다. 부디 답변 부탁드립니다.
글쓴이: 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:
댓글 달기