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
 * parameters.hpp
21
 *
22
 *  Created on: Feb 25, 2012
23
 *      Author: petero
24
 */
25
 
26
#ifndef PARAMETERS_HPP_
27
#define PARAMETERS_HPP_
28
 
29
#include "util/util.hpp"
30
#include "piece.hpp"
31
#include "position.hpp"
32
 
33
#include <memory>
34
#include <functional>
35
#include <map>
36
#include <string>
37
#include <cassert>
38
 
39
 
40
/** Handles all UCI parameters. */
41
class Parameters {
42
public:
43
    enum Type {
44
        CHECK,
45
        SPIN,
46
        COMBO,
47
        BUTTON,
48
        STRING
49
    };
50
 
51
    /** Observer pattern. */
52
    class Listener {
53
        using Func = std::function<void()>;
54
    public:
55
        int addListener(Func f, bool callNow = true);
56
 
57
        void removeListener(int id);
58
 
59
    protected:
60
        void notify();
61
 
62
    private:
63
        int nextId = 0;
64
        std::map<int, Func> listeners;
65
    };
66
 
67
    /** Base class for UCI parameters. */
68
    struct ParamBase : public Listener {
69
        std::string name;
70
        Type type;
71
 
72
        ParamBase(const std::string& n, Type t) : name(n), type(t) { }
73
        ParamBase(const ParamBase& other) = delete;
74
        ParamBase& operator=(const ParamBase& other) = delete;
75
 
76
        virtual bool getBoolPar() const { assert(false); return false; }
77
        virtual int getIntPar() const { assert(false); return 0; }
78
        virtual std::string getStringPar() const { assert(false); return ""; }
79
        virtual void set(const std::string& value) { assert(false); }
80
    };
81
 
82
    /** A boolean parameter. */
83
    struct CheckParam : public ParamBase {
84
        bool value;
85
        bool defaultValue;
86
 
87
        CheckParam(const std::string& name, bool def)
88
            : ParamBase(name, CHECK) {
89
            this->value = def;
90
            this->defaultValue = def;
91
        }
92
 
93
        bool getBoolPar() const override { return value; }
94
 
95
        void set(const std::string& value) override {
96
            if (toLowerCase(value) == "true")
97
                this->value = true;
98
            else if (toLowerCase(value) == "false")
99
                this->value = false;
100
            notify();
101
        }
102
    };
103
 
104
    /** An integer parameter. */
105
    struct SpinParam : public ParamBase {
106
        int minValue;
107
        int maxValue;
108
        int value;
109
        int defaultValue;
110
 
111
        SpinParam(const std::string& name, int minV, int maxV, int def)
112
            : ParamBase(name, SPIN) {
113
            minValue = minV;
114
            maxValue = maxV;
115
            value = def;
116
            defaultValue = def;
117
        }
118
 
119
        int getIntPar() const override { return value; }
120
 
121
        void set(const std::string& value) override {
122
            int val;
123
            if (str2Num(value, val) && (val >= minValue) && (val <= maxValue)) {
124
                this->value = val;
125
                notify();
126
            }
127
        }
128
 
129
        int getDefaultValue() const { return defaultValue; }
130
        int getMinValue() const { return minValue; }
131
        int getMaxValue() const { return maxValue; }
132
    };
133
 
134
    /** A multi-choice parameter. */
135
    struct ComboParam : public ParamBase {
136
        std::vector<std::string> allowedValues;
137
        std::string value;
138
        std::string defaultValue;
139
 
140
        ComboParam(const std::string& name, const std::vector<std::string>& allowed,
141
                   const std::string& def)
142
            : ParamBase(name, COMBO) {
143
            this->allowedValues = allowed;
144
            this->value = def;
145
            this->defaultValue = def;
146
        }
147
 
148
        std::string getStringPar() const override { return value; }
149
 
150
        void set(const std::string& value) override {
151
            for (size_t i = 0; i < allowedValues.size(); i++) {
152
                const std::string& allowed = allowedValues[i];
153
                if (toLowerCase(allowed) == toLowerCase(value)) {
154
                    this->value = allowed;
155
                    notify();
156
                    break;
157
                }
158
            }
159
        }
160
    };
161
 
162
    /** An action parameter. */
163
    struct ButtonParam : public ParamBase {
164
        ButtonParam(const std::string& name)
165
            : ParamBase(name, BUTTON) { }
166
 
167
        void set(const std::string& value) override {
168
            notify();
169
        }
170
    };
171
 
172
    /** A string parameter. */
173
    struct StringParam : public ParamBase {
174
        std::string value;
175
        std::string defaultValue;
176
 
177
        StringParam(const std::string& name, const std::string& def)
178
            : ParamBase(name, STRING) {
179
            this->value = def;
180
            this->defaultValue = def;
181
        }
182
 
183
        std::string getStringPar() const override { return value; }
184
 
185
        void set(const std::string& value) override {
186
            this->value = value;
187
            notify();
188
        }
189
    };
190
 
191
    /** Get singleton instance. */
192
    static Parameters& instance();
193
 
194
    /** Retrieve list of all parameters. */
195
    void getParamNames(std::vector<std::string>& parNames);
196
 
197
    std::shared_ptr<ParamBase> getParam(const std::string& name) const;
198
 
199
    bool getBoolPar(const std::string& name) const;
200
    int getIntPar(const std::string& name) const;
201
    std::string getStringPar(const std::string& name) const;
202
 
203
    void set(const std::string& name, const std::string& value);
204
 
205
    /** Register a parameter. */
206
    void addPar(const std::shared_ptr<ParamBase>& p);
207
 
208
private:
209
    Parameters();
210
 
211
    std::map<std::string, std::shared_ptr<ParamBase>> params;
212
    std::vector<std::string> paramNames;
213
};
214
 
