Apres avoir lurké deux fonctions magiques en hexa pour calculer les distances et directions entre deux cases je viens de pondre ca :
[cpp]Pieces is_attacked_by(Square s, Color c) {
Pieces attackers;
Pieces opponent_pieces = board.get_pieces(c);
for (Piece p = opponent_pieces.first(); p != opponent_pieces.last(); ++p) {
Square position = p->get_position();
MoveDirection direction = board.get_direction(position, s);
int distance = board.get_distance(p->get_position(), s);
switch (direction) { // Si la case s est atteignable depuis la position de la piece
case UP:
case DOWN:
case LEFT:
case RIGHT:
if (p->get_type() == QUEEN || p->get_type() == ROOK) {
if (distance == 1) {
attackers.add(p);
break;
}
else {
// C'est un slider, il faut boucler
// pour voir si qlq chose ne s'interpose pas
while (position != s) {
position = Square(position + direction);
if (board.get_ptr_piece()) {
break;
}
}
// Si rien ne s'est interposé on l'ajoute
attackers.add(p);
break;
}
}
break;
case UP_LEFT:
case UP_RIGHT:
if (distance == 1 && c == WHITE && p->get_type() == PAWN) {
attackers.add(p);
break;
}
case DOWN_RIGHT:
case DOWN_LEFT:
if (distance == 1 && c == BLACK && p->get_type() == PAWN) {
attackers.add(p);
break;
}
else if (p->get_type() == QUEEN || p->get_type() == BISHOP) {
if (distance == 1) {
attackers.add(p);
break;
}
else {
// C'est un slider, il faut boucler
// pour voir si qlq chose ne s'interpose pas
while (position != s) {
position = Square(position + direction);
if (board.get_ptr_piece()) {
break;
}
}
// Si rien ne s'est interposé on l'ajoute
attackers.add(p);
break;
}
}
break;
case UP_UP_RIGHT:
case RIGHT_UP_RIGHT:
case RIGHT_DOWN_RIGHT:
case DOWN_DOWN_RIGHT:
case DOWN_DOWN_LEFT:
case LEFT_DOWN_LEFT:
case LEFT_UP_LEFT:
case UP_UP_LEFT:
if (distance == 2 p->get_type() == BISHOP) {
attackers.add(p);
break;
}
break;
}
return attackers;
}[/cpp]
Destiné à avoir la liste des pieces d'une couleur attaquant une case... Utile par exemple pour savoir si le roi est échec mais aussi pour bien plus de chose !
En gros je pars d'une liste des pieces adverses et je regarde si elles peuvent attaquer la case.
Avant je partais de la case et suivait l'échiquier pour voir qui pouvait m'attaquer... Normalement la version que je viens de pondre devrait etre plus perf... A voir. En tout cas c'est plus simple je trouve mm s'il manque un ou deux trucs. Ca remplace ca :
[cpp]Pieces is_attacked_by(Board& b, Square s, Color c) {
Pieces pieces;
Piece* ptr_piece = 0;
Square to;
// Search for knights attacking s
for (int i = 0; i < NB_KNIGHT_MOVES; ++i) {
to = Square(s + KNIGHT_MOVES);
if (!b.is_off_the_board(to)) {
ptr_piece = b.get_ptr_piece(to);
if (ptr_piece && ptr_piece->get_type() == KNIGHT && ptr_piece->get_color() == c) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
}
}
// Search for others pieces attackings s
for (int i = 0; i < NB_QUEEN_MOVES; ++i) {
MoveOrientation offset = QUEEN_MOVES;
to = Square(s + offset);
if (!b.is_off_the_board(to)) {
ptr_piece = b.get_ptr_piece(to);
if (ptr_piece && ptr_piece->get_color() == c) {
// Pawn's attack
if (ptr_piece->get_type() == PAWN && (
(c == BLACK && (offset == UP_LEFT || offset == UP_RIGHT)) ||
(c == WHITE && (offset == DOWN_LEFT || offset == DOWN_RIGHT))
)) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
// Rook's attack
else if (ptr_piece->get_type() == ROOK && (
b.get_rank(s) == b.get_rank(to) || b.get_file(s) == b.get_file(to)
)) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
// Bishop's attack
else if (ptr_piece->get_type() == BISHOP && (
b.get_rank(s) != b.get_rank(to) && b.get_file(s) != b.get_file(to)
)) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
// Queen's or king's attack
else if (ptr_piece->get_type() == QUEEN || ptr_piece->get_type() == KING) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
}
else {
while (!ptr_piece && !b.is_off_the_board(Square(to + offset))) {
to = Square(to + offset);
ptr_piece = b.get_ptr_piece(to);
}
ptr_piece = b.get_ptr_piece(to);
if (ptr_piece && ptr_piece->get_color() == c) {
//TODO Weird stuff here, piece's position should be Square to, but sometime it's not.
if (ptr_piece->get_position() != to) {
cout << *ptr_piece << " " << hex << ptr_piece->get_position() << " " << hex << to << endl;
}
// Rook's attack
if (ptr_piece->get_type() == ROOK && (
b.get_rank(s) == b.get_rank(to) || b.get_file(s) == b.get_file(to)
)) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
// Bishop's attack
else if (ptr_piece->get_type() == BISHOP && (
b.get_rank(s) != b.get_rank(to) && b.get_file(s) != b.get_file(to)
)) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
// Queen's attack
else if (ptr_piece->get_type() == QUEEN) {
//cout << *ptr_piece << " in " << hex << to << " is attacking " << hex << s << "! ";
pieces.insert(*ptr_piece, BACK);
}
}
}
}
}
return pieces;
}[/cpp]