diff options
Diffstat (limited to 'mbbsd/chc_rule.c')
-rw-r--r-- | mbbsd/chc_rule.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/mbbsd/chc_rule.c b/mbbsd/chc_rule.c new file mode 100644 index 00000000..35d8fe6a --- /dev/null +++ b/mbbsd/chc_rule.c @@ -0,0 +1,186 @@ +/* $Id: chc_rule.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <sys/types.h> +#include <string.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern rc_t chc_from, chc_to; +extern int chc_my; + +#define CENTER(a, b) (((a) + (b)) >> 1) + +void chc_init_board(board_t board) { + memset(board, 0, sizeof(board_t)); + board[0][4] = CHE(1, chc_my ^ 1); /* 將 */ + board[0][3] = board[0][5] = CHE(2, chc_my ^ 1); /* 士 */ + board[0][2] = board[0][6] = CHE(3, chc_my ^ 1); /* 象 */ + board[0][0] = board[0][8] = CHE(4, chc_my ^ 1); /* 車 */ + board[0][1] = board[0][7] = CHE(5, chc_my ^ 1); /* 馬 */ + board[2][1] = board[2][7] = CHE(6, chc_my ^ 1); /* 包 */ + board[3][0] = board[3][2] = board[3][4] = + board[3][6] = board[3][8] = CHE(7, chc_my ^ 1); /* 卒 */ + + board[9][4] = CHE(1, chc_my); /* 帥 */ + board[9][3] = board[9][5] = CHE(2, chc_my); /* 仕 */ + board[9][2] = board[9][6] = CHE(3, chc_my); /* 相 */ + board[9][0] = board[9][8] = CHE(4, chc_my); /* 車 */ + board[9][1] = board[9][7] = CHE(5, chc_my); /* 傌 */ + board[7][1] = board[7][7] = CHE(6, chc_my); /* 炮 */ + board[6][0] = board[6][2] = board[6][4] = + board[6][6] = board[6][8] = CHE(7, chc_my); /* 兵 */ +} + +void chc_movechess(board_t board) { + board[chc_to.r][chc_to.c] = board[chc_from.r][chc_from.c]; + board[chc_from.r][chc_from.c] = 0; +} + +static int dist(rc_t from, rc_t to, int rowcol) { + int d; + + d = rowcol ? from.c - to.c : from.r - to.r; + return d > 0 ? d : -d; +} + +static int between(board_t board, rc_t from, rc_t to, int rowcol) { + int i, rtv = 0; + + if(rowcol) { + if(from.c > to.c) + i = from.c, from.c = to.c, to.c = i; + for(i = from.c + 1; i < to.c; i++) + if(board[to.r][i]) rtv++; + } else { + if(from.r > to.r) + i = from.r, from.r = to.r, to.r = i; + for(i = from.r + 1; i < to.r; i++) + if(board[i][to.c]) rtv++; + } + return rtv; +} + +int chc_canmove(board_t board, rc_t from, rc_t to) { + int i; + int rd, cd, turn; + + rd = dist(from, to, 0); + cd = dist(from, to, 1); + turn = CHE_O(board[from.r][from.c]); + + /* general check */ + if(board[to.r][to.c] && CHE_O(board[to.r][to.c]) == turn) + return 0; + + /* individual check */ + switch(CHE_P(board[from.r][from.c])) { + case 1: /* 將 帥 */ + if(!(rd == 1 && cd == 0) && + !(rd == 0 && cd == 1)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 2) || + (turn == chc_my && to.r < 7) || + to.c < 3 || to.c > 5) + return 0; + break; + case 2: /* 士 仕 */ + if(!(rd == 1 && cd == 1)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 2) || + (turn == chc_my && to.r < 7) || + to.c < 3 || to.c > 5) + return 0; + break; + case 3: /* 象 相 */ + if(!(rd == 2 && cd == 2)) + return 0; + if((turn == (chc_my ^ 1) && to.r > 4) || + (turn == chc_my && to.r < 5)) + return 0; + /* 拐象腿 */ + if(board[CENTER(from.r, to.r)][CENTER(from.c, to.c)]) + return 0; + break; + case 4: /* 車 */ + if(!(rd > 0 && cd == 0) && + !(rd == 0 && cd > 0)) + return 0; + if(between(board, from, to, rd == 0)) + return 0; + break; + case 5: /* 馬 傌 */ + if(!(rd == 2 && cd == 1) && + !(rd == 1 && cd == 2)) + return 0; + /* 拐馬腳 */ + if(rd == 2) { + if(board[CENTER(from.r, to.r)][from.c]) + return 0; + } else { + if(board[from.r][CENTER(from.c, to.c)]) + return 0; + } + break; + case 6: /* 包 炮 */ + if(!(rd > 0 && cd == 0) && + !(rd == 0 && cd > 0)) + return 0; + i = between(board, from, to, rd == 0); + if((i > 1) || + (i == 1 && !board[to.r][to.c]) || + (i == 0 && board[to.r][to.c])) + return 0; + break; + case 7: /* 卒 兵 */ + if(!(rd == 1 && cd == 0) && + !(rd == 0 && cd == 1)) + return 0; + if(((turn == (chc_my ^ 1) && to.r < 5) || + (turn == chc_my && to.r > 4)) && + cd != 0) + return 0; + if((turn == (chc_my ^ 1) && to.r < from.r) || + (turn == chc_my && to.r > from.r)) + return 0; + break; + } + return 1; +} + +static void findking(board_t board, int turn, rc_t *buf) { + int i, r, c; + + r = (turn == (chc_my ^ 1)) ? 0 : 7; + for(i = 0; i < 3; r++, i++) + for(c = 3; c < 6; c++) + if(CHE_P(board[r][c]) == 1 && + CHE_O(board[r][c]) == turn) { + buf->r = r, buf->c = c; + return ; + } +} + +int chc_iskfk(board_t board) { + rc_t from, to; + + findking(board, 0, &to); + findking(board, 1, &from); + if(from.c == to.c && between(board, from, to, 0) == 0) + return 1; + return 0; +} + +int chc_ischeck(board_t board, int turn) { + rc_t from, to; + + findking(board, turn, &to); + for(from.r = 0;from.r < BRD_ROW; from.r++) + for(from.c = 0; from.c < BRD_COL; from.c++) + if(board[from.r][from.c] && + CHE_O(board[from.r][from.c]) != turn) + if(chc_canmove(board, from, to)) + return 1; + return 0; +} |