215
// ----------------------------------------------------------------------------
216
 
217
/** Param can be either a UCI parameter or a compile time constant. */
218
template <int defaultValue, int minValue, int maxValue, bool uci> class Param;
219
 
220
template <int defaultValue, int minValue, int maxValue>
221
class Param<defaultValue, minValue, maxValue, false> {
222
public:
223
    Param() {}
224
    operator int() const { return defaultValue; }
225
    void registerParam(const std::string& name, Parameters& pars) {}
226
    template <typename Func> void addListener(Func f) { f(); }
227
};
228
 
229
template <int defaultValue, int minValue, int maxValue>
230
class Param<defaultValue, minValue, maxValue, true> {
231
public:
232
    Param() : value(0) {}
233
    operator int() const { return value; }
234
    void registerParam(const std::string& name, Parameters& pars) {
235
        par = std::make_shared<Parameters::SpinParam>(name, minValue, maxValue, defaultValue);
236
        pars.addPar(par);
237
        par->addListener([this](){ value = par->getIntPar(); });
238
    }
239
    template <typename Func> void addListener(Func f) {
240
        if (par)
241
            par->addListener(f, false);
242
        f();
243
    }
244
private:
245
    int value;
246
    std::shared_ptr<Parameters::SpinParam> par;
247
};
248
 
249
#define DECLARE_PARAM(name, defV, minV, maxV, uci) \
250
    using name##ParamType = Param<defV,minV,maxV,uci>; \
251
    extern name##ParamType name;
252
 
253
#define DEFINE_PARAM(name) \
254
    name##ParamType name;
255
 
256
#define REGISTER_PARAM(varName, uciName) \
257
    varName.registerParam(uciName, *this);
258
 
259
// ----------------------------------------------------------------------------
260
 
