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); }
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); } } }
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); }
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--; }
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); }
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); }
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); }
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; }
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; }
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; } }
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)); } }
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]); } }
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 }
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); }