精華區beta SetupBBS 關於我們 聯絡資訊
/*-------------------------------------------------------*/ /* mind.c ( YZU_CSE WindTop BBS ) */ /*-------------------------------------------------------*/ /* author : verit.bbs@bbs.yzu.edu.tw */ /* target : 心理測驗 */ /* create : 2003/08/05 */ /*-------------------------------------------------------*/ #undef _MODES_C_ #include "bbs.h" #define MAX_DESC_LENGTH (256) /* 敘述的長度 */ #define MAX_TEXT_LENGTH (512) /* 內文的長度 */ #define MAX_MIND_QUESTION (50) /* 最多題目個數 */ #define MAX_MIND_ANSWER (5) /* 每題最多答案數 */ #define MAX_MIND_RESULT (10) /* 最多結果數 */ #define LEN (50) /* 一行最多顯示幾個字 */ #define X (10) /* 預設輸出 x 座標 */ #define Y (5) /* 預設輸出 y 座標 */ #define DEF_PATH "/home/bbs/so_tmp/mind/" int x=X,y=Y; typedef struct { char question[MAX_DESC_LENGTH]; char ans_desc[MAX_MIND_ANSWER][MAX_DESC_LENGTH]; int ans_next[MAX_MIND_ANSWER]; int ans; } QUESTION; typedef struct { char title[MAX_DESC_LENGTH]; char desc[MAX_TEXT_LENGTH]; }RESULT; typedef struct { QUESTION question[MAX_MIND_QUESTION]; RESULT result[MAX_MIND_RESULT]; int qcount; int rcount; } MIND; int read_file(fpath,m) char *fpath; MIND *m; { FILE *fp; int num; int ans; int result; char buf[MAX_TEXT_LENGTH]; char *tmp,*tmp2; if(!(fp = fopen(fpath,"r"))) return -1; num = -1; result = 0; while(fgets(buf,sizeof(buf),fp)) { if(buf[1] == 'Q') { if(num >= 0) m->question[num].ans = ans; if(++num >= MAX_MIND_QUESTION) { fclose(fp); return -2; } strcpy(m->question[num].question , buf+3); if( tmp2 = strchr(m->question[num].question,'\n') ) *tmp2 = 0; ans = 0; } else if(buf[1] == 'A') { tmp = strchr(buf,']'); *tmp = 0; if(buf[3] == 'R') m->question[num].ans_next[ans] = atoi(buf+4); else m->question[num].ans_next[ans] = atoi(buf+3); strcpy(m->question[num].ans_desc[ans],tmp+1); if( tmp2 = strchr(m->question[num].ans_desc[ans],'\n') ) *tmp2 = 0; ++ans; } else if(buf[1] == 'R') { m->question[num].ans = ans; strcpy(m->result[result].title,buf+3); if( tmp2 = strchr(m->result[result].title,'\n') ) *tmp2 = 0; if(fgets(buf,sizeof(buf),fp)) strcpy(m->result[result].desc,buf); else memset(m->result[result].desc,0,MAX_TEXT_LENGTH); if( tmp2 = strchr(m->result[result].desc,'\n') ) *tmp2 = 0; if(++result >= MAX_MIND_RESULT) break; } } m->qcount = num+1; m->rcount = result; fclose(fp); return 1; } int print_quiz(char *src) { int wstate=0; int word=0; char *str = src; char buf[128],*tmp; char form[128] ; int pos=LEN+1; int height=0; sprintf(form,"%c-%ds",'%',pos+1); while(*str) { height++; tmp = str; move(y++,x); outs(" \033[0;37m▏\033[1;37m"); wstate=0; word=0; for(;word<pos && *str;str++) { wstate = (*str<0)?((wstate==1)?0:1):0; word++; } if(!(*str<0 && wstate==0)) str++; memset(buf,0,sizeof(buf)); strncpy(buf,tmp,str-tmp); prints(form,buf); if(strlen(buf)==pos) outs("\033[0;47;30m▉\033[40;30;1m▉\033[m "); else outs("\033[0;47;30m▉\033[40;30;1m▉\033[m "); } return height; } int draw_item(char *src,int pos,int mode) { char buf[128]; sprintf(buf,"%cd;37m %s %c-%ds",'%',(mode)?"◆":" ",'%',LEN-2); move(Y+pos+2,X); outs(" \033[0;37m▏\033[1;"); prints(buf,(mode)?41:40,src); outs("\033[0;47;30m▉\033[40;30;1m▉\033[m "); } static int draw_menu(QUESTION *question,int no) { int i,cur; int c; int h=0; y=Y;x=X; move(y++,x); prints(" \033[0;40;37mˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍ\033[m "); move(y++,x); prints(" \033[0;37;44m▏\033[1m%s %02d %-45s \033[0;47;34m▉\033[m ","第",no+1,"題"); move(y++,x); prints(" \033[0;37m▏\033[1m%-51s \033[0;47;30m▉\033[40;30;1m▉\033[m "," "); cur = 0; h = print_quiz(question[no].question)+2; move(y++,x); prints(" \033[0;37m▏\033[1m%-51s \033[0;47;30m▉\033[40;30;1m▉\033[m "," "); for(i=0;i<question[no].ans;++i,++y) { draw_item(question[no].ans_desc[i],i+h,(i==cur)?1:0); } move(y++,x); prints(" \033[0;37m▏\033[1m%-51s \033[0;47;30m▉\033[40;30;1m▉\033[m "," "); move(y++,x); prints(" \033[0;47;30m▇\033[30;1m▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇\033[40;30;1m▉\033[m "); outz("\033[1;37;42m 【操作說明】q)離開 Enter)作答 \033[m"); while(c = vkey() ) { draw_item(question[no].ans_desc[cur],cur+h,0); switch(c) { case KEY_UP : cur = (cur==0)?question[no].ans-1:cur-1 ; break ; case KEY_DOWN : cur = (cur+1) % question[no].ans ; break ; case '\n' : case ' ' : return cur; case 'q': vmsg(NULL); return -892226; } draw_item(question[no].ans_desc[cur],cur+h,1); } return 0; } int do_test(fpath,title) char *fpath; char *title; { int no,ans ; MIND m; if(read_file(fpath,&m) <= 0) return 1; no = 0; while(1) { clear();vs_head("心理測驗", str_site); move(3,X);prints("目前測驗的題目是 : %s",title); ans = draw_menu(m.question,no); if(ans == -892226) return ; no = m.question[no].ans_next[ans]; if( no < 0 ) { y=Y;x=X; no = -no; --no; clear();vs_head("心理測驗", str_site); move(y++,x); prints(" \033[0;40;37mˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍˍ\033[m "); move(y++,x); prints(" \033[0;37;42m▏\033[1m結果:%-45s \033[0;47;32m▉\033[m ",m.result[no].title); move(y++,x); prints(" \033[0;37m▏\033[1m%-51s \033[0;47;30m▉\033[40;30;1m▉\033[m "," "); print_quiz(m.result[no].desc); move(y++,x); prints(" \033[0;37m▏\033[1m%-51s \033[0;47;30m▉\033[40;30;1m▉\033[m "," "); move(y++,x); prints(" \033[0;47;30m▇\033[30;1m▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇\033[40;30;1m▉\033[m "); vmsg(NULL); break; } } } /*-------------------------------------------------------*/ /* xover 選單 */ /*-------------------------------------------------------*/ extern XZ xz[]; static int mind_add(); typedef struct { char title[56]; char fpath[8]; } XMIND; static void mind_item(num, mind) int num; XMIND *mind; { prints("%6d %-64s\n", num, mind->title); } static int mind_body(xo) XO *xo; { XMIND *mind; int num, max, tail; move(3, 0); clrtobot(); max = xo->max; if (max <= 0) { if (vans("要新增資料嗎(Y/N)?[N] ") == 'y') return mind_add(xo); return XO_QUIT; } mind = (XMIND *) xo_pool; num = xo->top; tail = num + XO_TALL; if (max > tail) max = tail; do { mind_item(++num, mind++); } while (num < max); return XO_NONE; } static int mind_head(xo) XO *xo; { vs_head("心理測驗", str_site); outs("\ [←]離開 [Enter]測驗 [h]投稿格式\n\ \033[30;47m 編號 測 驗 名 稱 \033[m"); return mind_body(xo); } static int mind_load(xo) XO *xo; { xo_load(xo, sizeof(XMIND)); return mind_body(xo); } static int mind_init(xo) XO *xo; { xo_load(xo, sizeof(XMIND)); return mind_head(xo); } static int mind_edit(mind,echo) XMIND *mind; int echo; { char fpath[128]; if(echo == DOECHO) { time_t t = time(0); memset(mind, 0, sizeof(XMIND)); archiv32(t, mind->fpath); } if(vget(b_lines, 0, "名稱:", mind->title, sizeof(mind->title), echo)) { sprintf(fpath,"%s%s",DEF_PATH,mind->fpath); if(vedit(fpath, NA)) { if(echo == DOECHO) vmsg("取消新增"); else vmsg("取消修改"); return 0; } return 1; } else return 0; } static int mind_add(xo) XO *xo; { XMIND mind; if(!HAVE_PERM(PERM_SYSOP)) return XO_FOOT; if(mind_edit(&mind,DOECHO)) { rec_add(xo->dir, &mind, sizeof(XMIND)); xo->pos = XO_TAIL /* xo->max */ ; xo_load(xo, sizeof(XMIND)); } return mind_head(xo); } static int mind_delete(xo) XO *xo; { if(!HAVE_PERM(PERM_SYSOP)) return XO_FOOT; if (vans(msg_del_ny) == 'y') { if (!rec_del(xo->dir, sizeof(XMIND), xo->pos, NULL, NULL)) { return mind_load(xo); } } return XO_FOOT; } static int mind_change(xo) XO *xo; { XMIND *mind, mate; int pos, cur; if(!HAVE_PERM(PERM_SYSOP)) return XO_FOOT; pos = xo->pos; cur = pos - xo->top; mind = (XMIND *) xo_pool + cur; mate = *mind; mind_edit(mind, GCARRY); if (memcmp(mind, &mate, sizeof(XMIND))) { rec_put(xo->dir, mind, sizeof(XMIND), pos); move(3 + cur, 0); mind_item(++pos, mind); } return XO_INIT; } static int mind_browser(xo) XO *xo; { XMIND *mind; int pos, cur; char fpath[128]; if(!HAVE_PERM(PERM_SYSOP)) return XO_FOOT; pos = xo->pos; cur = pos - xo->top; mind = (XMIND *) xo_pool + cur; sprintf(fpath,"%s%s",DEF_PATH,mind->fpath); more(fpath,NULL); return XO_INIT; } static int mind_do(xo) XO *xo; { XMIND *mind; int pos, cur; char fpath[128]; pos = xo->pos; cur = pos - xo->top; mind = (XMIND *) xo_pool + cur; sprintf(fpath,"%s%s",DEF_PATH,mind->fpath); do_test(fpath,mind->title); return XO_INIT; } static int mind_help(xo) XO *xo; { char fpath[128]; sprintf(fpath,"%shelp",DEF_PATH); more(fpath,NULL); return mind_head(xo); } KeyFunc mind_cb[] = { XO_INIT, mind_init, XO_LOAD, mind_load, XO_HEAD, mind_head, XO_BODY, mind_body, Ctrl('P'), mind_add, 'r', mind_do, 'q', mind_browser, 'c', mind_change, 's', mind_init, 'd', mind_delete, 'h', mind_help }; int mind_main() { XO *xo; char fpath[64]; utmp_mode(M_OMENU); sprintf(fpath, "%sindex",DEF_PATH); xz[XZ_OTHER - XO_ZONE].xo = xo = xo_new(fpath); xz[XZ_OTHER - XO_ZONE].cb = mind_cb; xover(XZ_OTHER); free(xo); return 0; } -- ※ Origin: 元智大學 風之塔 <bbs.yzu.edu.tw> ※ From : bbs.yzu.edu.tw