261
/** Non-template base class to reduce executable code size. */
262
class ParamTableBase : public Parameters::Listener {
263
public:
264
    int getMinValue() const { return minValue; }
265
    int getMaxValue() const { return maxValue; }
266
 
267
protected:
268
    ParamTableBase(bool uci0, int minVal0, int maxVal0) :
269
        uci(uci0), minValue(minVal0), maxValue(maxVal0) {}
270
    void registerParamsN(const std::string& name, Parameters& pars,
271
                         int* table, int* parNo, int N);
272
    void modifiedN(int* table, int* parNo, int N);
273
 
274
    const bool uci;
275
    const int minValue;
276
    const int maxValue;
277
 
278
    std::vector<std::shared_ptr<Parameters::SpinParam>> params;
279
};
280
 
281
template <int N>
282
class ParamTable : public ParamTableBase {
283
public:
284
    ParamTable(int minVal, int maxVal, bool uci,
285
               std::initializer_list<int> data,
286
               std::initializer_list<int> parNo);
287
 
288
    int operator[](int i) const { return table[i]; }
289
    const int* getTable() const { return table; }
290
 
291
    void registerParams(const std::string& name, Parameters& pars) {
292
        registerParamsN(name, pars, table, parNo, N);
293
    }
294
private:
295
    int table[N];
296
    int parNo[N];
297
};
298
 
299
template <int N>
300
class ParamTableMirrored {
301
public:
302
    ParamTableMirrored(ParamTable<N>& orig0) : orig(orig0) {
303
        orig.addListener([this]() {
304
            if (N == 64) {
305
                for (int sq = 0; sq < N; sq++)
306
                    table[sq] = orig[Position::mirrorY(sq)];
307
            } else {
308
                for (int i = 0; i < N; i++)
309
                    table[i] = orig[N-1-i];
310
            }
311
        });
312
    }
313
    int operator[](int i) const { return table[i]; }
314
    const int* getTable() const { return table; }
315
private:
316
    int table[N];
317
    ParamTable<N>& orig;
318
};
319
 
320
template <int N>
321
ParamTable<N>::ParamTable(int minVal0, int maxVal0, bool uci0,
322
                          std::initializer_list<int> table0,
323
                          std::initializer_list<int> parNo0)
324
    : ParamTableBase(uci0, minVal0, maxVal0) {
325
    assert(table0.size() == N);
326
    assert(parNo0.size() == N);
327
    for (int i = 0; i < N; i++) {
328
        table[i] = table0.begin()[i];
329
        parNo[i] = parNo0.begin()[i];
330
    }
331
}
332
 
333
inline bool
334
Parameters::getBoolPar(const std::string& name) const {
335
    return getParam(name)->getBoolPar();
336
}
337
 
338
inline int
339
Parameters::getIntPar(const std::string& name) const {
340
    return getParam(name)->getIntPar();
341
}
342
 
343
inline std::string
344
Parameters::getStringPar(const std::string& name) const {
345
    return getParam(name)->getStringPar();
346
}
347
 
348
inline void
349
Parameters::set(const std::string& name, const std::string& value) {
350
    auto it = params.find(toLowerCase(name));
351
    if (it == params.end())
352
        return;
353
    it->second->set(value);
354
}
355
 
356
// ----------------------------------------------------------------------------
357
// UCI parameters
358
 
359
namespace UciParams {
360
    extern std::shared_ptr<Parameters::SpinParam> hash;
361
    extern std::shared_ptr<Parameters::CheckParam> ownBook;
362
    extern std::shared_ptr<Parameters::CheckParam> ponder;
363
    extern std::shared_ptr<Parameters::CheckParam> analyseMode;
364
    extern std::shared_ptr<Parameters::SpinParam> strength;
365
    extern std::shared_ptr<Parameters::SpinParam> threads;
366
    extern std::shared_ptr<Parameters::SpinParam> multiPV;
367
 
368
    extern std::shared_ptr<Parameters::StringParam> gtbPath;
369
    extern std::shared_ptr<Parameters::SpinParam> gtbCache;
370
    extern std::shared_ptr<Parameters::StringParam> rtbPath;
371
    extern std::shared_ptr<Parameters::SpinParam> minProbeDepth;
372
 
373
    extern std::shared_ptr<Parameters::ButtonParam> clearHash;
374
}
375
 
