/* $Id: dark.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ #include #include #include #include #include #include #include #include "config.h" #include "pttstruct.h" #include "common.h" #include "proto.h" #define RED 1 #define BLACK 0 typedef short int sint; typedef struct item { short int color,value,die,out; } item; typedef struct cur{ short int y,x,end; } cur; static item brd[4][8]; static cur curr; /* 6 個 bytes */ extern userinfo_t *currutmp; static char *rname[]={"兵","炮","傌","車","相","仕","帥"}; static char *bname[]={"卒","包","馬","車","象","士","將"}; static sint cury[]={3,5,7,9}, curx[]={5,9,13,17,21,25,29,33}; static sint rcount,bcount,cont,fix; /* cont:是否可連吃 */ static sint my=0,mx=0,mly=-1,mlx=-1; /* 移動的座標 跟 選子的座標 */ static sint cur_eaty,cur_eatx; /* 吃掉對方其子的秀出座標 */ static void brdswap(sint y,sint x,sint ly,sint lx) { memcpy(&brd[y][x],&brd[ly][lx],sizeof(item)); brd[ly][lx].die=1; brd[ly][lx].color=-1; /* 沒這個color */ brd[ly][lx].value=-1; } static void pprints(sint y,sint x,char* s) { move(y,x); clrtoeol(); prints("%s",s); } static sint Is_win(item att, item det, sint y, sint x, sint ly, sint lx) { sint i,c=0,min,max; if(att.value == 1) /* 砲 */ { if(y!=ly && x!=lx) return 0; if((abs(ly-y)==1 && brd[y][x].die==0)|| (abs(lx-x)==1 && brd[y][x].die==0)) return 0; if(y==ly){ if(x>lx) {max=x;min=lx;} else {max=lx;min=x;} for(i=min+1;ily) {max=y;min=ly;} else {max=ly;min=y;} for(i=min+1;i= det.value) return 1; else return 0; } return 0; } static sint Is_move(sint y,sint x, sint ly, sint lx) { if(brd[y][x].die==1 && ((abs(ly-y)==1&&x==lx) || (abs(lx-x)==1&&ly==y))) return 1; return 0; } static void brd_rand() { sint y,x,index; sint tem[32]; sint value[32]={0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6, 0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6}; bzero(brd, sizeof(brd)); bzero(tem, sizeof(tem)); bzero(&curr, sizeof(curr)); srand(getpid()%2731+time(NULL)%3219); for(y=0;y<4;y++) for(x=0;x<8;x++) while(1) { index=rand()%32; if(tem[index]) continue; brd[y][x].color=(index>15)?0:1; brd[y][x].value=value[index]; tem[index]=1; break; } } static void brd_prints() { clear(); move(1,0); outs(" ╭─┬─┬─┬─┬─┬─┬─┬─╮ │●│●│●│●│●│●│●│●│ ├─┼─┼─┼─┼─┼─┼─┼─┤ │●│●│●│●│●│●│●│●│ ├─┼─┼─┼─┼─┼─┼─┼─┤ │●│●│●│●│●│●│●│●│ ├─┼─┼─┼─┼─┼─┼─┼─┤ │●│●│●│●│●│●│●│●│ ╰─┴─┴─┴─┴─┴─┴─┴─╯ "); } static void draw_line(sint y, sint f) { sint i; char buf[1024],tmp[256]; *buf = 0; *tmp = 0; strcpy(buf,"\033[43;30m"); for(i=0; i<8; i++) { if(brd[y][i].die==1) sprintf(tmp,"│ "); else if(brd[y][i].out==0) sprintf(tmp,"│●"); else { sprintf(tmp, "│\033[%s1;%dm%s\033[m\033[43;30m", (f==i)?"1;47;":"",(brd[y][i].color)?31:34, (brd[y][i].color)?rname[brd[y][i].value]: bname[brd[y][i].value]); } strcat(buf,tmp); } strcat(buf,"│\033[m"); move(cury[y],3); clrtoeol(); prints("%s",buf); } static void redraw() { sint i=0; for(;i<4;i++) draw_line(i,-1); } static sint playing(sint fd, sint color,sint ch,sint *b, userinfo_t *uin) { curr.end = 0; move(cury[my],curx[mx]); if(fix) { if(ch=='s') { fix=0; *b=0; return 0; } else { draw_line(mly,-1); } } switch(ch) { case KEY_LEFT: if(mx == 0) mx=7; else mx--; move(cury[my],curx[mx]); *b=-1; break; case KEY_RIGHT: if(mx==7) mx=0; else mx++; move(cury[my],curx[mx]); *b=-1; break; case KEY_UP: if(my==0) my=3; else my--; move(cury[my],curx[mx]); *b=-1; break; case KEY_DOWN: if(my==3) my=0; else my++; move(cury[my],curx[mx]); *b=-1; break; case 'q':case 'Q': if(!color) bcount=0; else rcount=0; *b=0; return -2; case 'p':case 'P': return -3; case 'c': return -4; case 'g': return -5; case 's': /* 翻開棋子 或是選擇棋子 */ /* 選擇棋子 */ if(brd[my][mx].out==1) { if(brd[my][mx].color != color) { *b=-1; break; } if(mly<0) /*可以選擇*/ { mly=my;mlx=mx; draw_line(my,mx); *b=-1; break; } else if(mly == my && mlx == mx) /*不選了*/ { mly=-1;mlx=-1; draw_line(my,-1); }else { draw_line(mly,-1); mly=my;mlx=mx; if(brd[mly][mlx].value == 1) fix=1; draw_line(my,mx); } *b=-1; break; } /* 翻開棋子 */ if(mly >=0 ){ *b=-1; break;} /*本來就是翻開的*/ /* 決定一開始的顏色 */ if(currutmp->color=='.'){ if(uin->color!='1' && uin->color!='0') currutmp->color=(brd[my][mx].color)?'1':'0'; else currutmp->color=(uin->color=='0')?'1':'0';} brd[my][mx].out=1; draw_line(my,-1); move(cury[my],curx[mx]); *b=0; break; case 'u': move(0,0);clrtoeol(); prints("%s色%s cont=%d",(brd[my][mx].color == RED)?"紅":"黑",rname[brd[my][mx].value],cont); *b=-1; break; case '\r': /* 吃 or 移動 ly跟lx必須大於0*/ case '\n': if( mly >= 0 /* 要先選子 */ && brd[mly][mlx].color != brd[my][mx].color /* 同色不能移動也不能吃 */ && (Is_move(my,mx,mly,mlx) || Is_win(brd[mly][mlx],brd[my][mx],my,mx,mly,mlx)) ) { if(fix && brd[my][mx].value<0) { *b=-1;return 0; } if(brd[my][mx].value>=0&&brd[my][mx].die==0) { if(!color) bcount--; else rcount--; move(cur_eaty,cur_eatx); prints("%s",(color)?bname[brd[my][mx].value]:rname[brd[my][mx].value]); if(cur_eatx>=26) { cur_eatx=5;cur_eaty++; } else cur_eatx+=3; } brdswap(my,mx,mly,mlx); draw_line(mly,-1); draw_line( my,-1); if(fix==1) *b=-1; else { mly=-1;mlx=-1;*b=0; } } else *b=-1; break; default: *b=-1; } if(!rcount) return -1; else if(!bcount) return -1; if(*b == -1) return 0; curr.y = my;curr.x = mx; curr.end=(!*b)?1:0; send(fd,&curr,sizeof(curr),0); send(fd,&brd,sizeof(brd),0); return 0; } int main_dark(int fd,userinfo_t *uin) { sint end=0,ch=1,go_on,i=0,cont=0; char buf[16]; *buf=0;fix=0; currutmp->color='.'; // '.' 表示還沒決定顏色 rcount=16;bcount=16; // initialize cur_eaty=18,cur_eatx=5; brd_prints(); if(currutmp->turn) { brd_rand(); send(fd,&brd,sizeof(brd),0); pprints(21,0," ◆你是先手"); pprints(22,0," ◆輪到你下了"); }else { recv(fd,&brd,sizeof(brd),0); pprints(21,0," ◆你是後手"); } move(12,3); prints("%s[0勝0敗]vs.%s[0勝0敗]",currutmp->userid,currutmp->mateid); outs(" ╳╱功\能表╲╳╲╱╳╲ ╱ ↑←↓→: 移動 ╳ s:  選子,翻子 ╱ enter:  吃棋,放棋  已經解決的:   ╳ p:  合棋    ╱ q:  認輸 ╳ c:  換邊"); if(currutmp->turn) move(cury[0],curx[0]); add_io(fd, 0); while(end<=0) { if(uin->turn=='w' || currutmp->turn=='w') { end=-1; break; } ch = igetkey(); if(ch == I_OTHERDATA) { ch=recv(fd,&curr,sizeof(curr),0); if(ch!=sizeof(curr)) { if(uin->turn=='e') { end=-3;break; } else if(uin->turn!='w') { end=-1; currutmp->turn='w'; break; } end=-1; break; } if(curr.end==-3) pprints(23,30,"\033[33m要求合棋\033[m"); else if(curr.end==-4) pprints(23,30,"\033[33m要求換邊\033[m"); else if(curr.end==-5) pprints(23,30,"\033[33m要求連吃\033[m"); else pprints(23,30,""); recv(fd,&brd,sizeof(brd),0); my=curr.y;mx=curr.x; redraw(); if(curr.end) pprints(22,0," ◆輪到你下了"); move(cury[my],curx[mx]); }else { if(currutmp->turn=='p') { if(ch=='y') { end=-3; currutmp->turn='e'; break; } else { pprints(23,30,""); *buf=0; currutmp->turn=(uin->turn)?0:1; } }else if(currutmp->turn=='c') { if(ch=='y') { currutmp->color=(currutmp->color=='1')?'0':'1'; uin->color=(uin->color=='1')?'0':'1'; pprints(21,0,(currutmp->color=='1')?" \033[1;33m◆你持紅色棋\033[m":" \033[1;33m◆你持黑色棋\033[m"); } else { pprints(23,30,""); currutmp->turn=(uin->turn)?0:1; } }else if(currutmp->turn=='g') { if(ch=='y') { cont=1; pprints(21,0," \033[1;33m◆你持紅色棋\033[m 可連吃"); } else { pprints(23,30,""); currutmp->turn=(uin->turn)?0:1; } } if(currutmp->turn==1) { if(uin->turn=='g') { cont=1;uin->turn=(currutmp->turn)?0:1; pprints(21,10,"可連吃"); } end=playing(fd,currutmp->color-'0',ch,&go_on,uin); if(end == -1) { currutmp->turn='w';break; } else if(end == -2) { uin->turn='w';break; } else if(end == -3) { uin->turn='p';curr.end=-3; send(fd,&curr,sizeof(curr),0); send(fd,&brd,sizeof(buf),0); continue; } else if(end == -4) { if(currutmp->color!='1'&&currutmp->color!='0') continue; uin->turn='c';i=0;curr.end=-4; send(fd,&curr,sizeof(curr),0); send(fd,&brd,sizeof(buf),0); continue; } else if(end == -5) { uin->turn='g';curr.end=-5; send(fd,&curr,sizeof(curr),0); send(fd,&brd,sizeof(buf),0); continue; } if(!i && currutmp->color=='1') { pprints(21,0," \033[1;33m◆你持紅色棋\033[m");i++;move(cury[my],curx[mx]); } if(!i && currutmp->color=='0') { pprints(21,0," \033[1;33m◆你持黑色棋\033[m");i++;move(cury[my],curx[mx]); } if(uin->turn == 'e') { end=-3; break; } if(go_on < 0) continue; move(22,0);clrtoeol(); prints(" ◆輪到%s下 別怕別怕 他算啥米",currutmp->mateid); currutmp->turn = 0; uin->turn = 1; }else { if(ch == 'q'){uin->turn='w';break;} move(22,0);clrtoeol(); prints(" ◆輪到%s下 別怕別怕 他算啥米",currutmp->mateid); } } } switch(end) { case -1: case -2: if(currutmp->turn=='w'){ move(22,0);clrtoeol();prints("你贏了.. 真是恭喜~~");} else {move(22,0);clrtoeol();prints("輸掉了啦.....下次讓他好看!!");} break; case -3: pprints(22,0,"合棋唷!! 下次在分高下吧 ^_^"); break; default: add_io(0,0); close(fd); pressanykey(); return 0; } add_io(0,0); close(fd); pressanykey(); return 0; }