Пример #1
0
int solution_piece_matches_edge(solution_t* s, piece_t* p, int pos) {
     int r,c,m=0;
     dir edge_dir;
     dir d;
     piece_t*** mat;
     int colA,colB;

     r=pos/(s->n);
     c=pos%(s->n);
     mat=s->mat;
     if (p==NULL) {
          p=mat[r][c];
     }
     edge_dir=direction_edge(pos,s->n);
     for(d=DOWN;d<=RIGHT;d++) {
          if (d!=edge_dir) {
               colA=PIECE_COLOUR(p,d);
               //colA=squares[p->square_index]->colour[ROTATE(p->rotation,d)];
               colB=PIECE_COLOUR(mat[r+ADJACENT[d*2]] [c+ADJACENT[d*2+1]],OPPOSITE(d));
               /*colB=squares[mat[r+ADJACENT[d*2]][c+ADJACENT[d*2+1]]->square_index]->colour
                    [ROTATE(mat[r+ADJACENT[d*2]][c+ADJACENT[d*2+1]]->rotation, (d+2)%4)];*/
               if (colA==colB) m++;
          }
     }
     return (m);
}
Пример #2
0
static void alists_hidden(alists_t * alists, const board_t * board, int from, int to) {

   int inc;
   int sq, piece;

   ASSERT(alists!=NULL);
   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(to));

   inc = DELTA_INC_LINE(to-from);

   if (inc != IncNone) { // line

      sq = from;
      do sq -= inc; while ((piece=board->square[sq]) == Empty);

      if (SLIDER_ATTACK(piece,inc)) {

         ASSERT(piece_is_ok(piece));
         ASSERT(PIECE_IS_SLIDER(piece));

         alist_add(alists->alist[PIECE_COLOUR(piece)],sq,board);
      }
   }
}
Пример #3
0
int solution_matches(solution_t* s){
    int i,j,n;
    int colA,colB; //used to make the code readable
    int cnt;
    piece_t ***mat;

    n=s->n;
    mat=s->mat;
    cnt=0;
    for(i=0;i<n;i++){
        if(i==0){
            //only horizontal-square_tcount
            for(j=1;j<n;j++){
                colA=PIECE_COLOUR(mat[i][j],LEFT);
                //squares[mat[i][j]->square_index]->colour[ROTATE(mat[i][j]->rotation,LEFT)];
                colB=PIECE_COLOUR(mat[i][j-1],RIGHT);
                //colB=squares[mat[i][j-1]->square_index]->colour[ROTATE(mat[i][j-1]->rotation,RIGHT)];
                if(colA==colB){
                cnt++;
                }
            }
        }
        else{
            //counting both vertical and horizontal
                //first column
                colA=PIECE_COLOUR(mat[i][0],UP);
                //colA=squares[mat[i][0]->square_index]->colour[ROTATE(mat[i][0]->rotation,UP)];
                colB=PIECE_COLOUR(mat[i-1][0],DOWN);
                //colB=squares[mat[i-1][0]->square_index]->colour[ROTATE(mat[i-1][0]->rotation,DOWN)];
                if(colA==colB){
                    cnt++;
                }
            for(j=1;j<n;j++){
                //horizontal
                colA=PIECE_COLOUR(mat[i][j],LEFT);
                //colA=squares[mat[i][j]->square_index]->colour[ROTATE(mat[i][j]->rotation,LEFT)];
                colB=PIECE_COLOUR(mat[i][j-1],RIGHT);
                //colB=squares[mat[i][j-1]->square_index]->colour[ROTATE(mat[i][j-1]->rotation,RIGHT)];
                if(colA==colB){
                    cnt++;
                }
                //vertical
                colA=PIECE_COLOUR(mat[i][j],UP);
                //colA=squares[mat[i][j]->square_index]->colour[ROTATE(mat[i][j]->rotation,UP)];
                colB=PIECE_COLOUR(mat[i-1][j],DOWN);
                //colB=squares[mat[i-1][j]->square_index]->colour[ROTATE(mat[i-1][j]->rotation,DOWN)];
                if(colA==colB){
                    cnt++;
                }
            }
        }
    }
return(cnt);
}
Пример #4
0
void move_undo(int move, const undo_t * undo) {

   int me;
   int from, to;
   int piece,pos;

   
   ASSERT(move_is_ok(move));
   ASSERT(undo!=NULL);

   // init

   me = undo->turn;

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = Square[to];
   pos=piece & 31;


   ASSERT(COLOUR_IS(piece,me));
   
   Square[from]=piece;
   Piece[pos]=from;

   BitRanks[from>>4] ^= g_BitRankMask[from];
   BitFiles[from & 0xf]^= g_BitFileMask[from];
 
  
   if(undo->capture)//吃子更新
   {
	   Square[to]=undo->capture_piece;
	   Piece[undo->capture_piece & 31]=to;
       
	   Piece_size[PIECE_COLOUR(undo->capture_piece)]++;
	   Number[PieceTo32[undo->capture_piece & 31]]++;
        
   }else
   { 
	   Square[to]=Empty;

	   BitRanks[to>>4] ^= g_BitRankMask[to];
	   BitFiles[to&0xf]^= g_BitFileMask[to];
   }
   
   Turn = undo->turn;

   Opening = undo->opening;
   Endgame = undo->endgame;

   Key = undo->key;
   Lock = undo->lock;

   Sp--;
}
Пример #5
0
int move_matches_diff_inner(solution_t* s, move_t* move) {
     int tot;
     piece_t *p1, *p2, *p1_old, *p2_old;
     dir d;

     p1=piece_new(move->square_index1,move->rotation1);
     p2=piece_new(move->square_index2,move->rotation2);

     //rotation of the same piece
     //p1==p2 if it is the same piece
     if (move->pos1==move->pos2) {
          tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1)
               + solution_piece_matches_inner(s, p1, move->pos1);
     } else {
          //non adjacent swap
          //old pieces matches are subtracted
          tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos1) - solution_piece_matches_inner(s,NULL,move->pos2);
          //new pieces matches are added
          tot+=solution_piece_matches_inner(s, p1, move->pos1) + solution_piece_matches_inner(s,p2, move->pos2);

          d=is_adjacent(move->pos2,move->pos1,s->n); //swap_pos->other_pos
          //adjacent swap
          if (d!=NONE) {
               p1_old=s->mat[(move->pos2)/(s->n)][(move->pos2)%(s->n)];
               p2_old=s->mat[(move->pos1)/(s->n)][(move->pos1)%(s->n)];
               if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
                   //the match has been subtracted twice
                   tot++;
               //to avoid counting matches with the previous version of themselves
               if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
                    tot--;
               if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) )
                    tot--;
               //to count the match between the new versions
               if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) )
                    tot++;
          }
     }
     piece_free(p1);
     piece_free(p2);
     return(tot);
}
Пример #6
0
int move_matches_diff_inner(solution_t* s, move_t* move) {
     int tot;
     piece_t *p1, *p2, *p1_old, *p2_old;
     dir d;

     p1=s->mat[1][1];
     p2=piece_new(move->square_index,move->rotation);

     //rotation of the first piece
     if (s->n+1==move->pos) {
          tot=s->matches - solution_piece_matches_inner(s,NULL,s->n+1) + solution_piece_matches_inner(s, p2, s->n+1);
     } else {
          //non adjacent swap
          //old pieces matches are subtracted
          tot=s->matches - solution_piece_matches_inner(s,NULL,move->pos) - solution_piece_matches_inner(s,NULL,s->n+1);
          //new pieces matches are added
          tot+=solution_piece_matches_inner(s, p2, s->n+1) + solution_piece_matches_inner(s,p1, move->pos);

          d=is_adjacent(s->n+1,move->pos,s->n);
          //adjacent swap
          if (d!=NONE) {
               p1_old=p1;
               p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)];
               if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
                   //the match has been subtracted twice
                   tot++;
               //to avoid counting matches with the previous version of themselves
               if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
                    tot--;
               if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) )
                    tot--;
               //to count the match between the new versions
               if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) )
                    tot++;
          }
     }
     //piece_free(p1); //placeholder for enhanced versions
     piece_free(p2);
     return(tot);
}
Пример #7
0
int move_matches_diff_edge(solution_t* s, move_t* move) {
     int tot;
     piece_t *p1, *p2, *p1_old, *p2_old;
     dir d;

     d=direction_edge(move->pos,s->n);
     p1=piece_new(s->mat[0][1]->square_index,square_rotate_edge(squares[s->mat[0][1]->square_index],d));
     p2=piece_new(move->square_index,move->rotation);


     //non adjacent swap
     //old pieces matches are subtracted
     tot=s->matches - solution_piece_matches_edge(s,NULL,move->pos) - solution_piece_matches_edge(s,NULL,1);
     //new pieces matches are added
     tot+=solution_piece_matches_edge(s,p2,1) + solution_piece_matches_edge(s,p1,move->pos);

     d=is_adjacent(1,move->pos,s->n);
     //adjacent swap
     if (d!=NONE) {
          p1_old=s->mat[0][1];
          p2_old=s->mat[(move->pos)/(s->n)][(move->pos)%(s->n)];
          if ( PIECE_COLOUR(p1_old,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
              //the match has been subtracted twice
              tot++;
          //to avoid counting matches with the previous version of themselves
          if ( PIECE_COLOUR(p2,d)==PIECE_COLOUR(p2_old,OPPOSITE(d)) )
               tot--;
          if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p1_old,d) )
               tot--;
          //to count the match between the new versions
          if ( PIECE_COLOUR(p1,OPPOSITE(d))==PIECE_COLOUR(p2,d) )
               tot++;
     }
     piece_free(p1);
     piece_free(p2);
     return(tot);
}
Пример #8
0
int see_move(int move, const board_t * board) {

   int att, def;
   int from, to;
   alists_t alists[1];
   int value, piece_value;
   int piece, capture;
   alist_t * alist;
   int pos;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   // init

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   // move the piece

   piece_value = 0;

   piece = board->square[from];
   ASSERT(piece_is_ok(piece));

   att = PIECE_COLOUR(piece);
   def = COLOUR_OPP(att);

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      ASSERT(PIECE_IS_PAWN(piece));
      piece = move_promote(move);
      ASSERT(piece_is_ok(piece));
      ASSERT(COLOUR_IS(piece,att));
   }

   piece_value += VALUE_PIECE(piece);

   // clear attacker lists

   ALIST_CLEAR(alists->alist[Black]);
   ALIST_CLEAR(alists->alist[White]);

   // find hidden attackers

   alists_hidden(alists,board,from,to);

   // capture the piece

   value = 0;

   capture = board->square[to];

   if (capture != Empty) {

      ASSERT(piece_is_ok(capture));
      ASSERT(COLOUR_IS(capture,def));

      value += VALUE_PIECE(capture);
   }

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      value += VALUE_PIECE(piece) - ValuePawn;
   }

   // en-passant

   if (MOVE_IS_EN_PASSANT(move)) {
      ASSERT(value==0);
      ASSERT(PIECE_IS_PAWN(board->square[SQUARE_EP_DUAL(to)]));
      value += ValuePawn;
      alists_hidden(alists,board,SQUARE_EP_DUAL(to),to);
   }

   // build defender list

   alist = alists->alist[def];

   alist_build(alist,board,to,def);
   if (alist->size == 0) return value; // no defender => stop SEE

   // build attacker list

   alist = alists->alist[att];

   alist_build(alist,board,to,att);

   // remove the moved piece (if it's an attacker)

   for (pos = 0; pos < alist->size && alist->square[pos] != from; pos++)
      ;

   if (pos < alist->size) alist_remove(alist,pos);

   // SEE search

   value -= see_rec(alists,board,def,to,piece_value);

   return value;
}
Пример #9
0
bool board_is_ok(const board_t * board) {

   int sq, piece, colour;
   int size, pos;

   if (board == NULL) return false;

   // optional heavy DEBUG mode

   if (!UseSlowDebug) return true;

   // squares

   for (sq = 0; sq < SquareNb; sq++) {

      piece = board->square[sq];
      pos = board->pos[sq];

      if (SQUARE_IS_OK(sq)) {

         // inside square

         if (piece == Empty) {

            if (pos != -1) return false;

         } else {

            if (!piece_is_ok(piece)) return false;

            if (!PIECE_IS_PAWN(piece)) {

               colour = PIECE_COLOUR(piece);
               if (pos < 0 || pos >= board->piece_size[colour]) return false;
               if (board->piece[colour][pos] != sq) return false;

            } else { // pawn

               if (SQUARE_IS_PROMOTE(sq)) return false;

               colour = PIECE_COLOUR(piece);
               if (pos < 0 || pos >= board->pawn_size[colour]) return false;
               if (board->pawn[colour][pos] != sq) return false;
            }
         }

      } else {

         // edge square

         if (piece != Edge) return false;
         if (pos != -1) return false;
      }
   }

   // piece lists

   for (colour = 0; colour < ColourNb; colour++) {

      // piece list

      size = board->piece_size[colour];
      if (size < 1 || size > 16) return false;

      for (pos = 0; pos < size; pos++) {

         sq = board->piece[colour][pos];
         if (!SQUARE_IS_OK(sq)) return false;

         if (board->pos[sq] != pos) return false;

         piece = board->square[sq];
         if (!COLOUR_IS(piece,colour)) return false;
         if (pos == 0 && !PIECE_IS_KING(piece)) return false;
         if (pos != 0 && PIECE_IS_KING(piece)) return false;

         if (pos != 0 && PIECE_ORDER(piece) > PIECE_ORDER(board->square[board->piece[colour][pos-1]])) {
            return false;
         }
      }

      sq = board->piece[colour][size];
      if (sq != SquareNone) return false;

      // pawn list

      size = board->pawn_size[colour];
      if (size < 0 || size > 8) return false;

      for (pos = 0; pos < size; pos++) {

         sq = board->pawn[colour][pos];
         if (!SQUARE_IS_OK(sq)) return false;
         if (SQUARE_IS_PROMOTE(sq)) return false;

         if (board->pos[sq] != pos) return false;

         piece = board->square[sq];
         if (!COLOUR_IS(piece,colour)) return false;
         if (!PIECE_IS_PAWN(piece)) return false;
      }

      sq = board->pawn[colour][size];
      if (sq != SquareNone) return false;

      // piece total

      if (board->piece_size[colour] + board->pawn_size[colour] > 16) return false;
   }

   // material

   if (board->piece_nb != board->piece_size[White] + board->pawn_size[White]
                        + board->piece_size[Black] + board->pawn_size[Black]) {
      return false;
   }

   if (board->number[WhitePawn12] != board->pawn_size[White]) return false;
   if (board->number[BlackPawn12] != board->pawn_size[Black]) return false;
   if (board->number[WhiteKing12] != 1) return false;
   if (board->number[BlackKing12] != 1) return false;

   // misc

   if (!COLOUR_IS_OK(board->turn)) return false;

   if (board->ply_nb < 0) return false;
   if (board->sp < board->ply_nb) return false;

   if (board->cap_sq != SquareNone && !SQUARE_IS_OK(board->cap_sq)) return false;

   if (board->opening != board_opening(board)) return false;
   if (board->endgame != board_endgame(board)) return false;
   if (board->key != hash_key(board)) return false;
   if (board->pawn_key != hash_pawn_key(board)) return false;
   if (board->material_key != hash_material_key(board)) return false;

   return true;
}
Пример #10
0
static void square_move(board_t * board, int from, int to, int piece, bool update) {

   int colour;
   int pos;
   int from_64, to_64;
   int piece_12;
   int piece_index;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(to));
   ASSERT(piece_is_ok(piece));
   ASSERT(update==true||update==false);

   // init

   colour = PIECE_COLOUR(piece);

   pos = board->pos[from];
   ASSERT(pos>=0);

   // from

   ASSERT(board->square[from]==piece);
   board->square[from] = Empty;

   ASSERT(board->pos[from]==pos);
   board->pos[from] = -1; // not needed

   // to

   ASSERT(board->square[to]==Empty);
   board->square[to] = piece;

   ASSERT(board->pos[to]==-1);
   board->pos[to] = pos;

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      ASSERT(board->piece[colour][pos]==from);
      board->piece[colour][pos] = to;

   } else {

      ASSERT(board->pawn[colour][pos]==from);
      board->pawn[colour][pos] = to;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(from)] ^= BIT(PAWN_RANK(from,colour));
      board->pawn_file[colour][SQUARE_FILE(to)]   ^= BIT(PAWN_RANK(to,colour));
   }

   // update

   if (update) {

      // init

      from_64 = SQUARE_TO_64(from);
      to_64 = SQUARE_TO_64(to);
      piece_12 = PIECE_TO_12(piece);

      // PST

      board->opening += PST(piece_12,to_64,Opening) - PST(piece_12,from_64,Opening);
      board->endgame += PST(piece_12,to_64,Endgame) - PST(piece_12,from_64,Endgame);

      // hash key

      piece_index = RandomPiece + (piece_12^1) * 64; // HACK: ^1 for PolyGlot book

      hash_xor = RANDOM_64(piece_index+to_64) ^ RANDOM_64(piece_index+from_64);

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;
   }
}
Пример #11
0
static void square_set(board_t * board, int square, int piece, int pos, bool update) {

   int piece_12, colour;
   int sq;
   int i, size;
   int sq_64;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(pos>=0);
   ASSERT(update==true||update==false);

   // init

   piece_12 = PIECE_TO_12(piece);
   colour = PIECE_COLOUR(piece);

   // square

   ASSERT(board->square[square]==Empty);
   board->square[square] = piece;

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      // init

      size = board->piece_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->piece[colour][size] = SquareNone;
      board->piece_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->piece[colour][i-1];

         board->piece[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

      board->piece[colour][pos] = square;

      ASSERT(board->pos[square]==-1);
      board->pos[square] = pos;

   } else {

      // init

      size = board->pawn_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->pawn[colour][size] = SquareNone;
      board->pawn_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->pawn[colour][i-1];

         board->pawn[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

      board->pawn[colour][pos] = square;

      ASSERT(board->pos[square]==-1);
      board->pos[square] = pos;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square,colour));
   }

   // material

   ASSERT(board->piece_nb<32);
   board->piece_nb++;;

   ASSERT(board->number[piece_12]<9);
   board->number[piece_12]++;

   // update

   if (update) {

      // init

      sq_64 = SQUARE_TO_64(square);

      // PST

      board->opening += PST(piece_12,sq_64,Opening);
      board->endgame += PST(piece_12,sq_64,Endgame);

      // hash key

      hash_xor = RANDOM_64(RandomPiece+(piece_12^1)*64+sq_64); // HACK: ^1 for PolyGlot book

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;

      // material key

      board->material_key ^= RANDOM_64(piece_12*16+(board->number[piece_12]-1));
   }
}
Пример #12
0
static void square_clear(board_t * board, int square, int piece, bool update) {

   int pos, piece_12, colour;
   int sq;
   int i, size;
   int sq_64;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(update==true||update==false);

   // init

   pos = board->pos[square];
   ASSERT(pos>=0);

   piece_12 = PIECE_TO_12(piece);
   colour = PIECE_COLOUR(piece);

   // square

   ASSERT(board->square[square]==piece);
   board->square[square] = Empty;

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      // init

      size = board->piece_size[colour];
      ASSERT(size>=1);

      // stable swap

      ASSERT(pos>=0&&pos<size);

      ASSERT(board->pos[square]==pos);
      board->pos[square] = -1;

      for (i = pos; i < size-1; i++) {

         sq = board->piece[colour][i+1];

         board->piece[colour][i] = sq;

         ASSERT(board->pos[sq]==i+1);
         board->pos[sq] = i;
      }

      // size

      size--;

      board->piece[colour][size] = SquareNone;
      board->piece_size[colour] = size;

   } else {

      // init

      size = board->pawn_size[colour];
      ASSERT(size>=1);

      // stable swap

      ASSERT(pos>=0&&pos<size);

      ASSERT(board->pos[square]==pos);
      board->pos[square] = -1;

      for (i = pos; i < size-1; i++) {

         sq = board->pawn[colour][i+1];

         board->pawn[colour][i] = sq;

         ASSERT(board->pos[sq]==i+1);
         board->pos[sq] = i;
      }

      // size

      size--;

      board->pawn[colour][size] = SquareNone;
      board->pawn_size[colour] = size;

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square,colour));
   }

   // material

   ASSERT(board->piece_nb>0);
   board->piece_nb--;

   ASSERT(board->number[piece_12]>0);
   board->number[piece_12]--;

   board->piece_material[colour] -= VALUE_PIECE(piece);  // Thomas 
   
   // update

   if (update) {

      // init

      sq_64 = SQUARE_TO_64(square);

      // PST

      board->opening -= PST(piece_12,sq_64,Opening);
      board->endgame -= PST(piece_12,sq_64,Endgame);

      // hash key

      hash_xor = RANDOM_64(RandomPiece+(piece_12^1)*64+sq_64); // HACK: ^1 for PolyGlot book

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;

      // material key

      board->material_key ^= RANDOM_64(piece_12*16+board->number[piece_12]);
   }
}
Пример #13
0
void move_do(int move, undo_t * undo) {

   int me, opp;
   int from, to;
   int piece, capture,pos;
   int piece_key;

   
   ASSERT(undo!=NULL);

   //ASSERT(board_is_legal(board));

   // initialise undo

   undo->capture = false;
   undo->turn = Turn;
   undo->opening = Opening;
   undo->endgame = Endgame;
   undo->key = Key;
   undo->lock = Lock;

   // init

   me = Turn;
   opp =COLOUR_OPP(me);

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   piece = Square[from];
   if(piece==0)
	   printf("Error move piece %x\n ",move);
   pos=piece & 31;
   // update key stack
   Stack[Sp++] = Lock;

   // update turn

   Turn = opp;
   Key ^= g_ZobristKeyPlayer;
   Lock ^= g_ZobristLockPlayer;

   piece_key=PieceToKey32[pos];


   if ((capture=Square[to]) != Empty) {

      undo->capture = true;
      undo->capture_square = to;
      undo->capture_piece = capture;
      
	  //吃掉的子进行清除
	  Piece[capture & 31]=0;
	  Piece_size[PIECE_COLOUR(capture)]--;

	  Number[PieceTo32[capture & 31]]--;

	  Key ^= g_ZobristKeyTable[piece_key][to];
      Lock ^= g_ZobristLockTable[piece_key][to];

   }else
   {
       //没有吃子,只更新位行、位列
	   BitRanks[to>>4] ^= g_BitRankMask[to];
       BitFiles[to & 0xf] ^= g_BitFileMask[to];
   }

   Square[from] = Empty;

   Square[to] = piece;
   
   Piece[pos] = to;

   BitRanks[from>>4] ^= g_BitRankMask[from];
   BitFiles[from & 0xf] ^= g_BitFileMask[from];

   if (piece_key < 5) {
        Opening +=g_PST[piece_key][to] - g_PST[piece_key][from];
 	    Endgame +=g_PST[piece_key+5][to] - g_PST[piece_key+5][from];
    } else {
	    Opening -=g_PST[piece_key-5][254 - to] - g_PST[piece_key-5][254 - from];
	    Endgame -=g_PST[piece_key][254 - to]   - g_PST[piece_key][254 - from];
    }
 
   Key ^= g_ZobristKeyTable[piece_key][to] ^ g_ZobristKeyTable[piece_key][from];
   Lock ^= g_ZobristLockTable[piece_key][to] ^ g_ZobristLockTable[piece_key][from];
   
   // move the piece
}
Пример #14
0
int solution_piece_matches_corner(solution_t* s, piece_t* p, int pos) {
     int r,c,m=0;
     piece_t*** mat;
     int colA,colB;

     r=pos/s->n;
     c=pos%s->n;
     mat=s->mat;
     if (p==NULL) {
          p=mat[r][c];
     }
     if (pos==0) {
               //UPPER_LEFT;
               colA=PIECE_COLOUR(p,DOWN);
               //colA=squares[mat[0][0]->square_index]->colour[ROTATE(mat[0][0]->rotation,DOWN)];
               colB=PIECE_COLOUR(mat[1][0],UP);
               //colB=squares[mat[1][0]->square_index]->colour[ROTATE(mat[1][0]->rotation,UP)];
               if (colA==colB) m++;
               colA=PIECE_COLOUR(p,RIGHT);
               //colA=squares[mat[0][0]->square_index]->colour[ROTATE(mat[0][0]->rotation,RIGHT)];
               colB=PIECE_COLOUR(mat[0][1],LEFT);
               //colB=squares[mat[0][1]->square_index]->colour[ROTATE(mat[0][1]->rotation,LEFT)];
               if (colA==colB) m++;
     } else if(pos==s->n-1) {
               //UPPER_RIGHT;
               colA=PIECE_COLOUR(p,DOWN);
               //colA=squares[mat[0][s->n-1]->square_index]->colour[ROTATE(mat[0][s->n-1]->rotation,DOWN)];
               colB=PIECE_COLOUR(mat[1][s->n-1],UP);
               //colB=squares[mat[1][s->n-1]->square_index]->colour[ROTATE(mat[1][s->n-1]->rotation,UP)];
               if (colA==colB) m++;
               colA=PIECE_COLOUR(p,LEFT);
               //colA=squares[mat[0][s->n-1]->square_index]->colour[ROTATE(mat[0][s->n-1]->rotation,LEFT)];
               colB=PIECE_COLOUR(mat[0][s->n-2],RIGHT);
               //colB=squares[mat[0][s->n-2]->square_index]->colour[ROTATE(mat[0][s->n-2]->rotation,RIGHT)];
               if (colA==colB) m++;
     } else  if( pos==(s->n-1)*(s->n) ) {
               //LOWER_LEFT;
               colA=PIECE_COLOUR(p,UP);
               //colA=squares[mat[s->n-1][0]->square_index]->colour[ROTATE(mat[s->n-1][0]->rotation,UP)];
               colB=PIECE_COLOUR(mat[s->n-2][0],DOWN);
               //colB=squares[mat[s->n-2][0]->square_index]->colour[ROTATE(mat[s->n-2][0]->rotation,DOWN)];
               if (colA==colB) m++;
               colA=PIECE_COLOUR(p,RIGHT);
               //colA=squares[mat[s->n-1][0]->square_index]->colour[ROTATE(mat[s->n-1][0]->rotation,RIGHT)];
               colB=PIECE_COLOUR(mat[s->n-1][1],LEFT);
               //colB=squares[mat[s->n-1][1]->square_index]->colour[ROTATE(mat[s->n-1][1]->rotation,LEFT)];
               if (colA==colB) m++;
     } else {
               //LOWER_RIGHT;
               colA=PIECE_COLOUR(p,UP);
               //colA=squares[mat[s->n-1][s->n-1]->square_index]->colour[ROTATE(mat[s->n-1][s->n-1]->rotation,UP)];
               colB=PIECE_COLOUR(mat[s->n-2][s->n-1],DOWN);
               //colB=squares[mat[spiece_colour->n-2][s->n-1]->square_index]->colour[ROTATE(mat[s->n-2][s->n-1]->rotation,DOWN)];
               if (colA==colB) m++;
               colA=PIECE_COLOUR(p,LEFT);
               //colA=squares[mat[s->n-1][s->n-1]->square_index]->colour[ROTATE(mat[s->n-1][s->n-1]->rotation,LEFT)];
               colB=PIECE_COLOUR(mat[s->n-1][s->n-2],RIGHT);
               //colB=squares[mat[s->n-1][s->n-2]->square_index]->colour[ROTATE(mat[s->n-1][s->n-2]->rotation,RIGHT)];
               if (colA==colB) m++;
     }
     return (m);
}