c언어 테트리스 코드 짜기 질문이요ㅜ 주석처리부분 도와주세요ㅜ

rnghksgml의 이미지

c언어로 구조체와 파일입출력 사용으로 테트리스 코드 짜기인데 너무 어렵네요ㅜ c언어 천재님들 좀 도와주세요ㅠㅠ주석처리 한 부분 알려주세요..

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
 
#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<MAP_HEIGHT;i++)
	{
		printf("  ■");
		for(j=0;j<MAP_WIDTH;j++)
		{
			tmp.y=i;
			tmp.x=j;
			if(tIsMovingBlockSpace(tmp, current_block_pos)) printf("□");
			else if(tIsFixedBlockSpace(tmp, map)) printf("▨");
			else	printf("  ");
		}
		printf("■");
		switch(i){
		case 0:  printf(""); break;
		case 1:  printf("\tNext Block"); break;
		case 2:  printf(""); break;
		case 3:  printf(""); break;
		case 4:  printf(""); break;
		case 5:  printf(""); break;
		case 6:  printf(""); break;
		case 7:  printf(""); break;
		case 8:  printf(""); break;
		case 9:  printf("\tKey"); break;
		case 10: printf("\t↑:블록방향 전환"); break;
		case 11: printf("\t←:좌측이동 →:우측이동"); break;
		case 12: printf("\t↓:아래로 한 칸 이동"); break;
		case 13: printf("\tspace bar:아래 끝으로 이동"); break;
		case 14: printf(""); break;
		case 15: printf(""); break;
		case 16: printf("\tSpeed : %d",speed); break;
		case 17: printf(""); break;
		case 18: printf("\tScore : %d",score); break;
		case 19: printf(""); break;
		}
		printf("\n");
	}
	printf("  ■■■■■■■■■■■■");
}
 
int tConditionalDeletionLines (int map[][MAP_WIDTH])
{
	int height;
	int score=0;
	int bonus_score=0;
	for(height=MAP_HEIGHT-1;height>=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;i<MAP_WIDTH;i++)
	{
		map[to_height][i]=map[from_height][i];
	}
}
int tIsFullLine(int map[][MAP_WIDTH], int height)
{
	return (
	map[height][0] &&map[height][1] &&map[height][2] &&map[height][3] 
	&&map[height][4] &&map[height][5] &&map[height][6] 
	&&map[height][7] &&map[height][8] &&map[height][9]
	);
}
 
int tIsFixedBlockSpace(Point check_point, int map[][MAP_WIDTH])
{
	return (map[check_point.y][check_point.x]==FIXED_SPACE);
}
 
int tIsMovingBlockSpace(Point check_point, Block current_block_pos)
{
	int i;
	for(i=0;i<4;i++){
		if(current_block_pos.point_set[i].x==check_point.x && current_block_pos.point_set[i].y==check_point.y)
			return 1;
	}
	return 0;
}
void tMoveBlockByKey (int map[][MAP_WIDTH], Block* current_block, int key_input)
{
	switch(key_input){
	case LEFT_KEY:
	// 적절히 함수를 활용
	case RIGHT_KEY:
	// 적절히 함수를 활용
		break;
	case UP_KEY:
	// 적절히 함수를 활용
		break;
	case DOWN_KEY:
	// 적절히 함수를 활용
		break;
	case SPACE_KEY:
	// 적절히 함수를 활용
		break;
	default: 
		break;
	}
}
void tSideMoveBlock (int map[][MAP_WIDTH], Block* current_block, int key_input)
{
	if(	key_input==LEFT_KEY && 
		!tIsTouchWall(current_block, LEFT_KEY) &&
		!tIsTouchSideFixedBlock(map, current_block, LEFT_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;
	}
	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;i<speed+5;i++){ 
			Sleep(UNIT_SPEED);
			if(_kbhit())
			{
				key_input=_getch();
				if(key_input==-32)
					key_input=_getch();
				// 키에 맞게 블록을 움직임
			}
 
		} // UNIT_SPEED * speed 의 시간
		// 블록을 한칸 내림
 
		// while 내부에서 적당한 위치에
		// 블록이 바닥에 접촉했을 때, 블록을 고정 된 영역으로 바꾸고, 함수를 종료시킬 수 있도록 해야함
		// 블록의 변화에 따라 tPrintView() 함수로 출력을 다시 해야 함
	}
}
 
void tBlockInitial (Block* block, int block_diag)
{
	block->block_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<file_number+1)||(file_number<1)) return 0;
 
	while((--file_number)!=0)
		fgets(file_name,FILE_NAME_LENGTH,fp);
	fgets(file_name,FILE_NAME_LENGTH,fp);
	file_name[strlen(file_name)-1]=0;
	printf("%s",file_name);
	fclose(fp);
 
	return file_name;
}
 
void tViewScoreBoard()
{
	// ScoreBoard.txt 파일을 읽고,
	// 형식에 맞게 순차적으로 출력
}
 
void tAddScore(char* name, int score)
{
	int i,j,length=0;
	char name_list[_LENGTH][NAME_LENGTH];
	int score_list[_LENGTH];
 
	FILE * fp;
 
	// ScoreBoard.txt 파일을 읽고,
	// 순차적으로 배열에 저장한 뒤
	// ScoreBoard.txt 파일에 재저장
	// 인자로 받은 스코어가 ScoreBoard.txt에 기록된 스코어보다 높다면
	// 그 자리에 인자로 받은 사용자 이름과 스코어를 기록하고,
	// 하나씩 미루어 저장
	// 제한은 10개를 넘지 않는다.
}
[/][/]
File attachments: 
첨부파일 크기
Plain text icon 테트리스 코드.txt15.02 KB
김정균의 이미지

소스 코드는 <code> ~ </code> 블럭을 이용해서 올려 주세요. 그래야 코드가 소실 되지 않고 들여쓰기도 제대로 보입니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.