376
// ----------------------------------------------------------------------------
377
// Tuning parameters
378
 
379
const bool useUciParam = false;
380
 
381
extern int pieceValue[Piece::nPieceTypes];
382
 
383
// Evaluation parameters
384
 
385
DECLARE_PARAM(pV, 100, 1, 200, useUciParam);
386
DECLARE_PARAM(nV, 385, 1, 800, useUciParam);
387
DECLARE_PARAM(bV, 385, 1, 800, useUciParam);
388
DECLARE_PARAM(rV, 597, 1, 1200, useUciParam);
389
DECLARE_PARAM(qV, 1215, 1, 2400, useUciParam);
390
DECLARE_PARAM(kV, 9900, 9900, 9900, false); // Used by SEE algorithm but not included in board material sums
391
 
392
DECLARE_PARAM(pawnIslandPenalty,        8, 0, 50, useUciParam);
393
DECLARE_PARAM(pawnBackwardPenalty,      15, 0, 50, useUciParam);
394
DECLARE_PARAM(pawnSemiBackwardPenalty1, 6, -50, 50, useUciParam);
395
DECLARE_PARAM(pawnSemiBackwardPenalty2, 2, -50, 50, useUciParam);
396
DECLARE_PARAM(pawnRaceBonus,            181, 0, 1000, useUciParam);
397
DECLARE_PARAM(passedPawnEGFactor,       63, 1, 128, useUciParam);
398
DECLARE_PARAM(RBehindPP1,               10, -100, 100, useUciParam);
399
DECLARE_PARAM(RBehindPP2,               24, -100, 100, useUciParam);
400
 
401
DECLARE_PARAM(QvsRMBonus1,         30, -100, 100, useUciParam);
402
DECLARE_PARAM(QvsRMBonus2,         -8, -100, 100, useUciParam);
403
DECLARE_PARAM(knightVsQueenBonus1, 125, 0, 200, useUciParam);
404
DECLARE_PARAM(knightVsQueenBonus2, 251, 0, 600, useUciParam);
405
DECLARE_PARAM(knightVsQueenBonus3, 357, 0, 800, useUciParam);
406
DECLARE_PARAM(krkpBonus,           135, 0, 400, useUciParam);
407
DECLARE_PARAM(krpkbBonus,          140, -200, 200, useUciParam);
408
DECLARE_PARAM(krpkbPenalty,        70,  0, 128, useUciParam);
409
DECLARE_PARAM(krpknBonus,          259, 0, 400, useUciParam);
410
DECLARE_PARAM(RvsBPBonus,          -38, -200, 200, useUciParam);
411
 
412
DECLARE_PARAM(pawnTradePenalty,    54, 0, 100, useUciParam);
413
DECLARE_PARAM(pieceTradeBonus,     10, 0, 100, useUciParam);
414
DECLARE_PARAM(pawnTradeThreshold,  361, 100, 1000, useUciParam);
415
DECLARE_PARAM(pieceTradeThreshold, 717, 10, 1000, useUciParam);
416
 
417
DECLARE_PARAM(threatBonus1,     63, 5, 500, useUciParam);
418
DECLARE_PARAM(threatBonus2,     1191, 100, 10000, useUciParam);
419
 
420
DECLARE_PARAM(rookHalfOpenBonus,     14, 0, 100, useUciParam);
421
DECLARE_PARAM(rookOpenBonus,         21, 0, 100, useUciParam);
422
DECLARE_PARAM(rookDouble7thRowBonus, 78, 0, 100, useUciParam);
423
DECLARE_PARAM(trappedRookPenalty1,   59, 0, 200, useUciParam);
424
DECLARE_PARAM(trappedRookPenalty2,   31, 0, 200, useUciParam);
425
 
