Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 1
/*
2
    Texel - A UCI chess engine.
3
    Copyright (C) 2012-2014  Peter Ă–sterlund, peterosterlund2@gmail.com
4
 
5
    This program is free software: you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation, either version 3 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18
 
19
/*
20
 * evaluate.hpp
21
 *
22
 *  Created on: Feb 25, 2012
23
 *      Author: petero
24
 */
25
 
26
#ifndef EVALUATE_HPP_
27
#define EVALUATE_HPP_
28
 
29
#include "parameters.hpp"
30
#include "piece.hpp"
31
#include "position.hpp"
32
#include "util/alignedAlloc.hpp"
33
 
34
class EvaluateTest;
35
 
36
/** Position evaluation routines. */
37
class Evaluate {
38
    friend class EvaluateTest;
39
private:
40
    struct PawnHashData {
41
        PawnHashData();
42
        U64 key;
43
        S16 current;        // For hash replacement policy
44
        S16 score;          // Positive score means good for white
45
        S16 passedBonusW;
46
        S16 passedBonusB;
47
        U64 passedPawns;    // The most advanced passed pawns for each file
48
                            // Contains both white and black pawns
49
        U64 outPostsW;      // Possible outpost squares for white
50
        U64 outPostsB;
51
        U64 stalePawns;     // Pawns that can not be used for "pawn breaks"
52
    };
53
 
54
    struct MaterialHashData {
55
        MaterialHashData();
56
        int id;
57
        int score;
58
        S16 wPawnIPF, bPawnIPF;
59
        S16 wKnightIPF, bKnightIPF;
60
        S16 castleIPF, queenIPF;
61
        S16 wPassedPawnIPF, bPassedPawnIPF;
62
        S16 kingSafetyIPF;
63
        S16 diffColorBishopIPF;
64
        S16 wKnightOutPostIPF, bKnightOutPostIPF;
65
        U8 endGame;
66
    };
67
 
68
    struct KingSafetyHashData {
69
        KingSafetyHashData();
70
        U64 key;
71
        int score;
72
        S16 current;        // For hash replacement policy
73
    };
74
 
75
public:
76
    struct EvalHashTables {
77
        EvalHashTables();
78
        std::vector<PawnHashData> pawnHash;
79
        std::vector<MaterialHashData> materialHash;
80
        vector_aligned<KingSafetyHashData> kingSafetyHash;
81
    };
82
 
83
    /** Constructor. */
84
    Evaluate(EvalHashTables& et);
85
 
86
    static int pieceValueOrder[Piece::nPieceTypes];
87
 
88
    static const int* psTab1[Piece::nPieceTypes];
89
    static const int* psTab2[Piece::nPieceTypes];
90
 
91
    /** Get evaluation hash tables. */
92
    static std::shared_ptr<EvalHashTables> getEvalHashTables();
93
 
94
    /**
95
     * Static evaluation of a position.
96
     * @param pos The position to evaluate.
97
     * @return The evaluation score, measured in centipawns.
98
     *         Positive values are good for the side to make the next move.
99
     */
100
    int evalPos(const Position& pos);
101
    int evalPosPrint(const Position& pos);
102
 
103
    /** Compute "swindle" score corresponding to an evaluation score when
104
     * the position is a known TB draw. */
105
    static int swindleScore(int evalScore);
106
 
107
    /**
108
     * Interpolate between (x1,y1) and (x2,y2).
109
     * If x < x1, return y1, if x > x2 return y2. Otherwise, use linear interpolation.
110
     */
111
    static int interpolate(int x, int x1, int y1, int x2, int y2);
112
 
113
    static const int IPOLMAX = 1024;
114
 
115
    /** Compute v1 + (v2-v1)*k/IPOLMAX */
116
    static int interpolate(int v1, int v2, int k);
117
 
118
    static void staticInitialize();
119
    static void updateEvalParams();
120
 
121
private:
122
    template <bool print> int evalPos(const Position& pos);
123
 
124
    /** Compute score based on piece square tables. Positive values are good for white. */
125
    int pieceSquareEval(const Position& pos);
126
 
127
    /** Get material score */
128
    int materialScore(const Position& pos, bool print);
129
 
130
    /** Compute material score. */
131
    void computeMaterialScore(const Position& pos, MaterialHashData& mhd, bool print) const;
132
 
133
    /** Implement the "when ahead trade pieces, when behind trade pawns" rule. */
134
    int tradeBonus(const Position& pos, int wCorr, int bCorr) const;
135
 
136
    /** Score castling ability. */
137
    int castleBonus(const Position& pos);
138
 
139
    PawnHashData& getPawnHashEntry(std::vector<PawnHashData>& pawnHash, U64 key);
140
    int pawnBonus(const Position& pos);
141
 
142
    /** Compute set of pawns that can not participate in "pawn breaks". */
143
    static U64 computeStalePawns(const Position& pos);
144
 
145
    /** Compute pawn hash data for pos. */
146
    void computePawnHashData(const Position& pos, PawnHashData& ph);
147
 
148
    /** Compute rook bonus. Rook on open/half-open file. */
149
    int rookBonus(const Position& pos);
150
 
151
    /** Compute bishop evaluation. */
152
    int bishopEval(const Position& pos, int oldScore);
153
 
154
    /** Compute knight evaluation. */
155
    int knightEval(const Position& pos);
156
 
157
    /** Bonus for threatening opponent pieces. */
158
    int threatBonus(const Position& pos);
159
 
160
    /** Bonus for own pieces protected by pawns. */
161
    int protectBonus(const Position& pos);
162
 
163
    /** Compute king safety for both kings. */
164
    int kingSafety(const Position& pos);
165
 
166
    KingSafetyHashData& getKingSafetyHashEntry(vector_aligned<KingSafetyHashData>& ksHash, U64 key);
167
    int kingSafetyKPPart(const Position& pos);
168
 
169
    static int castleMaskFactor[256];
170
    static int knightMobScoreA[64][9];
171
    static U64 knightKingProtectPattern[64];
172
    static U64 bishopKingProtectPattern[64];
173
 
174
    std::vector<PawnHashData>& pawnHash;
175
    const PawnHashData* phd;
176
 
177
    std::vector<MaterialHashData>& materialHash;
178
    const MaterialHashData* mhd;
179
 
180
    vector_aligned<KingSafetyHashData>& kingSafetyHash;
181
 
182
     // King safety variables
183
    U64 wKingZone, bKingZone;       // Squares close to king that are worth attacking
184
    int wKingAttacks, bKingAttacks; // Number of attacks close to white/black king
185
    U64 wAttacksBB, bAttacksBB;
186
    U64 wPawnAttacks, bPawnAttacks; // Squares attacked by white/black pawns
187
};
188
 
