| [ QuizWit ] in KIDS 글 쓴 이(By): parsec ( 먼 소 류 ) 날 짜 (Date): 2003년 3월 13일 목요일 오전 11시 21분 40초 제 목(Title): 여전히 허접한 장서가 프로그램 약간 업데이트했습니다. p(사람 추가), d(문 위치 설정), h(help)명령을 추가했습니다. move명령을 좀 더 단순화시키거나, curses라이브러리를 사용하면 좀더 인터페이스가 편리할 것 같은데 귀찮아서 아직 거기까진 손대지 못했습니다. ----------------------------------------------- C로 대강 짜봤습니다. 일단 시뮬레이션만 할 수 있도록... (한 칸씩만 움직일 수 있습니다.) 오픈소스입니다. 서브루틴을 고치거나 이용해서 더 좋은 프로그렘을 만들어 주시면 감사하겠습니다 ^^ study.c 와 study.init화일 두 개로 돼 있습니다. study.init화일을 편집해서 초기화 시킬 수 있습니다. 이 화일이 없으면 디폴트로 cdpark님의 풀이로 초기화됩니다. --------------- study.init ------------------- set a1 south fix set b1 south hor set c1 south hor set d1 south ver set a2 south hor set b2 south ver set a3 south hor set b3 south hor set c3 south ver set d3 south hor set a4 south ver set b4 south ver set c4 south hor set d4 west fix p d2 d 2 --------------- end of study.init ------------ ---------------- study.c --------------------- #include <stdio.h> #define ROOM_HEIGHT 4 #define ROOM_WIDTH 4 #define IMG_HEIGHT (ROOM_HEIGHT*3+2) #define IMG_WIDTH (ROOM_WIDTH*6+4) #define NONE 0 #define NORTH 1 #define SOUTH 2 #define EAST 3 #define WEST 4 #define FIX 0 #define VER 1 #define HOR 2 #define ANY 3 typedef struct bookcase { int id; int face; int dir; int x; int y; struct bookcase *next; } t_bookcase; int room[ROOM_HEIGHT][ROOM_WIDTH]; int case_count=0; void draw_case(t_bookcase *bc); void move_case(int pos_x, int pos_y, int dest_x, int dest_y); int get_caseid(int pos_x, int pos_y); t_bookcase* get_casep(int cid); void set_case(int pos_x, int pos_y, int face, int dir); void set_dabb(int pos_x, int pos_y); void reset_case(int caseid); void draw_study(void); void draw_door(void); void set_door(int pos); void init_study(void); void init_img(void); void draw_prompt(void); int get_command(void); char cmdbuf[80]; int cmdbufidx; unsigned char cmd; int pos; int dest; int face; int dir; int door_pos; unsigned char img_buf[IMG_HEIGHT][IMG_WIDTH+1]; t_bookcase *head = NULL; t_bookcase *curr = NULL; void init_study(void) { int i; for(i=0; i<ROOM_HEIGHT*ROOM_WIDTH; i++) room[i/ROOM_WIDTH][i%ROOM_WIDTH] = 0; } void init_img(void) { int i; for(i=0; i<IMG_HEIGHT*IMG_WIDTH; i++) img_buf[i/IMG_WIDTH][i%IMG_WIDTH] = ' '; img_buf[0][0] = img_buf[0][IMG_WIDTH-1] = \ img_buf[IMG_HEIGHT-1][0] = img_buf[IMG_HEIGHT-1][IMG_WIDTH-1] = '+'; for(i=1;i<IMG_HEIGHT-1; i++) { img_buf[i][0] = img_buf[i][IMG_WIDTH-1] = '|'; img_buf[i][IMG_WIDTH] = '\0'; } for(i=1;i<IMG_WIDTH-1; i++) img_buf[0][i] = img_buf[IMG_HEIGHT-1][i] = '-'; } int get_caseid(int pos_x, int pos_y) { return room[pos_x-1][pos_y-1]; } t_bookcase* get_casep(int caseid) { if (head == NULL) return NULL; curr = head; while(curr->next != NULL && curr->id != caseid) curr = curr->next; return curr; } void set_case(int pos_x, int pos_y, int face, int dir) { if(pos_x<1 || pos_x>ROOM_WIDTH || pos_y<1 || pos_y>ROOM_HEIGHT) return; if(case_count < ROOM_HEIGHT*ROOM_WIDTH && room[pos_x-1][pos_y-1] == 0) { case_count++; curr = head; if(curr != NULL) { while(curr->next != NULL) curr = curr->next; curr->next = (t_bookcase *)malloc(sizeof(t_bookcase)); curr = curr->next; } else { curr = (t_bookcase *)malloc(sizeof(t_bookcase)); head = curr; } curr->id = case_count; room[pos_x-1][pos_y-1] = curr->id; curr->face = face; curr->dir = dir; curr->x = pos_x; curr->y = pos_y; curr->next=NULL; } } void set_dabb(int pos_x, int pos_y) { set_case(pos_x, pos_y, NONE, ANY); } void set_door(int pos) { if (pos<1) pos = 1; if (pos>ROOM_WIDTH) pos = ROOM_WIDTH; door_pos = pos-1; } void reset_case(int caseid) { t_bookcase *temp; if (head == NULL) return; curr = head; if(head->id == caseid) { head = curr->next; room[curr->x-1][curr->y-1]=0; free(curr); case_count --; curr = head; } else { while(curr->next != NULL && curr->next->id != caseid) curr = curr->next; if(curr->next == NULL) return; temp = curr->next; curr->next = temp->next; curr = curr->next; room[temp->x-1][temp->y-1] = 0; free(temp); case_count --; } while(curr != NULL) { curr->id --; room[curr->x-1][curr->y-1]=curr->id; curr = curr->next; } } void move_case(int pos_x, int pos_y, int dest_x, int dest_y) { int dx, dy; t_bookcase * bcp; if(pos_x<1 || pos_x>ROOM_WIDTH || pos_y<1 || pos_y>ROOM_HEIGHT || dest_x<1|| dest_x>ROOM_WIDTH || dest_y<1|| dest_y>ROOM_HEIGHT) return; dx = dest_x - pos_x; dy = dest_y - pos_y; bcp = get_casep(get_caseid(pos_x, pos_y)); printf("caseid = %d x=%d y=%d\n", bcp->id, bcp->x, bcp->y); if(bcp == NULL || room[dest_x-1][dest_y-1] != 0) { printf("cannot move.\n"); return; } else if(dx*dx+dy*dy == 1 && ((bcp->dir==HOR && bcp->y==dest_y) || (bcp->dir==VER && bcp->x==dest_x) || bcp->dir == ANY)) { bcp->x = dest_x; bcp->y = dest_y; room[pos_x-1][pos_y-1] = 0; room[dest_x-1][dest_y-1] = bcp->id; printf("move okay!\n"); } else printf("illegal move.\n"); } void draw_case(t_bookcase *bc) { int i, j, k; i = (bc->y-1)*3+1; j = (bc->x-1)*6+2; if(bc->face == NONE && bc->dir == ANY) { img_buf[i+1][j+2] = '@'; return; } img_buf[i][j]=img_buf[i+2][j]=\ img_buf[i][j+4]=img_buf[i+2][j+4]='+'; img_buf[i+1][j]=img_buf[i+1][j+4]='|'; for(k=1; k<=3; k++) img_buf[i][j+k] = img_buf[i+2][j+k] = '-'; switch(bc->face) { case NORTH: img_buf[i][j+1] = \ img_buf[i][j+2] = \ img_buf[i][j+3] = '#'; break; case SOUTH: img_buf[i+2][j+1] = \ img_buf[i+2][j+2] = \ img_buf[i+2][j+3] = '#'; break; case EAST: img_buf[i+1][j+4] = '#'; break; case WEST: img_buf[i+1][j] = '#'; break; } switch(bc->dir) { case FIX: img_buf[i+1][j+2] = 'X'; break; case HOR: img_buf[i+1][j+2] = '-'; break; case VER: img_buf[i+1][j+2] = '|'; break; } } void draw_door(void) { int i = door_pos*6+2; img_buf[IMG_HEIGHT-1][i] = \ img_buf[IMG_HEIGHT-1][i+1] = \ img_buf[IMG_HEIGHT-1][i+2] = \ img_buf[IMG_HEIGHT-1][i+3] = \ img_buf[IMG_HEIGHT-1][i+4] = '='; } void draw_study(void) { int i,j; t_bookcase * bcp; init_img(); for(i=1; i<=4; i++) for(j=1;j<=4;j++) { bcp = get_casep(get_caseid(i,j)); if(bcp != NULL) draw_case(bcp); } draw_door(); printf(" 1 2 3 4\n"); for(i=0; i<IMG_HEIGHT; i++) printf("%c %s\n", (i%3==2 && i!=0)?'A'+i/3:' ', img_buf[i]); } void draw_prompt(void) { printf("\n\n"); printf("> "); } void draw_help(void) { printf("enter <cmd> <options>\n\n"); printf("cmd: h=help(print this hint),\n q=quit, m=move, s=set_bookcase, r=remove_bookcase,\n p=place_man, d=place_door\n"); printf("options:\n"); printf(" move: m <pos> <dest>\n"); printf(" set: <pos> <face> <dir>\n"); printf(" reset: <pos>\n"); printf(" p: <pos>\n"); printf(" d: <num>\n\n"); printf(" pos/dest: Xn : X=A/B/C/... n=1/2/3/...\n"); printf(" num: n : n=1/2/3/...\n"); printf(" face: n=north, s=south, e=east, w=west\n"); printf(" dir: f=fix, v=vetical, h=horizontal\n"); } unsigned char get_cmd(void); int get_pos(void); int get_dest(void); int get_face(void); int get_dir(void); int get_command(void) { gets(cmdbuf); } int decode_command(void) { cmdbufidx = 0; cmd = get_cmd(); switch(cmd) { case 'q': case 'Q': return -1; case 'm': case 'M': pos = get_pos(); dest = get_dest(); move_case(pos/16, pos%16, dest/16, dest%16); break; case 's': case 'S': pos = get_pos(); face = get_face(); dir = get_dir(); set_case(pos/16, pos%16, face, dir); case 'r': case 'R': pos = get_pos(); reset_case(get_caseid(pos/16, pos%16)); break; case 'p': case 'P': pos = get_pos(); set_dabb(pos/16, pos%16); break; case 'd': case 'D': pos = get_num(); set_door(pos); break; case 'h': case 'H': draw_help(); break; default: break; } return 0; } unsigned char get_cmd(void) { unsigned char c; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(isalpha(cmdbuf[cmdbufidx])) c = cmdbuf[cmdbufidx++]; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; return c; } int get_num(void) { int c; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(isdigit(cmdbuf[cmdbufidx])) c = cmdbuf[cmdbufidx++]-'0'; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; return c; } int get_pos(void) { int p; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(islower(cmdbuf[cmdbufidx])) p = cmdbuf[cmdbufidx++]-'a'+1; else if(isupper(cmdbuf[cmdbufidx])) p = cmdbuf[cmdbufidx++]-'A'+1; else p = 0; if(isdigit(cmdbuf[cmdbufidx])) p |= ((cmdbuf[cmdbufidx++]-'0') << 4); else p = 0; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(p >= 0x50 || ((p & 0x0F) > 4)) p=0; return p; } int get_dest(void) { int d; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(islower(cmdbuf[cmdbufidx])) d = cmdbuf[cmdbufidx++]-'a'+1; else if(isupper(cmdbuf[cmdbufidx])) d = cmdbuf[cmdbufidx++]-'A'+1; else d = 0; if(isdigit(cmdbuf[cmdbufidx])) d |= ((cmdbuf[cmdbufidx++]-'0') <<4 ); else d = 0; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(d >= 0x50 || ((d & 0x0F) > 4)) d=0; return d; } int get_face(void) { int f; char c; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(isalpha(cmdbuf[cmdbufidx])) c = cmdbuf[cmdbufidx++]; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; switch(c) { case 'n': case 'N': f = NORTH; break; case 's': case 'S': f = SOUTH; break; case 'e': case 'E': f = EAST; break; case 'w': case 'W': f = WEST; break; default: cmd = 'x'; break; } return f; } int get_dir(void) { int d; char c; while (isspace(cmdbuf[cmdbufidx])) cmdbufidx++; if(isalpha(cmdbuf[cmdbufidx])) c = cmdbuf[cmdbufidx++]; while (!isspace(cmdbuf[cmdbufidx])) cmdbufidx++; switch(c) { case 'f': case 'F': d = FIX; break; case 'v': case 'V': d = VER; break; case 'h': case 'H': d = HOR; break; default: cmd = 'x'; break; } return d; } #define DO_COMMAND(str) strcpy(cmdbuf, (str)); decode_command() int main(void) { FILE * fp; init_study(); if(fp=fopen("study.init", "r")) { while(fgets(cmdbuf, 80, fp)) decode_command(); } else { DO_COMMAND("set a1 south fix"); DO_COMMAND("set b1 south hor"); DO_COMMAND("set c1 south hor"); DO_COMMAND("set d1 south ver"); DO_COMMAND("set a2 south hor"); DO_COMMAND("set b2 south ver"); DO_COMMAND("set a3 south hor"); DO_COMMAND("set b3 south hor"); DO_COMMAND("set c3 south ver"); DO_COMMAND("set d3 south hor"); DO_COMMAND("set a4 south ver"); DO_COMMAND("set b4 south ver"); DO_COMMAND("set c4 south hor"); DO_COMMAND("set d4 west fix"); DO_COMMAND("placeman d2"); DO_COMMAND("door 2"); } draw_study(); draw_prompt(); get_command(); while(decode_command() != -1) { draw_study(); draw_prompt(); get_command(); } } ---------------- end of study.c --------------------- ... May the source be with you! |