549aafa90b46c8290c80332af9e644edf0f6ee52
[stockfish] / src / pawns.h
1 /*
2   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3   Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
4   Copyright (C) 2008-2010 Marco Costalba, Joona Kiiski, Tord Romstad
5
6   Stockfish is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   Stockfish is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #if !defined(PAWNS_H_INCLUDED)
21 #define PAWNS_H_INCLUDED
22
23 #include "bitboard.h"
24 #include "position.h"
25 #include "tt.h"
26 #include "types.h"
27
28 const int PawnTableSize = 16384;
29
30 /// PawnInfo is a class which contains various information about a pawn
31 /// structure. Currently, it only includes a middle game and an end game
32 /// pawn structure evaluation, and a bitboard of passed pawns. We may want
33 /// to add further information in the future. A lookup to the pawn hash table
34 /// (performed by calling the get_pawn_info method in a PawnInfoTable object)
35 /// returns a pointer to a PawnInfo object.
36 class PawnInfo {
37
38   friend class PawnInfoTable;
39
40 public:
41   Score pawns_value() const;
42   Bitboard pawn_attacks(Color c) const;
43   Bitboard passed_pawns(Color c) const;
44   int file_is_half_open(Color c, File f) const;
45   int has_open_file_to_left(Color c, File f) const;
46   int has_open_file_to_right(Color c, File f) const;
47
48   template<Color Us>
49   Score king_shelter(const Position& pos, Square ksq);
50
51 private:
52   template<Color Us>
53   Score updateShelter(const Position& pos, Square ksq);
54
55   Key key;
56   Bitboard passedPawns[2];
57   Bitboard pawnAttacks[2];
58   Square kingSquares[2];
59   Score value;
60   int halfOpenFiles[2];
61   Score kingShelters[2];
62 };
63
64
65 /// The PawnInfoTable class represents a pawn hash table. The most important
66 /// method is get_pawn_info, which returns a pointer to a PawnInfo object.
67
68 class PawnInfoTable : public SimpleHash<PawnInfo, PawnTableSize> {
69
70   enum SideType { KingSide, QueenSide };
71
72 public:
73   PawnInfo* get_pawn_info(const Position& pos) const;
74   void prefetch(Key key) const;
75
76 private:
77   template<Color Us>
78   Score evaluate_pawns(const Position& pos, Bitboard ourPawns, Bitboard theirPawns, PawnInfo* pi) const;
79 };
80
81 inline Square pawn_push(Color c) {
82   return c == WHITE ? DELTA_N : DELTA_S;
83 }
84
85 inline void PawnInfoTable::prefetch(Key key) const {
86
87     unsigned index = unsigned(key & (PawnTableSize - 1));
88     PawnInfo* pi = entries + index;
89     ::prefetch((char*) pi);
90 }
91
92 inline Score PawnInfo::pawns_value() const {
93   return value;
94 }
95
96 inline Bitboard PawnInfo::pawn_attacks(Color c) const {
97   return pawnAttacks[c];
98 }
99
100 inline Bitboard PawnInfo::passed_pawns(Color c) const {
101   return passedPawns[c];
102 }
103
104 inline int PawnInfo::file_is_half_open(Color c, File f) const {
105   return (halfOpenFiles[c] & (1 << int(f)));
106 }
107
108 inline int PawnInfo::has_open_file_to_left(Color c, File f) const {
109   return halfOpenFiles[c] & ((1 << int(f)) - 1);
110 }
111
112 inline int PawnInfo::has_open_file_to_right(Color c, File f) const {
113   return halfOpenFiles[c] & ~((1 << int(f+1)) - 1);
114 }
115
116 /// PawnInfo::updateShelter() calculates and caches king shelter. It is called
117 /// only when king square changes, about 20% of total king_shelter() calls.
118 template<Color Us>
119 Score PawnInfo::updateShelter(const Position& pos, Square ksq) {
120
121   const int Shift = (Us == WHITE ? 8 : -8);
122
123   Bitboard pawns;
124   int r, shelter = 0;
125
126   if (relative_rank(Us, ksq) <= RANK_4)
127   {
128       pawns = pos.pieces(PAWN, Us) & this_and_neighboring_files_bb(ksq);
129       r = square_rank(ksq) * 8;
130       for (int i = 1; i < 4; i++)
131       {
132           r += Shift;
133           shelter += BitCount8Bit[(pawns >> r) & 0xFF] * (128 >> i);
134       }
135   }
136   kingSquares[Us] = ksq;
137   kingShelters[Us] = make_score(shelter, 0);
138   return kingShelters[Us];
139 }
140
141 template<Color Us>
142 inline Score PawnInfo::king_shelter(const Position& pos, Square ksq) {
143   return kingSquares[Us] == ksq ? kingShelters[Us] : updateShelter<Us>(pos, ksq);
144 }
145
146 #endif // !defined(PAWNS_H_INCLUDED)