#include #include #include #include #include #define NORMAL (1) #define VARIABLE_MAP (2) #define SCORE_BOARD (3) #define HARD (4) #define EXIT (0) #define MAP_HEIGHT (20) #define MAP_WIDTH (10) #define LEFT_EDGE (0) #define RIGHT_EDGE (9) #define BOTTOM_EDGE (19) #define BLOCK_SIZE (4) #define BLOCK_DIAG (7) #define DEFAULT_SPACE (0) #define FIXED_SPACE (1) #define LEFT_KEY (75) #define RIGHT_KEY (77) #define UP_KEY (72) #define DOWN_KEY (80) #define SPACE_KEY (' ') #define PAUSE_KEY ('p') #define UNIT_SPEED (10) #define FILE_NAME_LENGTH (100) #define LIST_LENGTH (10) #define NAME_LENGTH (10) typedef struct{ int x; int y; }Point; typedef struct{ Point point_set[BLOCK_SIZE]; int block_diag; int block_dir; Point current_position; }Block; void tRunNormalGame(); void tViewScoreBoard(); void tRunMapSelGame(); int tMakeMap(int map[][MAP_WIDTH]); char* selectMapList(); void tAddScore(char* name, int score); int tIsGameEnd (int map[][MAP_WIDTH]); void tBlockInitial (Block *block, int block_diag); void tManageBlockFlow(int map[][MAP_WIDTH], Block* new_block, Block* next_block, int speed, int score); void tMovingBlock2FixedSpace (int map[][MAP_WIDTH], Block* current_block); void tPrintView (int map[][MAP_WIDTH], Block current_block_pos, int score, int speed); int tConditionalDeletionLines (int map[][MAP_WIDTH]); void tDeleteLine (int map[][MAP_WIDTH], int height); void tCopyLine(int map[][MAP_WIDTH], int from_height, int to_height); int tIsFullLine(int map[][MAP_WIDTH], int height); int tIsFixedBlockSpace(Point check_point, int map[][MAP_WIDTH]); int tIsMovingBlockSpace(Point check_point, Block current_block_pos); void tMoveBlockByKey (int map[][MAP_WIDTH], Block* current_block, int key_input); void tSideMoveBlock (int map[][MAP_WIDTH], Block* current_block, int key_input); void tDownMoveBlock (int map[][MAP_WIDTH], Block* current_block); int tIsTouchWall (Block* current_block, int direction); void tLotateBlock (int map[][MAP_WIDTH], Block* current_block); int tIsTouchBottom (int map[][MAP_WIDTH], Block* current_block); int tIsTouchSideFixedBlock (int map[][MAP_WIDTH], Block* current_block, int direction); const Point block_set[BLOCK_DIAG][4][BLOCK_SIZE] = { { {{-1,-1},{0,-1},{1,-1},{2,-1}}, {{0,-1},{0,0},{0,1},{0,2}}, {{-1,-1},{0,-1},{1,-1},{2,-1}}, {{0,-1},{0,0},{0,1},{0,2}}, // ¡à¡à¡à¡à }, { {{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},{-1,0},{1,-1},{0,0}}, {{0,-1},{0,0},{1,0},{1,1}}, {{0,-1},{-1,0},{1,-1},{0,0}},// ¡à¡à {{0,-1},{0,0},{1,0},{1,1}}, // ¡à¡à }, { {{-1,-1},{0,-1},{0,0},{1,0}}, {{0,0},{0,1},{1,-1},{1,0}}, {{-1,-1},{0,-1},{0,0},{1,0}},// ¡à¡à {{0,0},{0,1},{1,-1},{1,0}}, // ¡à¡à }, { {{-1,0},{0,0},{1,0},{0,-1}}, {{1,0},{0,-1},{0,0},{0,1}}, {{-1,-1},{0,-1},{1,-1},{0,0}}, // ¡à¡à¡à {{-1,0},{0,-1},{0,0},{0,1}}, // ¡à }, { {{-1,0},{0,0},{1,0},{-1,-1}}, {{0,-1},{-1,-1},{-1,0},{-1,1}}, {{-1,-1},{0,-1},{1,-1},{1,0}}, // ¡à¡à¡à {{0,1},{1,-1},{1,0},{1,1}}, // ¡à }, { {{-1,0},{0,0},{1,0},{1,-1}}, {{1,1},{0,-1},{0,0},{0,1}}, {{-1,-1},{0,-1},{1,-1},{-1,0}}, // ¡à¡à¡à {{0,-1},{1,-1},{1,0},{1,1}}, // ¡à } }; int main (void) { int select; while(TRUE) { system("cls"); printf("--------- TETRIS ----------\n\n"); printf("---------- Menu ----------\n"); printf(" 1. Normal Mode\n 2. Map Selection Mode\n 3. Score Board\n 0. Exit\n\n Select : "); scanf("%d",&select); switch(select) { case NORMAL: tRunNormalGame(); break; case VARIABLE_MAP: tRunMapSelGame(); break; case SCORE_BOARD: tViewScoreBoard(); break; case HARD: case EXIT: printf("\nÇÁ·Î±×·¥À» Á¾·áÇÕ´Ï´Ù.\n"); return 0; default: printf("\nÀ߸øµÈ ÀÔ·ÂÀÔ´Ï´Ù. ´Ù½Ã ¼±ÅÃÇØÁÖ¼¼¿ä.\n"); fflush(stdin); getchar(); } } } void tPrintView (int map[][MAP_WIDTH], Block current_block_pos, int score, int speed) { int i,j; Point tmp; system("cls"); printf("\n\n"); for(i=0;i=0;height--) { if(tIsFullLine(map, height)) { tDeleteLine(map, height); height++; score += (++bonus_score); } } return score; } void tDeleteLine (int map[][MAP_WIDTH], int height) { int i; if(height>=MAP_HEIGHT||height<0) return; for(i=height;i>0;i--) { tCopyLine(map,i-1,i); } } void tCopyLine(int map[][MAP_WIDTH], int from_height, int to_height) { int i; for(i=0;ipoint_set[0].x -= 1; current_block->point_set[1].x -= 1; current_block->point_set[2].x -= 1; current_block->point_set[3].x -= 1; current_block->current_position.x -= 1; } else if( key_input==RIGHT_KEY && !tIsTouchWall(current_block, RIGHT_KEY) && !tIsTouchSideFixedBlock(map, current_block, RIGHT_KEY)) { current_block->point_set[0].x += 1; current_block->point_set[1].x += 1; current_block->point_set[2].x += 1; current_block->point_set[3].x += 1; current_block->current_position.x += 1; } } void tDownMoveBlock (int map[][MAP_WIDTH], Block* current_block) { if(!tIsTouchBottom(map, current_block)) { current_block->point_set[0].y += 1; current_block->point_set[1].y += 1; current_block->point_set[2].y += 1; current_block->point_set[3].y += 1; current_block->current_position.y += 1; } } int tIsTouchWall (Block* current_block, int direction) { int i; if(direction==LEFT_KEY) { for(i=0;i<4;i++){ if(current_block->point_set[i].x<=0) { return 1; } } return 0; } else if(direction==RIGHT_KEY) { for(i=0;i<4;i++){ if(current_block->point_set[i].x>=MAP_WIDTH-1) { return 1; } } return 0; } } int tIsTouchSideFixedBlock (int map[][MAP_WIDTH], Block* current_block, int direction) { int i; if(direction==LEFT_KEY) for(i=0;i<4;i++) { if(map[current_block->point_set[i].y][current_block->point_set[i].x-1]==FIXED_SPACE) { return 1; } } else if(direction==RIGHT_KEY) for(i=0;i<4;i++) { if(map[current_block->point_set[i].y][current_block->point_set[i].x+1]==FIXED_SPACE) { return 1; } } return 0; } void tLotateBlock (int map[][MAP_WIDTH], Block* current_block) { int i; Block temp_block = *current_block; current_block->block_dir = (current_block->block_dir+1)%4; current_block->point_set[0].x = block_set[current_block->block_diag][current_block->block_dir][0].x+current_block->current_position.x; current_block->point_set[0].y = block_set[current_block->block_diag][current_block->block_dir][0].y+current_block->current_position.y; current_block->point_set[1].x = block_set[current_block->block_diag][current_block->block_dir][1].x+current_block->current_position.x; current_block->point_set[1].y = block_set[current_block->block_diag][current_block->block_dir][1].y+current_block->current_position.y; current_block->point_set[2].x = block_set[current_block->block_diag][current_block->block_dir][2].x+current_block->current_position.x; current_block->point_set[2].y = block_set[current_block->block_diag][current_block->block_dir][2].y+current_block->current_position.y; current_block->point_set[3].x = block_set[current_block->block_diag][current_block->block_dir][3].x+current_block->current_position.x; current_block->point_set[3].y = block_set[current_block->block_diag][current_block->block_dir][3].y+current_block->current_position.y; for(i=0;i<4;i++) { if(current_block->point_set[i].x<0 || current_block->point_set[i].x>=10) { *current_block = temp_block; return; } if(map[current_block->point_set[i].y][current_block->point_set[i].x]==FIXED_SPACE) { *current_block = temp_block; return; } } } int tIsTouchBottom (int map[][MAP_WIDTH], Block* current_block) { int i; for(i=0;i<4;i++) { if(map[current_block->point_set[i].y+1][current_block->point_set[i].x]==FIXED_SPACE || current_block->point_set[i].y==MAP_HEIGHT-1) { return 1; } } return 0; } void tMovingBlock2FixedSpace (int map[][MAP_WIDTH], Block* current_block) { int i; for(i=0;i<4;i++) map[current_block->point_set[i].y][current_block->point_set[i].x]=FIXED_SPACE; } void tManageBlockFlow(int map[][MAP_WIDTH], Block* new_block, Block* next_block, int speed, int score) { int i; char key_input; Block current_block = *new_block; tPrintView(map,current_block, score, speed); while(TRUE) { for(i=0;iblock_diag = block_diag; block->block_dir = 0; block->current_position.x = 4; block->current_position.y = 1; block->point_set[0].x = block_set[block_diag][block->block_dir][0].x+block->current_position.x; block->point_set[0].y = block_set[block_diag][block->block_dir][0].y+block->current_position.y; block->point_set[1].x = block_set[block_diag][block->block_dir][1].x+block->current_position.x; block->point_set[1].y = block_set[block_diag][block->block_dir][1].y+block->current_position.y; block->point_set[2].x = block_set[block_diag][block->block_dir][2].x+block->current_position.x; block->point_set[2].y = block_set[block_diag][block->block_dir][2].y+block->current_position.y; block->point_set[3].x = block_set[block_diag][block->block_dir][3].x+block->current_position.x; block->point_set[3].y = block_set[block_diag][block->block_dir][3].y+block->current_position.y; } int tIsGameEnd (int map[][MAP_WIDTH]) { if(map[0][3]==FIXED_SPACE || map[0][4]==FIXED_SPACE || map[0][5]==FIXED_SPACE || map[0][6]==FIXED_SPACE) return 1; else return 0; } void tRunNormalGame () { int map[MAP_HEIGHT][MAP_WIDTH]={0}; int score = 0; int speed=100; char player[NAME_LENGTH]; Block tmp1,tmp2; srand(time(NULL)); tBlockInitial(&tmp1,rand()%7); while(1){ // ´ÙÀ½ºí·ÏÀ» »ý¼ºÇÏ°í, // ÇϳªÀÇ ºí·Ï¿¡ ´ëÇÑ È帧 °ü¸®(ÇÔ¼ö È°¿ë) // ¸Ê¿¡¼­ ¿Ï¼ºµÈ °¡·ÎÁÙ »èÁ¦ ¹× ½ºÄÚ¾î °»½Å // (ºí·ÏÀÌ ¶³¾îÁö´Â ¼Óµµ¸¦ ÀÚÀ¯·Î¿î Á¶°Ç ÇÏ¿¡¼­ Á¶ÀýÇϵµ·Ï ÇÒ °Í) // °ÔÀÓÀÌ ³¡³µ´ÂÁö È®ÀÎÇÏ°í, // Ç÷¹À̾îÀÇ À̸§À» ÀÔ·Â¹Þ¾Æ // ½ºÄÚ¾î¿Í ÇÔ²² ScoreBoard.txt¿¡ ±â·Ï // ÀÌÈÄ Á¾·á } void tRunMapSelGame() { // ´ë´Ù¼ö ±â´ÉÀº tRunNormalGame() ÇÔ¼ö¿Í µ¿ÀÏ // ºí·ÏÀ» »ý¼ºÇÏ¿© ¶³¾î¶ß¸®±â Àü¿¡, ¸Ê ÆÄÀÏÀ» ¼±ÅÃÇÏ¿© Àаí ÆÄÀÏ ³»¿ë¿¡ µû¶ó ¸ÊÀ» ¼öÁ¤ // ½ºÄÚ¾î´Â ±â·ÏÇÏÁö ¾ÊÀ½ } int tMakeMap (int map[][MAP_WIDTH]) { int x,y; char * file_name = selectMapList(); FILE * fp = NULL; if(!file_name) return FALSE; fp = fopen(file_name,"r"); if(fp==NULL) { printf("ÆÄÀÏÀÌ ¾ø½À´Ï´Ù.\n"); fflush(stdin); getchar(); return FALSE; } while(2==fscanf(fp,"%d,%d",&y,&x)) { if(x>=0&&x<10&&y>=0&&y<20) map[y][x]=FIXED_SPACE; } return TRUE; } char* selectMapList () { int file_count=1, file_number; FILE * fp = fopen("mapList.txt","r"); char * file_name = (char*)malloc(sizeof(char)*FILE_NAME_LENGTH); if(fp==NULL) { printf("ÆÄÀÏÀÌ ¾ø½À´Ï´Ù.\n"); fflush(stdin); getchar(); return 0; } printf("------- Map List -------\n"); while(fgets(file_name,FILE_NAME_LENGTH,fp)!=NULL) printf("%3d. %s",file_count++,file_name); printf("\n------------------------\n"); rewind(fp); printf("Select File-Number : "); fflush(stdin); scanf("%d",&file_number); if((file_count