summaryrefslogtreecommitdiffstats
path: root/mbbsd/ch_dark.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-08-26 18:47:08 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2009-08-26 18:47:08 +0800
commit93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc (patch)
treea30f06e2eff15b42ca47f942923bde375b5c1d6d /mbbsd/ch_dark.c
parentfd70a4e6e7fc66edaf02664751270576cab74c73 (diff)
downloadpttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar.gz
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar.bz2
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar.lz
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar.xz
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.tar.zst
pttbbs-93d4cfc9955a16f6dc42ac3f7de55ec398e91bdc.zip
* change chess source file names to be prefixed with ch_*.
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4778 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/ch_dark.c')
-rw-r--r--mbbsd/ch_dark.c564
1 files changed, 564 insertions, 0 deletions
diff --git a/mbbsd/ch_dark.c b/mbbsd/ch_dark.c
new file mode 100644
index 00000000..1571f2b0
--- /dev/null
+++ b/mbbsd/ch_dark.c
@@ -0,0 +1,564 @@
+/* $Id$ */
+#include "bbs.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;
+
+struct DarkData {
+ item brd[4][8];
+ cur curr;
+ sint rcount, bcount, cont, fix; /* cont:是否可連吃 */
+ sint my, mx, mly, mlx; /* 移動的座標 標 */
+
+ sint cur_eaty, cur_eatx; /* 吃掉對方其子的秀出座標 */
+};
+
+static char * const rname[] = {"兵", "炮", "傌", "車", "相", "仕", "帥"};
+static char * const bname[] = {"卒", "包", "馬", "車", "象", "士", "將"};
+
+static const sint cury[] = {3, 5, 7, 9}, curx[] = {5, 9, 13, 17, 21, 25, 29, 33};
+
+static void
+brdswap(struct DarkData *dd, sint y, sint x, sint ly, sint lx)
+{
+ memcpy(&dd->brd[y][x], &dd->brd[ly][lx], sizeof(item));
+ dd->brd[ly][lx].die = 1;
+ dd->brd[ly][lx].color = -1; /* 沒這個color */
+ dd->brd[ly][lx].value = -1;
+}
+
+static sint
+Is_win(struct DarkData *dd, 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 && dd->brd[y][x].die == 0) ||
+ (abs(lx - x) == 1 && dd->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; i < max; i++)
+ if (dd->brd[y][i].die == 0)
+ c++;
+ } else if (x == lx) {
+ if (y > ly) {
+ max = y;
+ min = ly;
+ } else {
+ max = ly;
+ min = y;
+ }
+ for (i = min + 1; i < max; i++)
+ if (dd->brd[i][x].die == 0)
+ c++;
+ }
+ if (c != 1)
+ return 0;
+ if (det.die == 1)
+ return 0;
+ return 1;
+ }
+ /* 非砲 */
+ if (((abs(ly - y) == 1 && x == lx) || (abs(lx - x) == 1 && ly == y)) && dd->brd[y][x].out == 1) {
+ if (att.value == 0 && det.value == 6)
+ return 1;
+ else if (att.value == 6 && det.value == 0)
+ return 0;
+ else if (att.value >= det.value)
+ return 1;
+ else
+ return 0;
+ }
+ return 0;
+}
+
+static sint
+Is_move(struct DarkData *dd, sint y, sint x, sint ly, sint lx)
+{
+ if (dd->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(struct DarkData *dd)
+{
+ 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(dd->brd, sizeof(dd->brd));
+ bzero(tem, sizeof(tem));
+ bzero(&dd->curr, sizeof(dd->curr));
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 8; x++)
+ while (1) {
+ index = random() % 32;
+ if (tem[index])
+ continue;
+ dd->brd[y][x].color = (index > 15) ? 0 : 1;
+ dd->brd[y][x].value = value[index];
+ tem[index] = 1;
+ break;
+ }
+}
+
+static void
+brd_prints(void)
+{
+ clear();
+ move(1, 0);
+ outs("\n"
+ " " ANSI_COLOR(43;30) "╭─┬─┬─┬─┬─┬─┬─┬─╮" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "│●│●│●│●│●│●│●│●│" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "├─┼─┼─┼─┼─┼─┼─┼─┤" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "│●│●│●│●│●│●│●│●│" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "├─┼─┼─┼─┼─┼─┼─┼─┤" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "│●│●│●│●│●│●│●│●│" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "├─┼─┼─┼─┼─┼─┼─┼─┤" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "│●│●│●│●│●│●│●│●│" ANSI_RESET "\n"
+ " " ANSI_COLOR(43;30) "╰─┴─┴─┴─┴─┴─┴─┴─╯" ANSI_RESET "\n"
+ " ");
+}
+
+static void
+draw_line(struct DarkData *dd, sint y, sint f)
+{
+ sint i;
+ char buf[1024], tmp[256];
+
+ *buf = 0;
+ *tmp = 0;
+ strlcpy(buf, ANSI_COLOR(43;30), sizeof(buf));
+ for (i = 0; i < 8; i++) {
+ if (dd->brd[y][i].die == 1)
+ snprintf(tmp, sizeof(tmp), "│ ");
+ else if (dd->brd[y][i].out == 0)
+ snprintf(tmp, sizeof(tmp), "│●");
+ else {
+ snprintf(tmp, sizeof(tmp), "│" ANSI_COLOR(%s1;%d) "%s" ANSI_RESET ANSI_COLOR(43;30) "",
+ (f == i) ? "1;47;" : "", (dd->brd[y][i].color) ? 31 : 34,
+ (dd->brd[y][i].color) ? rname[dd->brd[y][i].value] :
+ bname[dd->brd[y][i].value]);
+ }
+ strcat(buf, tmp);
+ }
+ strcat(buf, "│" ANSI_RESET);
+
+ move(cury[y], 3);
+ clrtoeol();
+ outs(buf);
+}
+
+static void
+redraw(struct DarkData *dd)
+{
+ sint i = 0;
+ for (; i < 4; i++)
+ draw_line(dd, i, -1);
+}
+
+static sint
+playing(struct DarkData *dd, sint fd, sint color, sint ch, sint * b, userinfo_t * uin)
+{
+ dd->curr.end = 0;
+ move(cury[dd->my], curx[dd->mx]);
+
+ if (dd->fix) {
+ if (ch == 's') {
+ dd->fix = 0;
+ *b = 0;
+ return 0;
+ } else {
+ draw_line(dd, dd->mly, -1);
+ }
+ }
+ switch (ch) {
+ case KEY_LEFT:
+ if (dd->mx == 0)
+ dd->mx = 7;
+ else
+ dd->mx--;
+ move(cury[dd->my], curx[dd->mx]);
+ *b = -1;
+ break;
+ case KEY_RIGHT:
+ if (dd->mx == 7)
+ dd->mx = 0;
+ else
+ dd->mx++;
+ move(cury[dd->my], curx[dd->mx]);
+ *b = -1;
+ break;
+ case KEY_UP:
+ if (dd->my == 0)
+ dd->my = 3;
+ else
+ dd->my--;
+ move(cury[dd->my], curx[dd->mx]);
+ *b = -1;
+ break;
+ case KEY_DOWN:
+ if (dd->my == 3)
+ dd->my = 0;
+ else
+ dd->my++;
+ move(cury[dd->my], curx[dd->mx]);
+ *b = -1;
+ break;
+ case 'q':
+ case 'Q':
+ if (!color)
+ dd->bcount = 0;
+ else
+ dd->rcount = 0;
+ *b = 0;
+ return -2;
+ case 'p':
+ case 'P':
+ return -3;
+ case 'c':
+ return -4;
+ case 'g':
+ return -5;
+ case 's': /* 翻開棋子 或是選擇棋子 */
+ /* 選擇棋子 */
+ if (dd->brd[dd->my][dd->mx].out == 1) {
+ if (dd->brd[dd->my][dd->mx].color != color) {
+ *b = -1;
+ break;
+ }
+ if (dd->mly < 0) { /* 可以選擇 */
+ dd->mly = dd->my;
+ dd->mlx = dd->mx;
+ draw_line(dd, dd->my, dd->mx);
+ *b = -1;
+ break;
+ } else if (dd->mly == dd->my && dd->mlx == dd->mx) { /* 不選了 */
+ dd->mly = -1;
+ dd->mlx = -1;
+ draw_line(dd, dd->my, -1);
+ } else {
+ draw_line(dd, dd->mly, -1);
+ dd->mly = dd->my;
+ dd->mlx = dd->mx;
+ if (dd->brd[dd->mly][dd->mlx].value == 1)
+ dd->fix = 1;
+ draw_line(dd, dd->my, dd->mx);
+ }
+ *b = -1;
+ break;
+ }
+ /* 翻開棋子 */
+ if (dd->mly >= 0) {
+ *b = -1;
+ break;
+ } /* 本來就是翻開的 */
+ /* 決定一開始的顏色 */
+ if (currutmp->color == '.') {
+ if (uin->color != '1' && uin->color != '0')
+ currutmp->color = (dd->brd[dd->my][dd->mx].color) ? '1' : '0';
+ else
+ currutmp->color = (uin->color == '0') ? '1' : '0';
+ }
+ dd->brd[dd->my][dd->mx].out = 1;
+ draw_line(dd, dd->my, -1);
+ move(cury[dd->my], curx[dd->mx]);
+ *b = 0;
+ break;
+ case 'u':
+ move(0, 0);
+ clrtoeol();
+ prints("%s色%s cont=%d",
+ (dd->brd[dd->my][dd->mx].color == RED) ? "紅" : "黑",
+ rname[dd->brd[dd->my][dd->mx].value], dd->cont);
+ *b = -1;
+ break;
+ case KEY_ENTER: /* 吃 or 移動 ly跟lx必須大於0 */
+ if (
+ dd->mly >= 0 /* 要先選子 */
+ &&
+ dd->brd[dd->mly][dd->mlx].color != dd->brd[dd->my][dd->mx].color /* 同色不能移動也不能吃 */
+ &&
+ (Is_move(dd, dd->my, dd->mx, dd->mly, dd->mlx) ||
+ Is_win(dd, dd->brd[dd->mly][dd->mlx], dd->brd[dd->my][dd->mx], dd->my, dd->mx, dd->mly, dd->mlx))
+ ) {
+ if (dd->fix && dd->brd[dd->my][dd->mx].value < 0) {
+ *b = -1;
+ return 0;
+ }
+ if (dd->brd[dd->my][dd->mx].value >= 0 && dd->brd[dd->my][dd->mx].die == 0) {
+ if (!color)
+ dd->bcount--;
+ else
+ dd->rcount--;
+ move(dd->cur_eaty, dd->cur_eatx);
+ if(color)
+ outs(bname[dd->brd[dd->my][dd->mx].value]);
+ else
+ outs(rname[dd->brd[dd->my][dd->mx].value]);
+ if (dd->cur_eatx >= 26) {
+ dd->cur_eatx = 5;
+ dd->cur_eaty++;
+ } else
+ dd->cur_eatx += 3;
+ }
+ brdswap(dd, dd->my, dd->mx, dd->mly, dd->mlx);
+ draw_line(dd, dd->mly, -1);
+ draw_line(dd, dd->my, -1);
+ if (dd->fix == 1)
+ *b = -1;
+ else {
+ dd->mly = -1;
+ dd->mlx = -1;
+ *b = 0;
+ }
+ } else
+ *b = -1;
+ break;
+ default:
+ *b = -1;
+ }
+
+ if (!dd->rcount)
+ return -1;
+ else if (!dd->bcount)
+ return -1;
+ if (*b == -1)
+ return 0;
+ dd->curr.y = dd->my;
+ dd->curr.x = dd->mx;
+ dd->curr.end = (!*b) ? 1 : 0;
+ send(fd, &dd->curr, sizeof(dd->curr), 0);
+ send(fd, &dd->brd, sizeof(dd->brd), 0);
+ return 0;
+}
+
+int
+main_dark(int fd, userinfo_t * uin)
+{
+ sint end = 0, ch = 1, i = 0;
+ char buf[16];
+ struct DarkData dd;
+
+ memset(&dd, 0, sizeof(dd));
+ dd.my=dd.mx=0;
+ dd.mly=dd.mlx=-1;
+
+ *buf = 0;
+ dd.fix = 0;
+ currutmp->color = '.';
+ /* '.' 表示還沒決定顏色 */
+ dd.rcount = 16;
+ dd.bcount = 16;
+ //initialize
+ dd.cur_eaty = 18, dd.cur_eatx = 5;
+ setutmpmode(DARK);
+ brd_prints();
+ if (currutmp->turn) {
+ brd_rand(&dd);
+ send(fd, &dd.brd, sizeof(dd.brd), 0);
+ mvouts(21, 0, " " ANSI_COLOR(1;37) ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;37) "你是先手" ANSI_RESET);
+ mvouts(22, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(5;35) "輪到你下了" ANSI_RESET);
+ } else {
+ recv(fd, &dd.brd, sizeof(dd.brd), 0);
+ mvouts(21, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;37) "你是後手" ANSI_RESET);
+ }
+ move(12, 3);
+ prints("%s[0勝0敗]" ANSI_COLOR(5;31) "vs" ANSI_COLOR(1;37) "." ANSI_RESET "%s[0勝0敗]", currutmp->userid, currutmp->mateid);
+ outs("\n"
+ " " ANSI_COLOR(1;36) "╳╱" ANSI_COLOR(1;31) "功\能表" ANSI_COLOR(1;36) "╲╳╲╱╳╲" ANSI_RESET "\n"
+ " " ANSI_COLOR(1;36) "╱" ANSI_COLOR(1;33) " ↑←↓→" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) "移動" ANSI_RESET "\n"
+ " " ANSI_COLOR(1;36) "╳" ANSI_COLOR(1;33) " s" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " 選子,翻子" ANSI_RESET "\n"
+ " " ANSI_COLOR(1;36) "╱" ANSI_COLOR(1;33) " enter" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " 吃棋,放棋" ANSI_RESET "\n"
+ " " ANSI_COLOR(1;33) "已經解決的" ANSI_COLOR(1;37) ":" ANSI_COLOR(1;36) "   ╳" ANSI_COLOR(1;33) " p" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " 合棋" ANSI_RESET "\n"
+ "    " ANSI_COLOR(1;36) "╱" ANSI_COLOR(1;33) " q" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " 認輸" ANSI_RESET "\n"
+ " " ANSI_COLOR(1;36) "╳" ANSI_COLOR(1;33) " c" ANSI_COLOR(1;37) ": " ANSI_COLOR(1;35) " 換邊" ANSI_RESET);
+
+ 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 = igetch();
+ if (ch == I_OTHERDATA) {
+ ch = recv(fd, &dd.curr, sizeof(dd.curr), 0);
+ if (ch != sizeof(dd.curr)) {
+ if (uin->turn == 'e') {
+ end = -3;
+ break;
+ } else if (uin->turn != 'w') {
+ end = -1;
+ currutmp->turn = 'w';
+ break;
+ }
+ end = -1;
+ break;
+ }
+ if (dd.curr.end == -3)
+ mvouts(23, 30, ANSI_COLOR(33) "要求合棋" ANSI_RESET);
+ else if (dd.curr.end == -4)
+ mvouts(23, 30, ANSI_COLOR(33) "要求換邊" ANSI_RESET);
+ else if (dd.curr.end == -5)
+ mvouts(23, 30, ANSI_COLOR(33) "要求連吃" ANSI_RESET);
+ else
+ mvouts(23, 30, "");
+
+ recv(fd, &dd.brd, sizeof(dd.brd), 0);
+ dd.my = dd.curr.y;
+ dd.mx = dd.curr.x;
+ redraw(&dd);
+ if (dd.curr.end)
+ mvouts(22, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(5;35) "輪到你下了" ANSI_RESET);
+ move(cury[dd.my], curx[dd.mx]);
+ } else {
+ if (currutmp->turn == 'p') {
+ if (ch == 'y') {
+ end = -3;
+ currutmp->turn = 'e';
+ break;
+ } else {
+ mvouts(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';
+ mvouts(21, 0, (currutmp->color == '1') ? " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;31) "你持紅色棋" ANSI_RESET : " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;36) "你持黑色棋" ANSI_RESET);
+ } else {
+ mvouts(23, 30, "");
+ currutmp->turn = (uin->turn) ? 0 : 1;
+ }
+ } else if (currutmp->turn == 'g') {
+ if (ch == 'y') {
+ dd.cont = 1;
+ mvouts(21, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;31) "你持紅色棋" ANSI_RESET " 可連吃");
+ } else {
+ mvouts(23, 30, "");
+ currutmp->turn = (uin->turn) ? 0 : 1;
+ }
+ }
+ if (currutmp->turn == 1) {
+ sint go_on = 0;
+ if (uin->turn == 'g') {
+ dd.cont = 1;
+ uin->turn = (currutmp->turn) ? 0 : 1;
+ mvouts(21, 10, "可連吃");
+ }
+ end = playing(&dd, 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';
+ dd.curr.end = -3;
+ send(fd, &dd.curr, sizeof(dd.curr), 0);
+ send(fd, &dd.brd, sizeof(buf), 0);
+ continue;
+ } else if (end == -4) {
+ if (currutmp->color != '1' && currutmp->color != '0')
+ continue;
+ uin->turn = 'c';
+ i = 0;
+ dd.curr.end = -4;
+ send(fd, &dd.curr, sizeof(dd.curr), 0);
+ send(fd, &dd.brd, sizeof(buf), 0);
+ continue;
+ } else if (end == -5) {
+ uin->turn = 'g';
+ dd.curr.end = -5;
+ send(fd, &dd.curr, sizeof(dd.curr), 0);
+ send(fd, &dd.brd, sizeof(buf), 0);
+ continue;
+ }
+ if (!i && currutmp->color == '1') {
+ mvouts(21, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;31) "你持紅色棋" ANSI_RESET);
+ i++;
+ move(cury[dd.my], curx[dd.mx]);
+ }
+ if (!i && currutmp->color == '0') {
+ mvouts(21, 0, " " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;36) "你持黑色棋" ANSI_RESET);
+ i++;
+ move(cury[dd.my], curx[dd.mx]);
+ }
+ if (uin->turn == 'e') {
+ end = -3;
+ break;
+ }
+ if (go_on < 0)
+ continue;
+
+ move(22, 0);
+ clrtoeol();
+ prints(" " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;37) "輪到%s下 別怕別怕 他算啥米" ANSI_RESET, currutmp->mateid);
+ currutmp->turn = 0;
+ uin->turn = 1;
+ } else {
+ if (ch == 'q') {
+ uin->turn = 'w';
+ break;
+ }
+ move(22, 0);
+ clrtoeol();
+ prints(" " ANSI_COLOR(1;33) "◆" ANSI_COLOR(1;37) "輪到%s下 別怕別怕 他算啥米" ANSI_RESET, currutmp->mateid);
+ }
+ }
+ }
+
+ switch (end) {
+ case -1:
+ case -2:
+ if (currutmp->turn == 'w') {
+ move(22, 0);
+ clrtoeol();
+ outs(ANSI_COLOR(1;31) "你贏了.. 真是恭喜~~" ANSI_RESET);
+ } else {
+ move(22, 0);
+ clrtoeol();
+ outs(ANSI_COLOR(1;31) "輸掉了啦.....下次讓他好看!!" ANSI_RESET);
+ }
+ break;
+ case -3:
+ mvouts(22, 0, ANSI_COLOR(1;31) "合棋唷!! 下次在分高下吧 ^_^" ANSI_RESET);
+ break;
+ default:
+ add_io(0, 0);
+ close(fd);
+ pressanykey();
+ return 0;
+ }
+ add_io(0, 0);
+ close(fd);
+ pressanykey();
+ return 0;
+}