Merge branch 'release-2.1.0'
[purplehaze.git] / src / attack.cpp
blob874441fd0b4fbdc9a443ead19eab8b892304ed29
1 /* Copyright (C) 2007-2012 Vincent Ollivier
3 * Purple Haze is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * Purple Haze is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <cassert>
19 #include "game.h"
22 * Return true if the square s is attacked by one of the c color's pieces.
24 bool Board::is_attacked_by(const Color c, const Square s,
25 const Pieces& pieces) const
27 for (const PieceType& t : NOT_PAWN_TYPES) {
28 for (int i = 0, n = pieces.count(c, t); i < n; ++i) {
29 const Square from = pieces.position(c, t, i);
30 if (!can_attack(t, from, s)) {
31 continue;
33 if (t == KNIGHT || t == KING) {
34 return true;
36 const Direction d = direction_to(from, s);
37 Square to = static_cast<Square>(from + d);
38 while (to != s && is_empty(to)) {
39 to = static_cast<Square>(to + d);
41 if (to == s) {
42 return true;
47 // Specific code for pawns
48 for (const Direction &d : PAWN_CAPTURE_DIRS[!c]) {
49 const Square from = static_cast<Square>(s + d);
50 if (board[from].is(c, PAWN)) {
51 return true;
55 return false;
59 * Return 'true' if a piece 'p' can do a capture or a quiet move from
60 * square 'from' to square 'to' on the board. This function does not
61 * say if the move is legal.
63 bool Board::can_go(const Piece p, const Square from, const Square to) const
65 const Color c = p.color();
67 // A piece cannot capture another piece of the same color
68 if (!is_empty(to) && board[to].is(c)) {
69 return false;
72 Direction d;
73 Square s;
74 const PieceType t = p.type();
75 switch (t) {
76 case PAWN:
77 d = PAWN_PUSH_DIRS[c];
78 s = static_cast<Square>(from + d);
79 if (!is_empty(to)) { // Capture
80 if (to == static_cast<Square>(s + LEFT)) {
81 return true;
83 if (to == static_cast<Square>(s + RIGHT)) {
84 return true;
86 } else { // Pawn push (and double push)
87 if (to == s) {
88 return true;
90 if (to == static_cast<Square>(s + d)) {
91 if (is_empty(s) && is_pawn_begin(c, from)) {
92 return true;
96 break;
97 default:
98 if (!can_attack(t, from, to)) {
99 return false;
101 if (t == KNIGHT || t == KING) {
102 return true;
104 d = direction_to(from, to);
105 s = static_cast<Square>(from + d);
106 while (s != to && is_empty(s)) { // Search for a blocker
107 s = static_cast<Square>(s + d);
108 assert(!is_out(s));
110 if (s == to) {
111 return true;
113 break;
115 return false;