//象 void CMoveGenerator::Gen_ElephantMove(BYTE position[10][9],int i,int j,int nPly) { int x,y; //插入右下方的有效走法 x=j+2; y=i+2; if(x<9 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入右上方的有效走法 x=j+2; y=i-2; if(x<9 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左下方的有效走法 x=j-2; y=i+2; if(x>=0 && y<10 && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左上方的有效走法 x=j-2; y=i-2; if(x>=0 && y>=0 && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); }
void Solver::PrintSolution(void) { AnimCube->MoveList.Reset(); Window->ListClear(); Window->ListAdd(0); Window->SetMovesNum(solutionLength1 + solutionLength2); for (int i = 0; i < solutionLength1; i++) AddMove(TranslateMove(solutionMoves1[i], solutionPowers1[i], 0)); for (int i = 0; i < solutionLength2; i++) AddMove(TranslateMove(solutionMoves2[i], solutionPowers2[i], 1)); }
void CMoveGenerator::Gen_KingMove(BYTE position[10][9],int i,int j,int nPly) { int x,y; for(y=0;y<3;y++) for(x=3;x<6;x++) if(IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); for(y=7;y<10;y++) for(x=3;x<6;x++) if(IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); }
void Kyokumen::MoveKing(Teban teban, int &teNum, Te *teTop, Kiki kiki) { int i; int id = -1; //隣接王手駒の位置のid // 両王手でないなら王手駒の位置を探す. for (i=0; i < DIRECT_NUM_FOR_PIN; i++) { if (kiki & (1 << i)) { id = i; break; } } if (id >= 0) { // 隣接の王手 最初に取る手を生成するのだ. if (teban == SELF) { KomaInf koma = m_Ban[m_KingS-Direct[id]]; if ((koma == EMPTY || (koma & ENEMY) != 0) && !CountControlE(m_KingS - Direct[id]) // 敵の駒が効いていない. && (kiki & (1 << (DIRECT_RIGHT_UP+KIKI_JUMP_OFFSET-id))) == 0) { // 敵の飛駒で貫かれていない. AddMove(teban, teNum, teTop, m_KingS, -Direct[id], 0); } } else { KomaInf koma = m_Ban[m_KingE-Direct[id]]; if ((koma == EMPTY || (koma & SELF) != 0) && !CountControlS(m_KingE - Direct[id]) // 敵の駒が効いていない. && (kiki & (1 << (DIRECT_RIGHT_UP+KIKI_JUMP_OFFSET-id))) == 0) { // 敵の飛駒で貫かれていない. AddMove(teban, teNum, teTop, m_KingE, -Direct[id], 0); } } } for (i=0; i < DIRECT_NUM_FOR_PIN; i++) { if (i == id) continue; if (teban == SELF) { KomaInf koma = m_Ban[m_KingS-Direct[i]]; if ((koma == EMPTY || (koma & ENEMY) != 0) && !CountControlE(m_KingS - Direct[i]) // 敵の駒が効いていない. && (kiki & (1 << (DIRECT_RIGHT_UP+KIKI_JUMP_OFFSET-i))) == 0) { // 敵の飛駒で貫かれていない. AddMove(teban,teNum, teTop, m_KingS, -Direct[i], 0); } } else { KomaInf koma = m_Ban[m_KingE-Direct[i]]; if ((koma==EMPTY || (koma & SELF) != 0) && !CountControlS(m_KingE - Direct[i]) // 敵の駒が効いていない. && (kiki & (1 << (DIRECT_RIGHT_UP+KIKI_JUMP_OFFSET-i))) == 0) { // 敵の飛駒で貫かれていない. AddMove(teban,teNum, teTop, m_KingE, -Direct[i], 0); } } } }
void Kyokumen::AddStraight(Teban teban, int &teNum, Te *teTop, KomaPos from, int dir, int pin, int Rpin) { if (dir == Rpin || dir == -Rpin) { return; } int i; if (pin == 0 || pin == dir || pin == -dir) { // 空白の間、動く手を生成する. for(i=dir; m_Ban[from+i] == EMPTY; i+=dir) { AddMove(teban, teNum, teTop, from, i, 0); } // 味方の駒でないなら、そこへ動く. if ((m_Ban[from+i] & teban) == 0) { AddMove(teban, teNum, teTop, from, i, 0); } } }
void Kyokumen::MoveTo(Teban teban, int &teNum, Te *teTop, KomaPos to, int* pin) { int p; KomaInf koma; for(int i=0; i < DIRECT_NUM; i++) { koma = m_Ban[to-Direct[i]]; if (koma == EMPTY) { p = search(to, -Direct[i]); if ((m_Ban[p] & teban) != 0 && CanJump[i][m_Ban[p]]) { AddMove(teban, teNum, teTop, p, to-p, pin[p]); } } else { if ((koma&~teban) != OU && (koma&teban) != 0 && (CanMove[i][koma] || CanJump[i][koma])) { AddMove(teban, teNum, teTop, to-Direct[i], Direct[i], pin[to-Direct[i]]); } } } }
//马 void CMoveGenerator::Gen_HorseMove(BYTE position[10][9], int i, int j, int nPly) { int x, y; //插入右下方的有效走法 x=j+2;//右2 y=i+1;//下1 if((x<9 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入右上方的有效走法 x=j+2;//右2 y=i-1;//上1 if((x<9 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左下方的有效走法 x=j-2;//左2 y=i+1;//下1 if((x>=0 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左上方的有效走法 x=j-2;//左2 y=i-1;//上1 if((x>=0 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入右下方的有效走法 x=j+1;//右1 y=i+2;//下2 if((x<9 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左下方的有效走法 x=j-1;//左1 y=i+2;//下2 if((x>=0 && y<10) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入右上方的有效走法 x=j+1;//右1 y=i-2;//上2 if((x<9 && y >=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); //插入左上方的有效走法 x=j-1;//左1 y=i-2;//上2 if((x>=0 && y>=0) && IsValidMove(position,j,i,x,y,m_nUserChessColor)) AddMove(j,i,x,y,nPly,position[i][j]); }
void PlayerMoveList::AddMoves(int _idSquare, std::vector<int> _aDeltasX, std::vector<int> _aDeltasY) { if (_aDeltasX.size() > _aDeltasY.size()) { for (size_t i = _aDeltasY.size(); i < _aDeltasX.size(); i++) { _aDeltasY.push_back(0); } } else if (_aDeltasX.size() < _aDeltasY.size()) { for (size_t i = _aDeltasX.size(); i < _aDeltasY.size(); i++) { _aDeltasX.push_back(0); } } for (size_t i = 0; i < _aDeltasX.size(); i++) { AddMove(_aDeltasX[i], _aDeltasY[i], _idSquare); } }
/* Finds legal non-jump moves for the Piece at position x,y */ void FindMoves(int player, int board[8][8], int x, int y) { int i,j,x1,y1,move[12]; memset(move,0,12*sizeof(int)); if(player == 1) j = 1; else j = -1; /* Check the two adjacent squares in the forward direction */ for(i=-1; i<2; i+=2) { y1 = y+j; x1 = x+i; /* Make sure we're not off the edge of the board */ if(y1<0 || y1>7 || x1<0 || x1>7) continue; if(!board[y1][x1]) { /* The square is empty, so we can move there */ move[0] = square[y][x].val; move[1] = square[y1][x1].val; AddMove(move); } } }
/* Finds legal non-jump moves for the King at position x,y */ void FindKingMoves(int board[8][8], int x, int y) { int i,j,x1,y1,move[12]; memset(move,0,12*sizeof(int)); /* Check the four adjacent squares */ for(j=-1; j<2; j+=2) for(i=-1; i<2; i+=2) { y1 = y+j; x1 = x+i; /* Make sure we're not off the edge of the board */ if(y1<0 || y1>7 || x1<0 || x1>7) continue; if(!board[y1][x1]) { /* The square is empty, so we can move there */ move[0] = square[y][x].val; move[1] = square[y1][x1].val; AddMove(move); } } }
//黑卒 void CMoveGenerator::Gen_BPawnMove(BYTE position[10][9],int i,int j,int nPly) { int x,y; int nChessID; nChessID=position[i][j]; if(m_nUserChessColor==REDCHESS) { y=i+1;//向前 x=j; if(y<10 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍 if(i>4)//是否已过河 { y=i; x=j+1;//右边 if(x<9 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); x=j-1;//左边 if(x>=0 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); } } else { y=i-1;//向前 x=j; if(y<10 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]);//前方无阻碍 if(i<5)//是否已过河 { y=i; x=j+1;//右边 if(x<9 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); x=j-1;//左边 if(x>=0 && !IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); } } }
bool TEngine::Tick2(board_t * board, TFindPos * fp, bool full) { mv_t pv[3]; if (SearchPos(board,fp,pv, full)) { int pv_len = 0; for (int i=0; i<3; i++) { if (pv[i]==0) break; else pv_len++; } switch (pv_len) { case 0: if (LastMove) { LastMove = 0; StartNewThink(); } if (!GameStarted) { StartNewGame(); GameStarted = true; } return true; case 1: StateNewGame = false; if (LastMove != pv[0]) { LastMove = pv[0]; StartNewThink(); } return true; case 2: StateNewGame = false; AddMove(pv[0]); LastMove = pv[1]; StartNewThink(); return true; } } return false; }
//炮 void CMoveGenerator::Gen_CanonMove(BYTE position[10][9], int i, int j, int nPly) { int x,y; BOOL flag; int nChessID; nChessID=position[i][j]; //插入向右的有效的走法 x=j+1; y=i; flag=FALSE; while(x<9) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } x++;//继续下一个位置 } //插入向左的有效的走法 x=j-1; y=i; flag=FALSE; while(x>=0) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } x--;//继续下一个位置 } //插入向下的有效的走法 x=j; y=i+1; flag=FALSE; while(y<10) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } y++;//继续下一个位置 } //插入向上的有效的走法 x=j; y=i-1; flag=FALSE; while(y>=0) { if(NOCHESS==position[y][x]) { if(!flag)//隔有棋子 AddMove(j,i,x,y,nPly,position[i][j]); } else { if(!flag)//没有隔棋子,此棋子是第一个障碍,设置标志 flag=TRUE; else //隔有棋子,此处如为敌方棋子,则可走 { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } } y--;//继续下一个位置 } }
//车 void CMoveGenerator::Gen_CarMove(BYTE position[10][9], int i, int j, int nPly) { int x,y; int nChessID; nChessID=position[i][j]; //插入向右的有效的走法 x=j+1; y=i; while(x<9) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } x++; } //插入向左的有效的走法 x=j-1; y=i; while(x>=0) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } x--; } //插入向下的有效的走法 x=j; y=i+1; while(y<10) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } y++; } //插入向上的有效的走法 x=j; y=i-1; while(y>=0) { if(NOCHESS==position[y][x]) AddMove(j,i,x,y,nPly,position[i][j]); else { if(!IsSameSide(nChessID,position[y][x])) AddMove(j,i,x,y,nPly,position[i][j]); break; } y--; } }
void GenerateMoves(Listnode *ml, Position *pos) { int i, j, x, y, direc, cancastle; unsigned char side = pos->side, xside; SQUARE board[12][12]; if(side == WHITE) { xside = BLACK; direc = 1; } else { xside = WHITE; direc = -1; } ClearMoves(ml); for(i = 0; i < MAXLEGAL; i++) { ml->moves[i].oldep = pos->epstatus; ml->moves[i].oldcastle = pos->castle; } memcpy(&(board[0][0]), &(pos->board[0][0]), sizeof(SQUARE) * 144); for(i = 2; i < 10; i++) { for(j = 2; j < 10; j++) { if(board[i][j] != 0 && (board[i][j] & side)) { if(board[i][j] & KNIGHT) { x = -1; y = -2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -1; y = 2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 1; y = -2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 1; y = 2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -2; y = -1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -2; y = 1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 2; y = -1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 2; y = 1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } } if((board[i][j] & BISHOP) || (board[i][j] & QUEEN)) { for(x = 1; (board[i-x][j-x] != OFFBOARD) && (!(board[i-x][j-x] & side)); x++) if(board[i-x][j-x] & xside) { AddMove(ml, i, j, i-x, j-x, CAPTURE); break; } else AddMove(ml, i, j, i-x, j-x, NORMAL); for(x = 1; (board[i-x][j+x] != OFFBOARD) && (!(board[i-x][j+x] & side)); x++) if(board[i-x][j+x] & xside) { AddMove(ml, i, j, i-x, j+x, CAPTURE); break; } else AddMove(ml, i, j, i-x, j+x, NORMAL); for(x = 1; (board[i+x][j-x] != OFFBOARD) && (!(board[i+x][j-x] & side)); x++) if(board[i+x][j-x] & xside) { AddMove(ml, i, j, i+x, j-x, CAPTURE); break; } else AddMove(ml, i, j, i+x, j-x, NORMAL); for(x = 1; (board[i+x][j+x] != OFFBOARD) && (!(board[i+x][j+x] & side)); x++) if(board[i+x][j+x] & xside) { AddMove(ml, i, j, i+x, j+x, CAPTURE); break; } else AddMove(ml, i, j, i+x, j+x, NORMAL); } if((board[i][j] & ROOK) || (board[i][j] & QUEEN)) { for(x = 1; (board[i-x][j] != OFFBOARD) && (!(board[i-x][j] & side)); x++) if(board[i-x][j] & xside) { AddMove(ml, i, j, i-x, j, CAPTURE); break; } else AddMove(ml, i, j, i-x, j, NORMAL); for(x = 1; (board[i+x][j] != OFFBOARD) && (!(board[i+x][j] & side)); x++) if(board[i+x][j] & xside) { AddMove(ml, i, j, i+x, j, CAPTURE); break; } else AddMove(ml, i, j, i+x, j, NORMAL); for(x = 1; (board[i][j-x] != OFFBOARD) && (!(board[i][j-x] & side)); x++) if(board[i][j-x] & xside) { AddMove(ml, i, j, i, j-x, CAPTURE); break; } else AddMove(ml, i, j, i, j-x, NORMAL); for(x = 1; (board[i][j+x] != OFFBOARD) && (!(board[i][j+x] & side)); x++) if(board[i][j+x] & xside) { AddMove(ml, i, j, i, j+x, CAPTURE); break; } else AddMove(ml, i, j, i, j+x, NORMAL); } if(board[i][j] & KING) { for(x = -1; x <= 1; x++) for(y = -1; y <= 1; y++) { if(x == 0 && y == 0) continue; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } } } if(board[i][j] & PAWN) { if(board[i][j+direc] == 0) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i, j+direc, PROMOTE); else AddMove(ml, i, j, i, j+direc, NORMAL); } if((direc == -1 && j == 8) || (direc == 1 && j == 3)) if(board[i][j+direc+direc] == 0 && board[i][j+direc] == 0) AddMove(ml, i, j, i, j+direc+direc, TWOMOVE); if((board[i-1][j+direc] != OFFBOARD) && (board[i-1][j+direc] & xside)) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i-1, j+direc, PROMCAP); else AddMove(ml, i, j, i-1, j+direc, CAPTURE); } if((board[i+1][j+direc] != OFFBOARD) && (board[i+1][j+direc] & xside)) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i+1, j+direc, PROMCAP); else AddMove(ml, i, j, i+1, j+direc, CAPTURE); } /* there is at least one ep square */ if(pos->epstatus > 0 && direc == 1) { if(j == 6 && IsEpSquare(i-1, 6, pos->epstatus) == 1 && board[i-1][j+direc] == 0) AddMove(ml, i, j, i-1, j+direc, ENPASSANT); if(j == 6 && IsEpSquare(i+1, 6, pos->epstatus) == 1 && board[i+1][j+direc] == 0) AddMove(ml, i, j, i+1, j+direc, ENPASSANT); } if(pos->epstatus > 0 && direc == -1) { if(j == 5 && IsEpSquare(i-1, 5, pos->epstatus) == 1 && board[i-1][j+direc] == 0) AddMove(ml, i, j, i-1, j+direc, ENPASSANT); if(j == 5 && IsEpSquare(i+1, 5, pos->epstatus) == 1 && board[i+1][j+direc] == 0) AddMove(ml, i, j, i+1, j+direc, ENPASSANT); } } } } } if((pos->castle & WKC) && side == WHITE) { cancastle = 1; for(i = KFILE; i <= 8; i++) if(Attacked(pos, i, 2, xside) == 1) cancastle = 0; for(i = Minval(7, KFILE); i <= 8; i++) if(i != KFILE && i != KRFILE && board[i][2] != 0) cancastle = 0; if(cancastle == 1) AddMove(ml, KFILE, 2, 8, 2, KSCASTLE); } if((pos->castle & BKC) && side == BLACK) { cancastle = 1; for(i = KFILE; i <= 8; i++) if(Attacked(pos, i, 9, xside) == 1) cancastle = 0; for(i = Minval(7, KFILE); i <= 8; i++) if(i != KFILE && i != KRFILE && board[i][9] != 0) cancastle = 0; if(cancastle == 1) AddMove(ml, KFILE, 9, 8, 9, KSCASTLE); } if((pos->castle & WQC) && side == WHITE) { cancastle = 1; for(i = Minval(4, KFILE); i <= Maxval(4, KFILE); i++) if(Attacked(pos, i, 2, xside) == 1) cancastle = 0; for(i = Minval(QRFILE + 1, 4); i <= Maxval(5, KFILE); i++) if(i != KFILE && i != QRFILE && board[i][2] != 0) cancastle = 0; if(cancastle == 1) AddMove(ml, KFILE, 2, 4, 2, QSCASTLE); } if((pos->castle & BQC) && side == BLACK) { cancastle = 1; for(i = Minval(4, KFILE); i <= Maxval(4, KFILE); i++) if(Attacked(pos, i, 9, xside) == 1) cancastle = 0; for(i = Minval(QRFILE + 1, 4); i <= Maxval(5, KFILE); i++) if(i != KFILE && i != QRFILE && board[i][9] != 0) cancastle = 0; if(cancastle == 1) AddMove(ml, KFILE, 9, 4, 9, QSCASTLE); } for(i = 0; ml->moves[i].mtype != EMPTY; i++) { MakeMove(pos, &(ml->moves[i])); if(IsCheck(pos, side) == 1) { UnmakeMove(pos, &(ml->moves[i])); ml->moves[i].mtype = EMPTY; ml->num--; } else UnmakeMove(pos, &(ml->moves[i])); } }
void GenerateLegalandIllegal(Listnode *ml, Position *pos) { int i, j, x, y, direc; unsigned char side = pos->side, xside; SQUARE board[12][12]; if(side == WHITE) { xside = BLACK; direc = 1; } else { xside = WHITE; direc = -1; } ClearMoves(ml); for(i = 0; i < MAXLEGAL; i++) { ml->moves[i].oldep = pos->epstatus; ml->moves[i].oldcastle = pos->castle; } memcpy(&(board[0][0]), &(pos->board[0][0]), sizeof(SQUARE) * 144); for(i = 2; i < 10; i++) for(j = 2; j < 10; j++) { if(board[i][j] != 0 && (board[i][j] & side)) { if(board[i][j] & KNIGHT) { x = -1; y = -2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -1; y = 2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 1; y = -2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 1; y = 2; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -2; y = -1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = -2; y = 1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 2; y = -1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } x = 2; y = 1; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } } if((board[i][j] & BISHOP) || (board[i][j] & QUEEN)) { for(x = 1; (board[i-x][j-x] != OFFBOARD) && (!(board[i-x][j-x] & side)); x++) if(board[i-x][j-x] & xside) { AddMove(ml, i, j, i-x, j-x, CAPTURE); break; } else AddMove(ml, i, j, i-x, j-x, NORMAL); for(x = 1; (board[i-x][j+x] != OFFBOARD) && (!(board[i-x][j+x] & side)); x++) if(board[i-x][j+x] & xside) { AddMove(ml, i, j, i-x, j+x, CAPTURE); break; } else AddMove(ml, i, j, i-x, j+x, NORMAL); for(x = 1; (board[i+x][j-x] != OFFBOARD) && (!(board[i+x][j-x] & side)); x++) if(board[i+x][j-x] & xside) { AddMove(ml, i, j, i+x, j-x, CAPTURE); break; } else AddMove(ml, i, j, i+x, j-x, NORMAL); for(x = 1; (board[i+x][j+x] != OFFBOARD) && (!(board[i+x][j+x] & side)); x++) if(board[i+x][j+x] & xside) { AddMove(ml, i, j, i+x, j+x, CAPTURE); break; } else AddMove(ml, i, j, i+x, j+x, NORMAL); } if((board[i][j] & ROOK) || (board[i][j] & QUEEN)) { for(x = 1; (board[i-x][j] != OFFBOARD) && (!(board[i-x][j] & side)); x++) if(board[i-x][j] & xside) { AddMove(ml, i, j, i-x, j, CAPTURE); break; } else AddMove(ml, i, j, i-x, j, NORMAL); for(x = 1; (board[i+x][j] != OFFBOARD) && (!(board[i+x][j] & side)); x++) if(board[i+x][j] & xside) { AddMove(ml, i, j, i+x, j, CAPTURE); break; } else AddMove(ml, i, j, i+x, j, NORMAL); for(x = 1; (board[i][j-x] != OFFBOARD) && (!(board[i][j-x] & side)); x++) if(board[i][j-x] & xside) { AddMove(ml, i, j, i, j-x, CAPTURE); break; } else AddMove(ml, i, j, i, j-x, NORMAL); for(x = 1; (board[i][j+x] != OFFBOARD) && (!(board[i][j+x] & side)); x++) if(board[i][j+x] & xside) { AddMove(ml, i, j, i, j+x, CAPTURE); break; } else AddMove(ml, i, j, i, j+x, NORMAL); } if(board[i][j] & KING) { for(x = -1; x <= 1; x++) { for(y = -1; y <= 1; y++) { if(x == 0 && y == 0) continue; if((board[i+x][j+y] != OFFBOARD) && (!(board[i+x][j+y] & side))) { if(board[i+x][j+y] & xside) AddMove(ml, i, j, i+x, j+y, CAPTURE); else AddMove(ml, i, j, i+x, j+y, NORMAL); } } } } if(board[i][j] & PAWN) { if(board[i][j+direc] == 0) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i, j+direc, PROMOTE); else AddMove(ml, i, j, i, j+direc, NORMAL); } if((direc == -1 && j == 8) || (direc == 1 && j == 3)) if(board[i][j+direc+direc] == 0 && board[i][j+direc] == 0) AddMove(ml, i, j, i, j+direc+direc, TWOMOVE); if((board[i-1][j+direc] != OFFBOARD) && (board[i-1][j+direc] & xside)) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i-1, j+direc, PROMCAP); else AddMove(ml, i, j, i-1, j+direc, CAPTURE); } if((board[i+1][j+direc] != OFFBOARD) && (board[i+1][j+direc] & xside)) { if((direc == -1 && j == 3) || (direc == 1 && j == 8)) AddMove(ml, i, j, i+1, j+direc, PROMCAP); else AddMove(ml, i, j, i+1, j+direc, CAPTURE); } if(pos->epstatus > 0 && direc == 1) /* there is at least one ep square */ { if(j == 6 && IsEpSquare(i-1, 6, pos->epstatus) == 1 && board[i-1][j+direc] == 0) AddMove(ml, i, j, i-1, j+direc, ENPASSANT); if(j == 6 && IsEpSquare(i+1, 6, pos->epstatus) == 1 && board[i+1][j+direc] == 0) AddMove(ml, i, j, i+1, j+direc, ENPASSANT); } if(pos->epstatus > 0 && direc == -1) { if(j == 5 && IsEpSquare(i-1, 5, pos->epstatus) == 1 && board[i-1][j+direc] == 0) AddMove(ml, i, j, i-1, j+direc, ENPASSANT); if(j == 5 && IsEpSquare(i+1, 5, pos->epstatus) == 1 && board[i+1][j+direc] == 0) AddMove(ml, i, j, i+1, j+direc, ENPASSANT); } } } } }
void Kyokumen::AddMoves(Teban teban, int &teNum, Te *teTop, KomaPos from, int pin, int Rpin) { switch(m_Ban[from]) { case SFU: AddMove(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); break; case EFU: AddMove(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); break; case SKY: AddStraight(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); break; case EKY: AddStraight(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); break; case SKE: AddMove(teban, teNum, teTop, from, Direct[DIRECT_SKE_1], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_SKE_2], pin, Rpin); break; case EKE: AddMove(teban, teNum, teTop, from, Direct[DIRECT_EKE_1], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_EKE_2], pin, Rpin); break; case SGI: AddMove(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_DOWN], pin, Rpin); break; case EGI: AddMove(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_UP], pin, Rpin); break; case SKI:case STO:case SNY:case SNK:case SNG: AddMove(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT], pin, Rpin); break; case EKI:case ETO:case ENY:case ENK:case ENG: AddMove(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT], pin, Rpin); break; case SRY:case ERY: AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_UP], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT_UP], pin, Rpin); case SHI:case EHI: AddStraight(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_RIGHT], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_LEFT], pin, Rpin); break; case SUM:case EUM: AddMove(teban, teNum, teTop, from, Direct[DIRECT_DOWN], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_LEFT], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_RIGHT], pin, Rpin); AddMove(teban, teNum, teTop, from, Direct[DIRECT_UP], pin, Rpin); case SKA:case EKA: AddStraight(teban, teNum, teTop, from, Direct[DIRECT_LEFT_DOWN], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_UP], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_LEFT_UP], pin, Rpin); AddStraight(teban, teNum, teTop, from, Direct[DIRECT_RIGHT_DOWN], pin, Rpin); break; case SOU:case EOU: MoveKing(teban, teNum, teTop, 0); // 王手がかかっている時には、AntiCheckの方が呼ばれるから、Kikiは0です。 break; } }