426
DECLARE_PARAM(bishopPairPawnPenalty, 5, 0, 10, useUciParam);
427
DECLARE_PARAM(trappedBishopPenalty,  128, 0, 300, useUciParam);
428
DECLARE_PARAM(oppoBishopPenalty,     80, 0, 128, useUciParam);
429
 
430
DECLARE_PARAM(kingSafetyHalfOpenBCDEFG1, 18, 0, 100, useUciParam);
431
DECLARE_PARAM(kingSafetyHalfOpenBCDEFG2, -2, -50, 100, useUciParam);
432
DECLARE_PARAM(kingSafetyHalfOpenAH1,     21, 0, 100, useUciParam);
433
DECLARE_PARAM(kingSafetyHalfOpenAH2,     14, 0, 100, useUciParam);
434
DECLARE_PARAM(kingSafetyWeight1,         26, -50, 200, useUciParam);
435
DECLARE_PARAM(kingSafetyWeight2,         -50, -50, 200, useUciParam);
436
DECLARE_PARAM(kingSafetyWeight3,         7, -50, 200, useUciParam);
437
DECLARE_PARAM(kingSafetyWeight4,         1, -50, 200, useUciParam);
438
DECLARE_PARAM(kingSafetyThreshold,       46, 0, 200, useUciParam);
439
DECLARE_PARAM(knightKingProtectBonus,    12, -50, 50, useUciParam);
440
DECLARE_PARAM(bishopKingProtectBonus,    15, -50, 50, useUciParam);
441
DECLARE_PARAM(pawnStormBonus,            12, 0, 20, useUciParam);
442
 
443
DECLARE_PARAM(pawnLoMtrl,          503, 0, 10000, useUciParam);
444
DECLARE_PARAM(pawnHiMtrl,          3205, 0, 10000, useUciParam);
445
DECLARE_PARAM(minorLoMtrl,         1114, 0, 10000, useUciParam);
446
DECLARE_PARAM(minorHiMtrl,         3743, 0, 10000, useUciParam);
447
DECLARE_PARAM(castleLoMtrl,        712, 0, 10000, useUciParam);
448
DECLARE_PARAM(castleHiMtrl,        7884, 0, 10000, useUciParam);
449
DECLARE_PARAM(queenLoMtrl,         4504, 0, 10000, useUciParam);
450
DECLARE_PARAM(queenHiMtrl,         6544, 0, 10000, useUciParam);
451
DECLARE_PARAM(passedPawnLoMtrl,    768, 0, 10000, useUciParam);
452
DECLARE_PARAM(passedPawnHiMtrl,    2511, 0, 10000, useUciParam);
453
DECLARE_PARAM(kingSafetyLoMtrl,    919, 0, 10000, useUciParam);
454
DECLARE_PARAM(kingSafetyHiMtrl,    3567, 0, 10000, useUciParam);
455
DECLARE_PARAM(oppoBishopLoMtrl,    752, 0, 10000, useUciParam);
456
DECLARE_PARAM(oppoBishopHiMtrl,    3386, 0, 10000, useUciParam);
457
DECLARE_PARAM(knightOutpostLoMtrl, 157, 0, 10000, useUciParam);
458
DECLARE_PARAM(knightOutpostHiMtrl, 539, 0, 10000, useUciParam);
459
 
460
extern ParamTable<64>         kt1b, kt2b, pt1b, pt2b, nt1b, nt2b, bt1b, bt2b, qt1b, qt2b, rt1b;
461
extern ParamTableMirrored<64> kt1w, kt2w, pt1w, pt2w, nt1w, nt2w, bt1w, bt2w, qt1w, qt2w, rt1w;
462
 
463
extern ParamTable<64> knightOutpostBonus;
464
extern ParamTable<64> protectedPawnBonus, attackedPawnBonus;
465
extern ParamTable<4> protectBonus;
466
 
467
extern ParamTable<15> rookMobScore;
468
extern ParamTable<14> bishMobScore;
469
extern ParamTable<28> knightMobScore;
470
extern ParamTable<28> queenMobScore;
471
 
