/*-------------------------------------------------------*/
/* 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