/* $Id: gomo.c,v 1.4 2002/05/25 11:18:11 ptt Exp $ */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <time.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include "config.h" #include "pttstruct.h" #include "gomo.h" #include "common.h" #include "modes.h" #include "proto.h" extern int usernum; extern userinfo_t *currutmp; extern time_t now; char ku[BRDSIZ][BRDSIZ]; static char *chess[] = { "��", "��" }; static int tick, lastcount, mylasttick, hislasttick; unsigned char *pat, *adv; typedef struct { char x; char y; } Horder_t; static Horder_t *v, pool[225]; static void HO_init() { memset(pool, 0, sizeof(pool)); v = pool; pat = pat_gomoku; adv = adv_gomoku; memset(ku, 0, sizeof(ku)); } static void HO_add(Horder_t *mv) { *v++ = *mv; } static void HO_undo(Horder_t *mv) { char *str = "�z�s�{�u�q�t�|�r�}"; int n1, n2, loc; *mv = *(--v); ku[(int)mv->x][(int)mv->y] = BBLANK; BGOTO(mv->x, mv->y); n1 = (mv->x == 0) ? 0 : (mv->x == 14) ? 2 : 1; n2 = (mv->y == 14)? 0 : (mv->y == 0) ? 2 : 1; loc= 2 * ( n2 * 3 + n1); prints("%.2s", str + loc); } extern userec_t cuser; static void HO_log(char *user) { int i; FILE *log; char buf[80]; char buf1[80]; char title[80]; Horder_t *ptr = pool; extern screenline_t *big_picture; fileheader_t mymail; sprintf(buf, "home/%c/%s/F.%d", cuser.userid[0], cuser.userid, rand() & 65535); log = fopen(buf, "w"); for(i = 1; i < 17; i++) fprintf(log, "%.*s\n", big_picture[i].len, big_picture[i].data); i = 0; do { fprintf(log, "[%2d]%s ==> %c%d%c", i + 1, chess[i % 2], 'A' + ptr->x, ptr->y + 1, (i % 2) ? '\n' : '\t'); i++; } while( ++ptr < v); fclose(log); sethomepath(buf1, cuser.userid); stampfile(buf1, &mymail); mymail.filemode = FILE_READ|FILE_HOLD; strcpy(mymail.owner, "[��.��.��]"); sprintf(mymail.title, "\033[37;41m����\033[m %s VS %s", cuser.userid, user); sethomedir(title, cuser.userid); Rename(buf, buf1); append_record(title, &mymail, sizeof(mymail)); unlink(buf); } static int countgomo() { Horder_t *ptr; int i; ptr = pool; i = 0; do { i++; } while(++ptr < v); return i; } static int chkmv(Horder_t *mv, int color, int limit) { char *xtype[] = {"\033[1;31m���T\033[m", "\033[1;31m���T\033[m", "\033[1;31m���|\033[m", "\033[1;31m���|\033[m", "\033[1;31m���|\033[m", "\033[1;31m�|�T\033[m", "\033[1;31m���T\033[m", "\033[1;31m���|\033[m", "\033[1;31m���|\033[m", "\033[1;31m�s��\033[m", "\033[1;31m�s��\033[m"}; int rule = getstyle(mv->x, mv->y, color, limit); if(rule > 1 && rule < 13) { move(15, 40); outs(xtype[rule - 2]); bell(); } return chkwin(rule, limit); } static int gomo_key(int fd, int ch, Horder_t *mv) { if( ch >= 'a' && ch <= 'o') { char pbuf[4], vx, vy; *pbuf = ch; if(fd) add_io(0, 0); oldgetdata(17, 0, "�������w��m :", pbuf, sizeof(pbuf), DOECHO); if(fd) add_io(fd, 0); vx = pbuf[0] - 'a'; vy = atoi(pbuf + 1) - 1; if(vx >= 0 && vx < 15 && vy >= 0 && vy < 15 && ku[(int)vx][(int)vy] == BBLANK) { mv->x = vx; mv->y = vy; return 1; } } else { switch(ch) { case KEY_RIGHT: mv->x = (mv->x == BRDSIZ - 1) ? mv->x : mv->x + 1; break; case KEY_LEFT: mv->x = (mv->x == 0 ) ? 0 : mv->x - 1; break; case KEY_UP: mv->y = (mv->y == BRDSIZ - 1) ? mv->y : mv->y + 1; break; case KEY_DOWN: mv->y = (mv->y == 0 ) ? 0 : mv->y - 1; break; case ' ': case '\r': if(ku[(int)mv->x][(int)mv->y] == BBLANK) return 1; } } return 0; } extern userec_t xuser; static int reload_gomo() { passwd_query(usernum, &xuser); cuser.five_win = xuser.five_win; cuser.five_lose = xuser.five_lose; cuser.five_tie = xuser.five_tie; return 0; } int gomoku(int fd) { Horder_t mv; int me, he, win, ch; int hewantpass, iwantpass; userinfo_t *my = currutmp; HO_init(); me = !(my->turn) + 1; he = my->turn + 1; win = 1; tick=now + MAX_TIME; lastcount = MAX_TIME; setutmpmode(M_FIVE); clear(); prints("\033[1;46m ���l�ѹ�� \033[45m%30s VS %-30s\033[m", cuser.userid, my->mateid); show_file("etc/@five", 1, -1, ONLY_COLOR); move(11, 40); prints("�ڬO %s", me == BBLACK ? "���� ��, ���T��" : "��� ��"); move(16, 40); prints("\033[1;33m%s", cuser.userid); move(17, 40); prints("\033[1;33m%s", my->mateid); reload_gomo(); move(16, 60); prints("\033[1;31m%d\033[37m�� \033[34m%d\033[37m�� \033[36m%d\033[37m�M" "\033[m", cuser.five_win, cuser.five_lose, cuser.five_tie); getuser(my->mateid); move(17, 60); prints("\033[1;31m%d\033[37m�� \033[34m%d\033[37m�� \033[36m%d\033[37m" "�M\033[m", xuser.five_win, xuser.five_lose, xuser.five_tie); cuser.five_lose++; /* �@�i�ӥ��[�@���ѳ�, Ĺ�F��A���^�h, �קK�ֿ�F�c�N�_�u */ passwd_update(usernum, &cuser); add_io(fd, 0); hewantpass = iwantpass = 0; mv.x = mv.y = 7; move(18, 40); prints("%s�ɶ��ٳ�%d:%02d\n", my->turn ? "�A��" : "���", MAX_TIME / 60, MAX_TIME % 60); for(;;) { move(13, 40); outs(my->turn ? "����ۤv�U�F!": "���ݹ��U�l.."); if(lastcount != tick-now) { lastcount = tick-now; move(18, 40); prints("%s�ɶ��ٳ�%d:%02d\n", my->turn ? "�A��" : "���", lastcount / 60, lastcount % 60); if(lastcount <= 0 && my->turn) { move(19, 40); outs("�ɶ��w��, �A��F"); my->five_lose++; send(fd, '\0', 1, 0); break; } if(lastcount <= -5 && !my->turn) { move(19, 40); outs("���Ӥ[�S�U, �AĹ�F!"); win = 1; cuser.five_lose--; cuser.five_win++; my->five_win++; passwd_update(usernum, &cuser); mv.x = mv.y = -2; send(fd, &mv, sizeof(Horder_t), 0); mv = *(v - 1); break; } } move(14, 40); if(hewantpass) { outs("\033[1;32m�M�ѭn�D!\033[m"); bell(); } else clrtoeol(); BGOTOCUR(mv.x, mv.y); ch = igetkey(); if(ch != I_OTHERDATA) iwantpass = 0; if(ch == 'q') { if(countgomo() < 10) { cuser.five_lose--; passwd_update(usernum, &cuser); } send(fd, '\0', 1, 0); break; } else if(ch == 'u' && !my->turn && v > pool) { mv.x = mv.y = -1; ch = send(fd, &mv, sizeof(Horder_t), 0); if(ch == sizeof(Horder_t)) { HO_undo(&mv); tick = mylasttick; my->turn = 1; continue; } else break; } if(ch == 'p') { if(my->turn ) { if(iwantpass == 0) { iwantpass = 1; mv.x = mv.y = -2; send(fd, &mv, sizeof(Horder_t), 0); mv = *(v - 1); } continue; } else if(hewantpass) { win = 0; cuser.five_lose--; cuser.five_tie++; my->five_tie++; passwd_update(usernum, &cuser); mv.x=mv.y=-2; send(fd, &mv, sizeof(Horder_t), 0); mv = *(v - 1); break; } } if(ch == I_OTHERDATA) { ch = recv(fd, &mv, sizeof(Horder_t), 0); if(ch != sizeof(Horder_t)) { lastcount=tick-now; if(lastcount >=0) { win = 1; cuser.five_lose--; if(countgomo() >=10) { cuser.five_win++; my->five_win++; } passwd_update(usernum, &cuser); outmsg("���{��F!!"); break; } else { win = 0; outmsg("�A�W�L�ɶ����U�l, ��F!"); my->five_lose++; break; } } else if(mv.x == -2 && mv.y == -2) { if(iwantpass == 1) { win = 0; cuser.five_lose--; cuser.five_tie++; my->five_tie++; passwd_update(usernum, &cuser); break; } else { hewantpass = 1; mv = *(v - 1); continue; } } if(my->turn && mv.x == -1 && mv.y == -1) { outmsg("��讬��"); tick = hislasttick; HO_undo(&mv); my->turn = 0; continue; } if(!my->turn) { win = chkmv(&mv, he, he == BBLACK); HO_add(&mv); hislasttick = tick; tick = now + MAX_TIME; ku[(int)mv.x][(int)mv.y] = he; bell(); BGOTO(mv.x, mv.y); outs(chess[he - 1]); if(win) { outmsg(win == 1 ? "���Ĺ�F!" : "���T��"); if(win != 1) { cuser.five_lose--; cuser.five_win++; my->five_win++; passwd_update(usernum, &cuser); } else my->five_lose++; win = -win; break; } my->turn = 1; } continue; } if(my->turn) { if(gomo_key(fd, ch, &mv)) my->turn = 0; else continue; if(!my->turn) { HO_add(&mv); BGOTO(mv.x, mv.y); outs(chess[me - 1]); win = chkmv( &mv, me, me == BBLACK); ku[(int)mv.x][(int)mv.y] = me; mylasttick = tick; tick = now + MAX_TIME; /*�˼�*/ lastcount = MAX_TIME; if(send(fd, &mv, sizeof(Horder_t), 0) != sizeof(Horder_t)) break; if(win) { outmsg(win == 1 ? "��Ĺ�o~~" : "�T���F" ); if(win == 1) { cuser.five_lose--; cuser.five_win++; my->five_win++; passwd_update(usernum, &cuser); } else my->five_lose++; break; } move(15, 40); clrtoeol(); } } } add_io(0, 0); close(fd); igetch(); if(v > pool) { char ans[4]; getdata(19 , 0, "�n�O�d���������ж�?(y/N)", ans, sizeof(ans), LCECHO); if(*ans == 'y') HO_log(my->mateid); } return 0; }