189
 
190
inline
191
Evaluate::PawnHashData::PawnHashData()
192
    : key((U64)-1), // Non-zero to avoid collision for positions with no pawns
193
      current(0), score(0),
194
      passedBonusW(0),
195
      passedBonusB(0),
196
      passedPawns(0) {
197
}
198
 
199
inline
200
Evaluate::MaterialHashData::MaterialHashData()
201
    : id(-1), score(0) {
202
}
203
 
204
inline
205
Evaluate::KingSafetyHashData::KingSafetyHashData()
206
    : key((U64)-1), score(0), current(0) {
207
}
208
 
209
inline
210
Evaluate::EvalHashTables::EvalHashTables() {
211
    pawnHash.resize(1<<16);
212
    kingSafetyHash.resize(1 << 15);
213
    materialHash.resize(1 << 14);
214
}
215
 
216
inline int
217
Evaluate::interpolate(int x, int x1, int y1, int x2, int y2) {
218
    if (x > x2) {
219
        return y2;
220
    } else if (x < x1) {
221
        return y1;
222
    } else {
223
        return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
224
    }
225
}
226
 
227
inline int
228
Evaluate::interpolate(int v1, int v2, int k) {
229
    return v1 + (v2 - v1) * k / IPOLMAX;
230
}
231
 
232
inline int
233
Evaluate::materialScore(const Position& pos, bool print) {
234
    int mId = pos.materialId();
235
    int key = (mId >> 16) * 40507 + mId;
236
    MaterialHashData& newMhd = materialHash[key & (materialHash.size() - 1)];
237
    if ((newMhd.id != mId) || print)
238
        computeMaterialScore(pos, newMhd, print);
239
    mhd = &newMhd;
240
    return newMhd.score;
241
}
242
 
243
inline Evaluate::PawnHashData&
244
Evaluate::getPawnHashEntry(std::vector<Evaluate::PawnHashData>& pawnHash, U64 key) {
245
    int e0 = (int)key & (pawnHash.size() - 2);
246
    int e1 = e0 + 1;
247
    if (pawnHash[e0].key == key) {
248
        pawnHash[e0].current = 1;
249
        pawnHash[e1].current = 0;
250
        return pawnHash[e0];
251
    }
252
    if (pawnHash[e1].key == key) {
253
        pawnHash[e1].current = 1;
254
        pawnHash[e0].current = 0;
255
        return pawnHash[e1];
256
    }
257
    if (pawnHash[e0].current) {
258
        pawnHash[e1].current = 1;
259
        pawnHash[e0].current = 0;
260
        return pawnHash[e1];
261
    } else {
262
        pawnHash[e0].current = 1;
263
        pawnHash[e1].current = 0;
264
        return pawnHash[e0];
265
    }
266
}
267
 
268
inline Evaluate::KingSafetyHashData&
269
Evaluate::getKingSafetyHashEntry(vector_aligned<Evaluate::KingSafetyHashData>& ksHash, U64 key) {
270
    int e0 = (int)key & (ksHash.size() - 2);
271
    int e1 = e0 + 1;
272
    if (ksHash[e0].key == key) {
273
        ksHash[e0].current = 1;
274
        ksHash[e1].current = 0;
275
        return ksHash[e0];
276
    }
277
    if (ksHash[e1].key == key) {
278
        ksHash[e1].current = 1;
279
        ksHash[e0].current = 0;
280
        return ksHash[e1];
281
    }
282
    if (ksHash[e0].current) {
283
        ksHash[e1].current = 1;
284
        ksHash[e0].current = 0;
285
        return ksHash[e1];
286
    } else {
287
        ksHash[e0].current = 1;
288
        ksHash[e1].current = 0;
289
        return ksHash[e0];
290
    }
291
}
292
 
293
#endif /* EVALUATE_HPP_ */