summaryrefslogblamecommitdiffstats
path: root/mbbsd/dark.c
blob: 4c9c6486cc8aa27337d307fd28a8ae19f69fea4f (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                                                     
                





                       

                                           
 


                              
 

                                                
 

                                                                     
 

                                                                               
                                                                           
 
                                                                    
           





                                                   

 
           


                                
               
                    

 
                    




                                                            
                     
























                                                       
         



                         


                 








                                                                                                 



             
                    


                                                                                               



                 
           





                                                                                



                               









                                                       



                      
           

            
            
               
             









                                                             

 
           



                                        


             
                                             

                               
                                               
                                    
                                               
              



                                                                           
         
                         
     
                            
 
                     
               
                      

 
           




                          

 
                    

                                                                 
                 
                             
 




                        
                
                               

         
                 
                  





                                 

                   





                                 

                





                                 

                  





                                 
              






                       
                  

             




                  
                                                           
                      


                                             

                      




                                              
                      










                                                                    
             
                    


                      



                                                    
                              


                                                                  
                





                                                                  

              



                                                                                                           
              
                                                                 
              

                                              
              
                                                                                  
              




                                                                                               
             


                                                                 
                    







                                                                                            
             











                                      

              
                
     

                
                  
                     
                  






                                     


             
   






                                                            

                              


                                    
                 
                         
                   





                                                                
     

                                                                                             
             






                                                                                                                           
 

                               

                  




                                                        
                       












                                                  
             







                                                          
 


                                           
                     












                                                                   
                 















                                                                                                                                                   
                 
             






                                                                          
 










                                                     
                             

                                                                         
                                 




                                                     
                             




                                                     

                             















                                                                             
 


                                                                                             

                                   







                                                                                             



             
                  

            









                                                            
            

                                                                
            



                      
     
                 



                  
/* $Id: dark.c,v 1.8 2002/07/22 19:02:00 in2 Exp $ */
#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;

static item     brd[4][8];
static cur      curr;       /* 6 個 bytes */

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; i < max; i++)
        if (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 (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)) && 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(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 + now % 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("\n"
     "   ╭─┬─┬─┬─┬─┬─┬─┬─╮\n"
     "   │●│●│●│●│●│●│●│●│\n"
     "   ├─┼─┼─┼─┼─┼─┼─┼─┤\n"
     "   │●│●│●│●│●│●│●│●│\n"
     "   ├─┼─┼─┼─┼─┼─┼─┼─┤\n"
     "   │●│●│●│●│●│●│●│●│\n"
     "   ├─┼─┼─┼─┼─┼─┼─┼─┤\n"
     "   │●│●│●│●│●│●│●│●│\n"
     "   ╰─┴─┴─┴─┴─┴─┴─┴─╯\n"
     "   ");
}

static void
draw_line(sint y, sint f)
{
    sint            i;
    char            buf[1024], tmp[256];

    *buf = 0;
    *tmp = 0;
    strlcpy(buf, "\033[43;30m", sizeof(buf));
    for (i = 0; i < 8; i++) {
    if (brd[y][i].die == 1)
        snprintf(tmp, sizeof(tmp), "│  ");
    else if (brd[y][i].out == 0)
        snprintf(tmp, sizeof(tmp), "│●");
    else {
        snprintf(tmp, sizeof(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("\n"
     "                                                ╳╱功\能表╲╳╲╱╳╲\n"
     "                                                ╱ ↑←↓→: 移動\n"
     "                                                ╳ s:       選子,翻子\n"
     "                                                ╱ enter:    吃棋,放棋\n"
     " 已經解決的:                                 ╳ p:       合棋\n"
     "                                              ╱ q:       認輸\n"
     "                                                ╳ 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;
}