If you want to do it automatically, the problem is that computers are usually very poor at answering questions like: "what does the following set ofpositions have in common". The easiest way would probably be to have it generate random boolean expressions from position characteristics that are likely to be useful. E.g. in KPK you would have:
* side to move
* pawn on edge file
* promotion square
* pawn on Nth rank (N=2, 6, 7)
* distances between pieces and promo square
* kings in path of pawn
* exact relative locations of pieces
You could generate random boolean expressions from those, and then determine how well they correlate with the EGT WDL score. The expression that correlates best would then be taken as the primary decision. You could then test the other expressions on the sub-sets of positions in each of the classes created by the primary decision, etc.
generating algorithms
Moderators: hgm, Rebel, chrisw
-
- Posts: 27870
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
-
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: generating algorithms
Is exactly what I thought! Is what I tried to explain here in the first post, but seems that I was not very successful :hgm wrote:If you want to do it automatically, the problem is that computers are usually very poor at answering questions like: "what does the following set ofpositions have in common". The easiest way would probably be to have it generate random boolean expressions from position characteristics that are likely to be useful. E.g. in KPK you would have:
* side to move
* pawn on edge file
* promotion square
* pawn on Nth rank (N=2, 6, 7)
* distances between pieces and promo square
* kings in path of pawn
* exact relative locations of pieces
You could generate random boolean expressions from those, and then determine how well they correlate with the EGT WDL score. The expression that correlates best would then be taken as the primary decision. You could then test the other expressions on the sub-sets of positions in each of the classes created by the primary decision, etc.
"To generate this I think one can iterate trough all the possible positions having tablebase access and find which "Ifs" are true always; first find one-condition if's that are always true; then find two condition if's that are always true; and so on until all the cases or most of them are covered. Of course the if's that cover most positions will be first in the resulting algorithm. "
Daniel José - http://www.andscacs.com
-
- Posts: 27870
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: generating algorithms
But the problem is how to generate useful conditions.
-
- Posts: 2273
- Joined: Mon Sep 29, 2008 1:50 am
Re: generating algorithms
Has anyone tried the C5 algorithmhgm wrote:But the problem is how to generate useful conditions.
https://en.wikipedia.org/wiki/C4.5_algorithm ?
I don't know nothing about it, but it appears to be a standard algorithm.
Ideas=science. Simplification=engineering.
Without ideas there is nothing to simplify.
Without ideas there is nothing to simplify.
-
- Posts: 127
- Joined: Sat Jan 22, 2011 7:14 pm
- Location: Lille, France
Re: generating algorithms
C5 is a good ML algorithm. But more is needed here: feature construction.Michel wrote:Has anyone tried the C5 algorithm
https://en.wikipedia.org/wiki/C4.5_algorithm ?
I don't know nothing about it, but it appears to be a standard algorithm.
One can start with Utgoff's papers although he had evaluation in mind, not EGTB compression:
http://chessprogramming.wikispaces.com/Paul+E.+Utgoff
An alternative is Inductive Logic Programming (ILP), which builds features in a Prolog-like language.
Make no mistake though, feature construction is a difficult problem. Selection is much easier.
-
- Posts: 366
- Joined: Thu Jun 05, 2014 2:14 pm
- Location: Iran
- Full name: Mehdi Amini
Re: generating algorithms
[...]
If you are interested in Prolog, some chapters in the book "Prolog_Programming_for_Artificial_Intelligence" by lvan Bratko discuss worthwhile topics.
[...]Xann wrote:An alternative is Inductive Logic Programming (ILP), which builds features in a Prolog-like language.
If you are interested in Prolog, some chapters in the book "Prolog_Programming_for_Artificial_Intelligence" by lvan Bratko discuss worthwhile topics.
Farewell.
-
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: generating algorithms
Anyone has a working Stockfish version with tablebase support for Visual Studio? I made it work, but modifying some things, and now the tablebases always returns draw
I'm working on the algorithm to find algorithms, adding some functions to Stockfish, but I need this.
Thanks!
I'm working on the algorithm to find algorithms, adding some functions to Stockfish, but I need this.
Thanks!
Daniel José - http://www.andscacs.com
-
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: generating algorithms
Jose mº velasco just sent me one that works well. Thanks!cdani wrote:Anyone has a working Stockfish version with tablebase support for Visual Studio? I made it work, but modifying some things, and now the tablebases always returns draw
I'm working on the algorithm to find algorithms, adding some functions to Stockfish, but I need this.
Thanks!
Daniel José - http://www.andscacs.com
-
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: generating algorithms
Finally I tried to manually generate an algorithm to solve the KPK endgame, to try to see what is supposed to be generated automatically. The result I publish here is incomplete, it solves 265222 of 331352 possible positions (from the point of view of white). I stopped developing it because I think nobody will use this for anything but as an example and also of course is difficult to continue.
It's clear what HGM told that it's an impossible task for a computer, unless someone finds who knows what type of hidden relations.
It's done in Stockfish. Here I show the function I created, which generates every possible KPK position, then tries to solve it by hand generated algorithm, and compares the result to tablebase result. If a position is not correct, it shows it and exits. Also it shows the first position that it's not covered by the hand generated algorithm, if any, to give ideas over what can be the next condition to add. And finally shows the number of positions well solved by hand.
Maybe I will try to do the hand algorithm to solve the typical KBPK with rook pawn endgame , as I suppose it will be a lot easier, and can be used in most engines.
Here is the Visual Studio solution:
http://www.andscacs.com/stockfish/stockfish_syzygy.zip
This is the main function:
It's clear what HGM told that it's an impossible task for a computer, unless someone finds who knows what type of hidden relations.
It's done in Stockfish. Here I show the function I created, which generates every possible KPK position, then tries to solve it by hand generated algorithm, and compares the result to tablebase result. If a position is not correct, it shows it and exits. Also it shows the first position that it's not covered by the hand generated algorithm, if any, to give ideas over what can be the next condition to add. And finally shows the number of positions well solved by hand.
Maybe I will try to do the hand algorithm to solve the typical KBPK with rook pawn endgame , as I suppose it will be a lot easier, and can be used in most engines.
Here is the Visual Studio solution:
http://www.andscacs.com/stockfish/stockfish_syzygy.zip
This is the main function:
Code: Select all
void endgame_kpk(Position& pos) {
long long totalpositions = 0;
long long resolvedpositions = 0;
int unknown = 999;
bool first_unresolved_shown = false;
for (Square bk = SQ_A1; bk <= SQ_H8; bk++) {
for (Square wk = SQ_A1; wk <= SQ_H8; wk++) {
if (SquareDistance[bk][wk] <= 1)
continue;
for (Square p = SQ_A2; p <= SQ_H7; p++) {
if (p == wk || p == bk /*|| p == b*/)
continue;
for (Color c = WHITE; c <= BLACK; ++c) { //turn
pos.clear();
pos.thisThread = Threads.main();
pos.st->epSquare = SQ_NONE;
pos.put_piece(WHITE, PAWN, p);
pos.put_piece(WHITE, KING, wk);
pos.put_piece(BLACK, KING, bk);
pos.sideToMove = c;
pos.set_state(pos.st);
if (pos.attackers_to(pos.king_square(~c)) & pos.pieces(c))
continue; //illegal position
int own = unknown, found, v = Tablebases::probe_wdl(pos, &found);
if (!found) {
sync_cout << "Error not found; pawn: " << UCI::square(p) << " wk: " << UCI::square(wk) << " bk: " << UCI::square(bk) << sync_endl;
return;
}
totalpositions++;
// -2 : loss
// 0 : draw
// 2 : win
if (rank_of(bk) < rank_of(p) && c == WHITE) //pawn scapes
own = 2; //74772
if (own == unknown && rank_of(bk) < rank_of(p) - 1 && c == BLACK) //pawn scapes
own = -2; //53440 - 128212
if (own == unknown && rank_of(p) == 1 && rank_of(bk) <= 1) {//pawn scapes advancing 2 squares
if (c == WHITE || (rank_of(bk) == 0 && (SquareDistance[wk][p] == 1 || SquareDistance[bk][p] > 1))) //white's turn or pawn defended and black cannot block it or black cannot take pawn
own = 2; //4892
}
//black king prevents white king to unblock the pawn, or it must leave an entry to black king
if (own == unknown && (file_of(p) == 0 || file_of(p) == 7) && file_of(wk) == file_of(p) &&
rank_of(wk) > rank_of(p)) {
if (abs(file_of(bk) - file_of(wk)) - (c == BLACK ? 1 : 0) <= 2
&& (
(rank_of(bk) + (c == BLACK ? 1 : 0)) >= rank_of(wk) //black king will arrive to block the wking
||
(rank_of(p) == 6 && file_of(bk) != file_of(wk) && (rank_of(bk) + (c == BLACK ? 1 : 0)) == 6) //black king will arrive to c7/f7 to block the wking
||
(c == WHITE && SquareDistance[wk][p] >= SquareDistance[bk][p] && rank_of(wk) - rank_of(bk) == 1 && rank_of(p) != 1)
))
own = 0; //608
}
if (own == unknown && rank_of(bk) == rank_of(p) && c == WHITE && SquareDistance[wk][p] == 1 && rank_of(wk) >= rank_of(p)) //pawn scapes, maybe defended by own king
own = 2; //928 - 132808 //this works because of the previous condition
if (own == unknown && bk - p == 8 && c == BLACK && rank_of(bk) < 7) //black king blocks pawn to advance
own = 0; //2230 - 135038
if (own == unknown && bk - p == 8 && c == WHITE && rank_of(bk) == 7) {
//white king cannot force black king to leave the blockade of pawn, as black is stalemated
if (file_of(bk) == 0 ||
file_of(bk) == 7 ||
(rank_of(wk) < 4 || //pawn undefended
(file_of(wk) != file_of(p) && SquareDistance[wk][p] == 1) //wk has to go to the same file of their pawn to defend it
))
own = 0; //324 - 135362
}
//black king can block the pawn on 8th, but white king forces it to leave 8th row.
if (own == unknown && rank_of(bk) == 7 && rank_of(p) == 6 &&
//c == BLACK && p - wk == 8
(
(c == BLACK && p - wk == 8 && file_of(bk) != file_of(p))
||
(c == WHITE && SquareDistance[wk][p] == 2 && rank_of(wk) != 7 && file_of(bk) == file_of(p))
||
((c == WHITE && p - wk == 8) || (c == BLACK && (p - wk == 7 || p - wk == 9)) && file_of(bk) == file_of(p))
)
&& file_of(p) != 0 && file_of(p) != 7)
own = 2; //66
if (own == unknown && SquareDistance[bk][p] == 1 && c == BLACK && SquareDistance[wk][p] > 1) //black captures pawn
own = 0; //16076 - 151438
//white king between black king and pawn
if (own == unknown && file_of(bk) > file_of(wk) && file_of(wk) > file_of(p) && rank_of(bk) <= rank_of(wk) && SquareDistance[bk][p] > SquareDistance[wk][p] + (c == WHITE ? 1 : 0) + 1)
own = 2; //3209
if (own == unknown && file_of(bk) < file_of(wk) && file_of(wk) < file_of(p) && rank_of(bk) <= rank_of(wk) && SquareDistance[bk][p] > SquareDistance[wk][p] + (c == WHITE ? 1 : 0) + 1)
own = 2; //3209
if (own == unknown &&
SquareDistance[bk][make_square(file_of(p), (Rank)7)] - (c == BLACK ? 1 : 0) > SquareDistance[p][make_square(file_of(p), (Rank)7)]
) //king can not stop pawn
own = 2; //31920
if (own == unknown &&
SquareDistance[bk][make_square(file_of(p), (Rank)7)] < SquareDistance[wk][make_square(file_of(p), (Rank)7)] - (c == WHITE ? 1 : 0) &&
SquareDistance[bk][make_square(file_of(p), rank_of(p) + (Rank)1)] < SquareDistance[wk][make_square(file_of(p), rank_of(p) + (Rank)1)] - (c == WHITE ? 1 : 0) &&
(
rank_of(bk) > rank_of(p)
||
(rank_of(bk) == rank_of(p) &&
(
rank_of(p) != 1
||
SquareDistance[bk][make_square(file_of(p), rank_of(p) + (Rank)1)] == 1 //king can block the pawn immediately if in 2nd rank
)
)
)
) //king can stop pawn
own = 0; //41262
//king can catch and capture the pawn
if (own == unknown && rank_of(bk) + (c == BLACK ? 1 : 0) >= rank_of(p) && rank_of(p) != 1 &&
SquareDistance[bk][p] + (c == BLACK ? 1 : 0) < SquareDistance[wk][p] - (c == WHITE ? 1 : 0) && //+ (c == BLACK ? 1 : 0) seems illogical but is a way to ignore a bunch of exceptions
abs(file_of(wk) - file_of(p)) - (c == WHITE ? 1 : 0) > abs(file_of(wk) - file_of(p)) - (c == BLACK ? 1 : 0)
)
own = 0; //5874
if (own == unknown &&
SquareDistance[bk][make_square(file_of(p), rank_of(p) + (Rank)1)] - (c == BLACK ? 1 : 0) > SquareDistance[wk][make_square(file_of(p), rank_of(p) + (Rank)1)] - (c == WHITE ? 1 : 0) + 1 &&
rank_of(wk) >= rank_of(bk)
) //king can not stop pawn
own = 2; //5810
/*if (p == SQ_C3 && wk == SQ_A5 && bk == SQ_A2 && c == BLACK)
p = p;*/
Square antbk = bk, antwk = wk;
for (int tried = 0; tried < 5; tried++) {
//king can catch and capture the pawn from left side
if (own == unknown && file_of(p) > 0 && SquareDistance[bk][make_square(file_of(p) - (File)1, rank_of(p))] - (c == BLACK ? 1 : 0) <= 1 &&
SquareDistance[wk][make_square(file_of(p) - (File)1, rank_of(p))] > 1 &&
(SquareDistance[wk][p] > 3
|| ((rank_of(wk) > rank_of(p) + 1 && file_of(wk) < file_of(p)) &&
(c == BLACK && (file_of(wk) == file_of(bk) || (rank_of(wk) > rank_of(p) + 2 && SquareDistance[bk][make_square(file_of(p) - (File)1, rank_of(p))] == 1))))
|| ((rank_of(wk) > rank_of(p) + 1 && file_of(wk) >= file_of(p)) &&
(c == BLACK && ((rank_of(wk) > rank_of(p) + 2 && SquareDistance[bk][make_square(file_of(p) - (File)1, rank_of(p))] == 1))))
)
&& rank_of(p) != 1
) {
own = 0; //2551
break;
}
//push kings to pawn and try again
if (file_of(bk) < file_of(p))
bk += (Square)1;
if (file_of(wk) < file_of(p))
wk += (Square)1;
else
if (file_of(wk) > file_of(p))
wk -= (Square)1;
if (rank_of(bk) <= rank_of(p)) //'<=' necessary to remove space to white king 8/1K6/8/8/8/4P3/k7/8 b - - 0 1
bk += (Square)8;
if (rank_of(wk) > rank_of(p) && SquareDistance[bk][wk - 8] > 1)
wk -= (Square)8;
if (SquareDistance[bk][wk] == 1)
break;
}
bk = antbk;
wk = antwk;
for (int tried = 0; tried < 5; tried++) {
//king can catch and capture the pawn from right side
if (own == unknown && file_of(p) < 7 && SquareDistance[bk][make_square(file_of(p) + (File)1, rank_of(p))] - (c == BLACK ? 1 : 0) <= 1 &&
SquareDistance[wk][make_square(file_of(p) + (File)1, rank_of(p))] > 1 &&
(SquareDistance[wk][p] > 3
|| ((rank_of(wk) > rank_of(p) + 1 && file_of(wk) > file_of(p)) &&
(c == BLACK && (file_of(wk) == file_of(bk) || (rank_of(wk) > rank_of(p) + 2 && SquareDistance[bk][make_square(file_of(p) + (File)1, rank_of(p))] == 1))))
|| ((rank_of(wk) > rank_of(p) + 1 && file_of(wk) <= file_of(p)) &&
(c == BLACK && ((rank_of(wk) > rank_of(p) + 2 && SquareDistance[bk][make_square(file_of(p) + (File)1, rank_of(p))] == 1))))
)
&& rank_of(p) != 1
) {
own = 0; //2353
break;
}
//push kings to pawn and try again
if (file_of(bk) > file_of(p))
bk -= (Square)1;
if (file_of(wk) > file_of(p))
wk -= (Square)1;
else
if (file_of(wk) < file_of(p))
wk += (Square)1;
if (rank_of(bk) <= rank_of(p)) //'<=' necessary to remove space to white king 8/1K6/8/8/8/4P3/k7/8 b - - 0 1
bk += (Square)8;
if (rank_of(wk) > rank_of(p) && SquareDistance[bk][wk - 8] > 1)
wk -= (Square)8;
if (SquareDistance[bk][wk] == 1)
break;
}
bk = antbk;
wk = antwk;
//black king can stop the pawn on H
//8/8/8/8/8/7P/1k6/3K4 b - - 0 1
if (own == unknown && file_of(p) == 7 &&
SquareDistance[bk][SQ_H8] - (c == BLACK ? 1 : 0) < SquareDistance[wk][SQ_H8] - (c == WHITE ? 1 : 0) &&
SquareDistance[bk][SQ_H8] - (c == BLACK ? 1 : 0) < SquareDistance[p][SQ_H8] &&
rank_of(wk) < rank_of(bk)
)
own = 0; //2563
//black king can stop the pawn on A
if (own == unknown && file_of(p) == 0 &&
SquareDistance[bk][SQ_A8] - (c == BLACK ? 1 : 0) < SquareDistance[wk][SQ_A8] - (c == WHITE ? 1 : 0) &&
SquareDistance[bk][SQ_A8] - (c == BLACK ? 1 : 0) < SquareDistance[p][SQ_A8] &&
rank_of(wk) < rank_of(bk)
)
own = 0; //2563
//white king wins oposition going to the other side of the pawn
//8/8/8/8/8/8/k1P5/2K5 b - - 0 1
if (own == unknown && file_of(p) > 1 && file_of(p) < 7 && bk == make_square(file_of(p) - (File)2, rank_of(p)) && SquareDistance[wk][make_square(file_of(p) + (File)1, rank_of(p))] == 1)
own = 2; //280
if (own == unknown && file_of(p) < 6 && file_of(p) > 0 && bk == make_square(file_of(p) + (File)2, rank_of(p)) && SquareDistance[wk][make_square(file_of(p) - (File)1, rank_of(p))] == 1)
own = 2; //280
if (own == unknown && bk - p == 16 && (rank_of(bk) < 7 || c == BLACK)) //black king blocks pawn to advance
own = 0; //1166
//stalemate
if (own == unknown && c == BLACK && bk == SQ_H8 && wk != SQ_F6 && SquareDistance[wk][bk] == 2 &&
((file_of(wk) > FILE_F && p == SQ_F7) || (file_of(wk) == FILE_F && p == SQ_G6)))
own = 0; //4
if (own == unknown && c == BLACK && bk == SQ_A8 && wk != SQ_C6 && SquareDistance[wk][bk] == 2 &&
((file_of(wk) < FILE_C && p == SQ_C7) || (file_of(wk) == FILE_C && p == SQ_B6)))
own = 0; //4
//white king supporting advance of pawn, in front of black king, and pawn in the middle of the kings, and wk on the left of the pawn
//if (own == unknown && file_of(wk) + 1 == file_of(p) && file_of(p) + 1 == file_of(bk) && rank_of(wk) == rank_of(bk))
if (own == unknown &&
(file_of(wk) + 1 == file_of(p) ||
(file_of(wk) == file_of(p) - 2 && c == WHITE && !(p == SQ_G6 && bk == SQ_H8))) && //avoid stalemate
(file_of(p) + 1 == file_of(bk) || (file_of(p) + 2 == file_of(bk) && c == BLACK)) &&
(
rank_of(wk) == rank_of(bk) ||
(abs(rank_of(wk) - rank_of(bk)) == 1 && c == WHITE)
)
)
own = 2; //894
//white king supporting advance of pawn, in front of black king, and pawn in the middle of the kings, and wk on the right of the pawn
//if (own == unknown && file_of(wk) - 1 == file_of(p) && file_of(p) - 1 == file_of(bk) && rank_of(wk) == rank_of(bk))
if (own == unknown &&
(file_of(wk) - 1 == file_of(p) ||
(file_of(wk) == file_of(p) + 2 && c == WHITE && !(p == SQ_B6 && bk == SQ_A8))) && //avoid stalemate
(file_of(p) - 1 == file_of(bk) || (file_of(p) - 2 == file_of(bk) && c == BLACK)) &&
(
rank_of(wk) == rank_of(bk) ||
(abs(rank_of(wk) - rank_of(bk)) == 1 && c == WHITE)
)
)
own = 2; //894
//white king supporting advance of pawn in same file of the pawn, and in front of black king
if (own == unknown &&
(file_of(wk) == file_of(p) ||
(abs(file_of(wk) - file_of(p)) == 1 && c == WHITE)) &&
abs(file_of(p) - file_of(bk)) == 2 &&
(
rank_of(wk) == rank_of(bk) ||
(abs(rank_of(wk) - rank_of(bk)) == 1 && c == WHITE)
) &&
file_of(p) != 0 && file_of(p) != 7
)
own = 2; //860
//black king reaches front of pawn
if (own == unknown && rank_of(bk) > rank_of(p) &&
(file_of(bk) == file_of(p) || (abs(file_of(bk) - file_of(p)) == 1 && c == BLACK)) &&
abs(file_of(wk) - file_of(p)) > 1 &&
(rank_of(bk) <= rank_of(wk) || (rank_of(bk) - 1 == rank_of(wk) && c == BLACK))
)
own = 0; //2528
//black king disables advance of white king to support the pawn, from the left side
//8/8/8/8/8/8/k2P4/2K5 b - - 0 1
if (own == unknown && file_of(p) > (File)1 && make_square(file_of(wk) + (File)1, rank_of(wk) + (Rank)1) == p &&
SquareDistance[bk][make_square(file_of(p) - (File)2, rank_of(p) + (Rank)1)] == (c == BLACK ? 1 : 0) &&
rank_of(p) < 5
)
own = 0; //88
//black king disables advance of white king to support the pawn, from the right side
if (own == unknown && file_of(p) < (File)6 && make_square(file_of(wk) - (File)1, rank_of(wk) + (Rank)1) == p &&
SquareDistance[bk][make_square(file_of(p) + (File)2, rank_of(p) + (Rank)1)] == (c == BLACK ? 1 : 0) &&
rank_of(p) < 5
)
own = 0; //88
//white king reaches a good square to help to advance the pawn, against a king on the left side of the pawn
if (own == unknown && file_of(p) < 7 && file_of(bk) < file_of(p) && file_of(p) - file_of(bk) >= 2 + (c == BLACK ? 1 : 0) && SquareDistance[wk][p] < 2 &&
rank_of(bk) < rank_of(wk) + 3 + (c == WHITE && rank_of(wk) > rank_of(p) ? 1 : 0)
)
own = 2; //1551
//white king reaches a good square to help to advance the pawn, against a king on the right side of the pawn
if (own == unknown && file_of(p) > 0 && file_of(bk) > file_of(p) && file_of(bk) - file_of(p) >= 2 + (c == BLACK ? 1 : 0) && SquareDistance[wk][p] < 2 &&
rank_of(bk) < rank_of(wk) + 3 + (c == WHITE && rank_of(wk) > rank_of(p) ? 1 : 0)
)
own = 2; //1551
/*if (own == unknown && rank_of(p)>2 && SquareDistance[bk][make_square(file_of(p), rank_of(p) + (Rank)2)] < SquareDistance[wk][make_square(file_of(p), rank_of(p) + (Rank)1)] - (c == WHITE ? 1 : 0)) //black king blocks pawn to advance
own = 0; */
/*if (own == unknown && rank_of(p) < 6 && rank_of(p) != 1 && SquareDistance[wk][make_square(file_of(p), rank_of(p) + (Rank)2)] - (c == WHITE ? 1 : 0) <= SquareDistance[bk][make_square(file_of(p), rank_of(p) + (Rank)2)] - (c == BLACK ? 1 : 0))
own = 2;*/
if (own != 999 && abs(own) != abs(v)) {
sync_cout << "Error result: pawn: " << UCI::square(p) << " wk: " << UCI::square(wk) << " bk: " << UCI::square(bk) << " color: " << c << " own: " << own << " good: " << v << sync_endl;
return;
}
if (own != unknown)
resolvedpositions++;
else
if (!first_unresolved_shown) {
sync_cout << "1st unresolved: pawn: " << UCI::square(p) << " wk: " << UCI::square(wk) << " bk: " << UCI::square(bk) << " color: " << c << " good: " << v << sync_endl;
first_unresolved_shown = true;
}
}
}
}
}
sync_cout << "Total positions: " << totalpositions << " resolved positions: " << resolvedpositions << sync_endl;
}
Daniel José - http://www.andscacs.com