/* mine.c: 기 (TUI) : win32 console program : C : : 2010 12 24 1 : 2010 12 29*/ #include<stdio.h> #include<stdlib.h> #include<time.h> #include<conio.h> #include<windows.h> #define TRUE 1 #define FALSE 0 //#define NO_STATE 3 typedef struct cell//1개 구 { int iIsRevealed; int iIsMine; int iNumOfMine;// 개 int iIsUnknown; int iIsFined; }CELL; COORD* make_mine_map(CELL** map,COORD size,int iNumOfMine); void print_map(CELL** map,COORD size,int iNumOfMine,int iCurrentFindedMine); int click_cell(CELL** map,COORD size,int *iNumOfLeftCell); void one_right_click_cell(CELL** map,COORD size,COORD *cPosOfMine,int iNumOfMine,int *iFindedRealMine); void double_right_click_cell(CELL** map,COORD size); void find_mine(CELL** map,COORD size,COORD pos,int *iNumOfLeftCell); void count_time(int iSecond); void print_one_cell(CELL** map,int xpos,int ypos,int mine); COORD coord_input(COORD size); void initialize_cell(CELL *input); int search_mine(int iNumOfMine,COORD* real_mine_cell,COORD target_cell); int main(int argc,char* argv[]) { CELL **map; COORD size; COORD *cPosOfMine; int iNumOfMine,iCurrentFindedMine=0,iNumOfLeftCell,iIsAlive=TRUE,tempX,tempY,iFindedRealMine=0,i,j; time_t tStartTime,tEndTime; char cSelect; /*걍 고 */ for(i=0;i<5;i++) printf("*****************************************************************************\n"); printf("********** **********\n"); printf("********** **********\n"); printf("********** **********\n"); printf("********** 기 **********\n"); printf("********** **********\n"); printf("********** **********\n"); printf("********** **********\n"); printf("********** **********\n"); printf("********** 거 *********\n"); for(i=0;i<5;i++) printf("\*****************************************************************************\n"); /*map */ if(argc==4){//argument 경 size.X=(short)atoi(argv[1]); size.Y=(short)atoi(argv[2]); } else{//argument 경 printf(" ( ): "); scanf("%d %d",&tempX,&tempY); size.X=tempX; size.Y=tempY; } map=(CELL**)malloc(sizeof(CELL)*size.Y);//1 for(i=0;i<size.Y;i++){ map[i]=(CELL*)malloc(sizeof(CELL)*size.X);//2 for(j=0;j<size.X;j++) initialize_cell(&map[i][j]);//기 } if(argc==4) iNumOfMine=atoi(argv[3]);////argument 개 경 else{ printf(" 개 : "); scanf("%d",&iNumOfMine); } cPosOfMine=make_mine_map(map,size,iNumOfMine); iNumOfLeftCell=size.X*size.Y; printf(" 공 .\n3 게 .\n"); count_time(3); //system("pause"); /*게 */ time(&tStartTime);//간 do{ print_map(map,size,iNumOfMine,iCurrentFindedMine); printf(" \na: 기\ts: \td: 기 겠\tq: "); cSelect=getch(); fflush(stdin); cSelect=tolower(cSelect); switch(cSelect){ case 'a': iIsAlive=click_cell(map,size,&iNumOfLeftCell); if(iIsAlive==FALSE){ printf(" \n"); system("pause");// 까 } break; case 's': one_right_click_cell(map,size,cPosOfMine,iNumOfMine,&iFindedRealMine); iCurrentFindedMine++; break; case 'd': double_right_click_cell(map,size); break; case 'q': for(i=0;i<size.Y;i++) free(map[i]);//2 free(map); free(cPosOfMine); printf("게 .\n: 게 까\n"); system("pause"); exit(0); break; default: printf(" ."); } }while(iNumOfLeftCell>iNumOfMine && iIsAlive==TRUE && iFindedRealMine!=iNumOfMine); time(&tEndTime);//간 free(cPosOfMine); /* */ system("cls"); if(iIsAlive==TRUE) printf("! .\a\a\a\n"); else if(iIsAlive==FALSE) printf(" .\a\a\n"); else printf("Unproteted error is occured!\a"); /* */ for(i=0;i<size.Y;i++){ for(j=0;j<size.X;j++) print_one_cell(map,j,i,TRUE); free(map[i]);//2 Sleep(500); printf("\n"); } free(map);//1 printf("간: %ldsec.\n",tEndTime-tStartTime);//간 printf("2010 거 \n"); system("pause"); return 0; } COORD* make_mine_map(CELL **map,COORD size,int iNumOfMine) { int i,j; static COORD *pos_data; //FILE *txtForDebug=fopen("mine_pos.txt","w"); srand(time(NULL)); pos_data=(COORD*)malloc(sizeof(COORD)*iNumOfMine);// 개 /* */ for(i=0;i<iNumOfMine;){ pos_data[i].X=rand()%size.X; pos_data[i].Y=rand()%size.Y; /* */ for(j=0;j<i;j++) if(pos_data[i].X==pos_data[j].X && pos_data[i].Y==pos_data[j].Y) continue;// 기 i++; } /* 깅 */ for(i=0;i<iNumOfMine;i++){ //printf("%d: %d %d\n",i,pos_data[i].X,pos_data[i].Y); map[pos_data[i].Y][pos_data[i].X].iIsMine=TRUE; //fprintf(txtForDebug,"%d: %d %d\n",i,(int)pos_data[i].X,(int)pos_data[i].Y); } //system("pause"); return pos_data; } void print_map(CELL **map,COORD size,int iNumOfMine,int iCurrentFindedMine) { int xIndex,yIndex; system("cls"); for(yIndex=-1;yIndex<size.Y;yIndex++){ for(xIndex=-1;xIndex<size.X;xIndex++){ if(yIndex==-1){ if(xIndex==-1) printf(" "); else printf("%d ",xIndex); } else if(xIndex==-1) printf("%d",yIndex); else{ print_one_cell(map,xIndex,yIndex,FALSE); } } printf("\n"); } printf(" 개: %d\n",iNumOfMine-iCurrentFindedMine); } int click_cell(CELL** map,COORD size,int *iNumOfLeftCell) { COORD input=coord_input(size); if(map[input.Y][input.X].iIsRevealed==TRUE) return TRUE;// 깐 경 else if(map[input.Y][input.X].iIsMine==TRUE) return FALSE;// 경 else find_mine(map,size,input,&(*iNumOfLeftCell)); return TRUE; } void one_right_click_cell(CELL **map,COORD size,COORD *cPosOfMine,int iNumOfMine,int *iFindedRealMine) { COORD input=coord_input(size); if(map[input.Y][input.X].iIsRevealed==TRUE) return;// 깐 경 else{ if(map[input.Y][input.X].iIsFined==TRUE) map[input.Y][input.X].iIsFined=FALSE; else map[input.Y][input.X].iIsFined=TRUE; } if(search_mine(iNumOfMine,cPosOfMine,input)==TRUE) (*iFindedRealMine)++; } void double_right_click_cell(CELL **map,COORD size) { COORD input=coord_input(size); if(map[input.Y][input.X].iIsRevealed==TRUE) return;// 깐 경 else{ if(map[input.Y][input.X].iIsUnknown==FALSE) map[input.Y][input.X].iIsUnknown=TRUE; else map[input.Y][input.X].iIsUnknown=FALSE; } } void find_mine(CELL **map,COORD size,COORD pos,int *iNumOfLeftCell) { int iNumOfMine=0,coordX,coordY; COORD temp_pos=pos; if(map[pos.Y][pos.X].iIsMine==TRUE) return;// map[pos.Y][pos.X].iIsRevealed=TRUE;//까 (*iNumOfLeftCell)--; for(coordY=-1;coordY<=1;coordY++){ for(coordX=-1;coordX<=1;coordX++){ temp_pos=pos; if(coordX==0 && coordY==0) continue;//기 temp_pos.X=pos.X+coordX; temp_pos.Y=pos.Y+coordY; if((temp_pos.X>size.X-1 || temp_pos.X<0) || (temp_pos.Y>size.Y-1 || temp_pos.Y<0)) continue;// 과 경 else if(map[temp_pos.Y][temp_pos.X].iIsRevealed==TRUE) continue;// 깐 경 else if(map[temp_pos.Y][temp_pos.X].iIsMine==TRUE) iNumOfMine++; } } map[pos.Y][pos.X].iNumOfMine=iNumOfMine;// 개 if(map[pos.Y][pos.X].iNumOfMine!=0) return;// 개 0개 else{// for(coordY=-1;coordY<=1;coordY++){ for(coordX=-1;coordX<=1;coordX++){ temp_pos=pos; temp_pos.X+=coordX; temp_pos.Y+=coordY; if((temp_pos.X>size.X-1 || temp_pos.X<0) || (temp_pos.Y>size.Y-1 || temp_pos.Y<0)) continue;// 과 경 if(coordX==0 && coordY==0) continue;//기 경. stack overflow if(map[temp_pos.Y][temp_pos.X].iIsRevealed==TRUE) continue;// 경 find_mine(map,size,temp_pos,&(*iNumOfLeftCell)); } } } } void count_time(int iSecond) { for(;iSecond>0;iSecond--){ printf("%d\a ",iSecond); Sleep(1000); } printf("%d\a\n",iSecond); } void print_one_cell(CELL **map,int xpos,int ypos,int mine) { if(map[ypos][xpos].iIsRevealed==TRUE){ if(mine==TRUE && map[ypos][xpos].iIsMine==TRUE) printf(" *"); else if(map[ypos][xpos].iNumOfMine==0) printf("□"); else printf(" %d",map[ypos][xpos].iNumOfMine); } else{ if(map[ypos][xpos].iIsFined==TRUE) printf(" m"); else if(map[ypos][xpos].iIsUnknown==TRUE) printf(" ?"); else if(mine==TRUE && map[ypos][xpos].iIsMine) printf(" *"); else printf("■"); } } COORD coord_input(COORD size) { COORD temp; int tempX,tempY; printf(" (x y): "); scanf("%d %d",&tempX,&tempY); temp.X=(short)tempX; temp.Y=(short)tempY; while(temp.X<0 || temp.X>size.X-1 || temp.Y<0 || temp.Y>size.Y-1){ printf(" . .\n (x y): "); scanf("%d %d",&tempX,&tempY); temp.X=(short)tempX; temp.Y=(short)tempY; } return temp; } void initialize_cell(CELL *input) { input->iIsFined=FALSE; input->iIsMine=FALSE; input->iIsRevealed=FALSE; input->iIsUnknown=FALSE; } int search_mine(int iNumOfMine,COORD *real_mine_cell,COORD target_cell) { int i; for(i=0;i<iNumOfMine;i++) if(real_mine_cell[i].X==target_cell.X && real_mine_cell[i].Y==target_cell.Y) return TRUE; return FALSE; }
게 기 .
그 구, 깨.
그 구, 깨.
근 그 거 ㅠ