Add pawn ending restriction on null move pruning
[purplehaze.git] / src / attack.cpp
blob84bc430a0999ec6a6aaddc12bfc1f5de67e95ab2
1 /* Copyright (C) 2007-2011 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 <assert.h>
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(Color c, Square s, const Pieces& pieces) const
26 for (const PieceType& t : NOT_PAWN_TYPES) {
27 int n = pieces.count(c, t);
28 for (int i = 0; i < n; ++i) {
29 Square from = pieces.get_position(c, t, i);
30 if (!can_attack(t, from, s)) continue;
31 if (t == KNIGHT || t == KING) return true;
32 Direction d = get_direction_to(from, s);
33 Square to = Square(from + d);
34 while (to != s && is_empty(to)) {
35 to = Square(to + d);
37 if (to == s) return true;
41 // Specific code for pawns
42 for (int i = 0; i < 2; ++i) {
43 Square from = Square(s + PAWN_CAPTURE_DIRS[!c][i]);
44 if (get_piece(from).get_type() == PAWN &&
45 get_piece(from).get_color() == c) {
46 return true;
50 return false;
54 * Return true if a piece p can do a capture or a quiet move from square from
55 * to square to on the board. This method does not say if the move is a legal
56 * one.
58 bool Board::can_go(Piece p, Square from, Square to) const
60 PieceType t = p.get_type();
61 Color c = p.get_color();
62 Direction d = get_direction_to(from, to);
64 // A piece cannot capture another piece of the same color
65 if (!is_empty(to) && get_piece(to).get_color() == c) return false;
67 Direction push_dir;
68 Square s;
69 switch (t) {
70 case PAWN:
71 push_dir = (c == WHITE ? UP : DOWN);
72 if (!is_empty(to)) { // Capture
73 if (to == Square(from + push_dir + LEFT)) return true;
74 if (to == Square(from + push_dir + RIGHT)) return true;
75 } else { // Pawn push (and double push)
76 if (to == Square(from + push_dir)) return true;
77 if (to == Square(from + 2 * push_dir) &&
78 is_empty(Square(from + push_dir)) &&
79 is_pawn_begin(c, from)) return true;
81 break;
82 default:
83 if (!can_attack(t, from, to)) return false;
84 if (t == KNIGHT || t == KING) return true;
85 s = Square(from + d);
86 while (s != to && is_empty(s)) { // Search for a blocker
87 s = Square(s + d);
88 assert(!is_out(s));
90 if (s == to) return true;
91 break;
93 return false;