#Stockfish - Three Checks to Win Variant.
19 messages · Page 1 of 1 (latest)
if u want an example, take a look at the code from the old multivariant https://github.com/ddugovic/Stockfish open it with some IDE like visual studio or something and search for #ifdef THREECHECK on all files and also search for pos.is_variant_end() that should show you all the code you need for three checks (even 5 checks as well), now applying it to NNUE would be more difficult, as you would need to add some sort of data added to the inputs.
As far as I know, fairy-stockfish uses very clever code to calculate the eval with the NNUE (since it does not have the check condition as an input to the NNUE)
rather than "very clever" I would rather call it a crude hack 😉. The NNUE simply is trained without the check count as input and in the engine a check bonus is then added on top of the NNUE output. That approach was chosen in Fairy-SF simply because it would be a lot of work to properly consider the check count in NNUE while it however would only benefit one of the many variants.
I've tried using the code from ddugovic. It's quite interesting and helpful, but I still can't get it to work with the current stockfish...
Is there a specific reason why you want to have it on latest SF? In terms of playing strength it shouldn't make a big difference, and if you compile multivariant-SF (ddugovic fork) with only -DTHREECHECK you basically already get the minimal extra code to make 3check work in SF. If you want the current best 3check engine then simply use Fairy-SF.
Problems with winboard. Choosing 3check under the UCI_Variant hasn't worked for either fairystockfish and ddugovic. So I thought it would be much easier if it was just hardcoded into the latest stockfish to make things a lot easier..
if its just winboard, u can get this https://fairy-stockfish.github.io/gui/#xboardwinboard i think it works really well for UCI engines (both fairy-stockfish and multivariant), you can also check https://github.com/cutechess/cutechess
https://fairy-stockfish.github.io/ loads of tools are also displayed here on the fairy website
Actually Fairy-SF has the big advantage of directly supporting the xboard protocol without any adapter, so if you just select that in winboard instead of using UCI it should work fine. It should in principle also work with recent UCI2WB adapters, only some adapters in older winboard versions are buggy, but it is easiest to just avoid using adapters for Fairy-SF since it has native support for all major chess variant engine protocols (UCI, xboard/CECP, USI, UCCI, UCI-cyclone).
I've tried doing that, but nothing I do seems to work.
The current stockfish code: File types.h: I've added
enum CheckCount : int {
CHECKS_0 = 0, CHECKS_NB = 11
};```
between enum Castling Right/ enum Bound
///// ENABLE_INCR_OPERATORS_ON(CheckCount) - I added that line to types.h as well.
////// Position.h - under struct StateInfo
{ Added - "```c++ CheckCount checksRemaining[COLOR_NB];'." "CheckCount checks_remaining(Color c) const;", "inline CheckCount Position::checks_remaining(Color c) const {
return st->checksRemaining[c];
}"```
Position.cpp - under namespace zobrist
```c++
Key checks[COLOR_NB][CHECKS_NB];```
// Lichess-style counter for 3check
```c++
if (check_counting())
{
if (ss >> token && token == '+')
{
ss >> token;
st->checksRemaining[WHITE] = CheckCount(std::max(3 - (token - '0'), 0));
ss >> token >> token;
st->checksRemaining[BLACK] = CheckCount(std::max(3 - (token - '0'), 0));
}
}" " for (Color c : {WHITE, BLACK})
si->key ^= Zobrist::checks[c][si->checksRemaining[c]];", " ss << st->checksRemaining[WHITE] << "+" << st->checksRemaining[BLACK] << " ";"
let me try formatting:
enum CheckCount : int {
CHECKS_0 = 0, CHECKS_NB = 11
};
``` between `enum Castling Right/ enum Bound`.
///// `ENABLE_INCR_OPERATORS_ON(CheckCount)` - I added that line to types.h as well. //////
`Position.h` - under struct
```c++
StateInfo {
//Added -
CheckCount checksRemaining[COLOR_NB];
CheckCount checks_remaining(Color c) const;
inline CheckCount Position::checks_remaining(Color c) const {
return st->checksRemaining[c];
}```
/////// `Position.cpp` - under namespace zobrist
```c++
Key checks[COLOR_NB][CHECKS_NB];
// Lichess-style counter for 3check
if (check_counting())
{
if (ss >> token && token == '+')
{
ss >> token;
st->checksRemaining[WHITE] = CheckCount(std::max(3 - (token - '0'), 0));
ss >> token >> token;
st->checksRemaining[BLACK] = CheckCount(std::max(3 - (token - '0'), 0));
}
}
for (Color c : {WHITE, BLACK}) {
si->key ^= Zobrist::checks[c][si->checksRemaining[c]];
ss << st->checksRemaining[WHITE] << "+" << st->checksRemaining[BLACK] << " ";
}
but I still don't really get what this is supposed to do
I think there are a lot more places
where the check counter needs to be added
if you truly want it to work
How do you format code like that in the chat?
use
` ` `c++
code
` ` `
enum CheckCount : int {
CHECKS_0 = 0, CHECKS_NB = 11
};```
```c++
ENABLE_INCR_OPERATORS_ON(CheckCount)
c++ CheckCount checksRemaining[COLOR_NB];
CheckCount checks_remaining(Color c) const;```
```c++
inline CheckCount Position::checks_remaining(Color c) const {
return st->checksRemaining[c];
}```
```c++
Key checks[COLOR_NB][CHECKS_NB];```
```c++
for (Color c : {WHITE, BLACK})
for (int n = 0; n < CHECKS_NB; ++n)
Zobrist::checks[c][n] = rng.rand<Key>();```
```c++
if (ss >> token && token == '+')
{
ss >> token;
st->checksRemaining[WHITE] = CheckCount(std::max(3 - (token - '0'), 0));
ss >> token >> token;
st->checksRemaining[BLACK] = CheckCount(std::max(3 - (token - '0'), 0));
}```
```c++
for (Color c : {WHITE, BLACK})
si->key ^= Zobrist::checks[c][si->checksRemaining[c]];```
```c++
ss << st->checksRemaining[WHITE] << "+" << st->checksRemaining[BLACK] << " ";```
```c++
if (givesCheck)
k ^= Zobrist::checks[us][st->checksRemaining[us]] ^ Zobrist::checks[us][--(st->checksRemaining[us])];```
```c++
if (checks_remaining(~sideToMove) == 0)
{
result = mated_in(ply);
return true;
} ```
Do I need any others?