472
extern ParamTable<36> connectedPPBonus;
473
extern ParamTable<8> passedPawnBonusX, passedPawnBonusY;
474
extern ParamTable<10> ppBlockerBonus;
475
extern ParamTable<8> candidatePassedBonus;
476
 
477
extern ParamTable<16> majorPieceRedundancy;
478
extern ParamTable<5> QvsRRBonus;
479
extern ParamTable<7> RvsMBonus, RvsMMBonus;
480
extern ParamTable<4> bishopPairValue;
481
extern ParamTable<7> rookEGDrawFactor, RvsBPDrawFactor;
482
 
483
extern ParamTable<4> castleFactor;
484
extern ParamTable<9> pawnShelterTable, pawnStormTable;
485
extern ParamTable<14> kingAttackWeight;
486
extern ParamTable<5> kingPPSupportK;
487
extern ParamTable<8> kingPPSupportP;
488
 
489
extern ParamTable<8> pawnDoubledPenalty;
490
extern ParamTable<8> pawnIsolatedPenalty;
491
extern ParamTable<10> halfMoveFactor;
492
extern ParamTable<9> stalePawnFactor;
493
 
494
 
495
// Search parameters
496
 
497
DECLARE_PARAM(aspirationWindow, 15, 1, 100, useUciParam);
498
DECLARE_PARAM(rootLMRMoveCount, 2, 0, 100, useUciParam);
499
 
500
DECLARE_PARAM(razorMargin1, 86, 1, 500, useUciParam);
501
DECLARE_PARAM(razorMargin2, 353, 1, 1000, useUciParam);
502
 
503
DECLARE_PARAM(reverseFutilityMargin1, 204, 1, 1000, useUciParam);
504
DECLARE_PARAM(reverseFutilityMargin2, 420, 1, 1000, useUciParam);
505
DECLARE_PARAM(reverseFutilityMargin3, 533, 1, 2000, useUciParam);
506
DECLARE_PARAM(reverseFutilityMargin4, 788, 1, 3000, useUciParam);
507
 
508
DECLARE_PARAM(futilityMargin1,  61, 1,  500, useUciParam);
509
DECLARE_PARAM(futilityMargin2, 144, 1,  500, useUciParam);
510
DECLARE_PARAM(futilityMargin3, 268, 1, 1000, useUciParam);
511
DECLARE_PARAM(futilityMargin4, 334, 1, 1000, useUciParam);
512
 
513
DECLARE_PARAM(lmpMoveCountLimit1,  3, 1, 256, useUciParam);
514
DECLARE_PARAM(lmpMoveCountLimit2,  6, 1, 256, useUciParam);
515
DECLARE_PARAM(lmpMoveCountLimit3, 12, 1, 256, useUciParam);
516
DECLARE_PARAM(lmpMoveCountLimit4, 24, 1, 256, useUciParam);
517
 
518
DECLARE_PARAM(lmrMoveCountLimit1,  3, 1, 256, useUciParam);
519
DECLARE_PARAM(lmrMoveCountLimit2, 12, 1, 256, useUciParam);
520
 
521
DECLARE_PARAM(quiesceMaxSortMoves, 8, 0, 256, useUciParam);
522
DECLARE_PARAM(deltaPruningMargin, 152, 0, 1000, useUciParam);
523
 
524
 
525
// Time management parameters
526
 
527
DECLARE_PARAM(timeMaxRemainingMoves, 35, 2, 200, useUciParam);
528
DECLARE_PARAM(bufferTime, 1000, 1, 10000, useUciParam);
529
DECLARE_PARAM(minTimeUsage, 85, 1, 100, useUciParam);
530
DECLARE_PARAM(maxTimeUsage, 400, 100, 1000, useUciParam);
531
DECLARE_PARAM(timePonderHitRate, 35, 1, 100, useUciParam);
532
 
533
 
534
#endif /* PARAMETERS_HPP_ */