[D]4k3/8/8/8/8/8/4P3/4K3 w - - 0
I did some internal nodes recognizer stuff for
node after a move:-
1) draw basics - when mat == 0 or single n/b
2) draw kpk;
If the above are disabled, Snailchess will lose this game.If enabled, will mate in about 20 moves.
I think if these are not implemented, a program may concede a stalemate/draw here.
Strelka has a bug in playing these at 60 moves/ 40sec.
It may win the first time and if replayed (with hash filled), it may blunder.
Code: Select all
[Event "Computer chess game"]
[Site "AAA-2A681BDBB73"]
[Date "2007.06.09"]
[Round "-"]
[White "Strelka v.1.0.beta"]
[Black "SnailChessV3"]
[Result "1/2-1/2"]
[TimeControl "60/40"]
[FEN "4k3/8/8/8/8/8/4P3/4K3 w - - 0 1"]
[SetUp "1"]
1. Kf2 Kf8 2. Ke3 Ke7 3. Kd4 Kd6 4. e4 Ke6 5. e5 Ke7 6. Ke3 Ke6 7. Ke4 Kd7
8. Kf5 Ke7 9. Kg5 Ke6 10. Kf4 Kd7 11. e6+ Kxe6
{SnailChess draws - insufficient material} 1/2-1/2
Code: Select all
...in search(), before make()
using matHashkey to determine basic board configuration after a move
if (!(SINGLE_PIECE(pS + 1) && PAWN(pS + 1) && IS_MOVE_CAPTURE_EP(*pS->pCurrentMove)));
else{
//edit
score = score_kpk(board, pS, side, *pS->pCurrentMove);
assert(!IS_MOVE_PROMOTE(*pS->pCurrentMove)); ...
}
//search end
int score_kpk(const board_t * board, stack_t * pS, const int side, const move_t m){
/*
will return :-
0 == draw
> 0 == side will safely promote
< 0 == oppn will safely promote
*/
//never promote
int pcCapture = !IS_MOVE_EP(m) ? PIECE( board->brd[TO(m)].sq) : Pawn;
int p_color = ((pS + 1)->matHashkey & MatHashkeyBP) != 0;//at most 1 p after make()
int xp_color = p_color ^ 1;
int p_sq = board->pawn[p_color]->sq;
int promote_sq = PROMOTE_SQ(p_sq, p_color);
//diagonal sq next to a corner promote-sq
int virtualPromoteSq = FILE(promote_sq) == 0 || FILE(promote_sq) == 7
? NEXT_DIAGONAL_PROMOTE_SQ_CORNER(promote_sq, p_color) : promote_sq;
int frontPawn = FRONT_SQ(p_sq, p_color);
int pOnMove = (p_color == side) ^ 1;
int score, i, j, k;
u64 bb;
assert((pS + 1)->matHashkey == DRAW_KPK_WP
|| (pS + 1)->matHashkey == DRAW_KPK_BP);
assert(pcCapture);
assert( board->nPawn[0] + board->nPawn[1] - (pcCapture == Pawn) == 1);
assert(bitCount((pS + 1)->matHashkey) == 1);//p
if (!pOnMove){
//draw if lone-k on move and can safe capt pawn
//get bb, pos of pawn after do()
if (IS_MOVE_PAWN(m)){
if (!IS_MOVE_EP(m)){//pawn at to-sq
bb = board->brd[TO(m)].bb;
}else{//pawn at ep-sq
bb = board->brd[EP_CAPTURE_SQ(m)].bb;
}
}else{//pawn not moved
bb = pS->bits[p_color][Pawn];
}
assert(bb && !(bb & bb - 1));
//bb == pos of pawn after do()
if (bb & pS->attackBB[xp_color][King] & ~pS->attackBB[p_color][King]){
//hash node after do()
hash(MaxDepth, EX, 0, (pS+1)->matHashkey, 100, 0);
return 0;
}
}
/*
1) stalemate if lone-k can occupy any of 4 corners of promote-sq if promote-sq is corner
2) stalemate if lone-k can occupy the frontsq of promote sq
3) k-k race to prom_sq must add + 1 step for p-king as it may need to avoid attack-sq of pawn
*/
if (board->king[xp_color]->sq == frontPawn
|| board->king[xp_color]->sq == virtualPromoteSq){//ok
//hash node after do()
hash(MaxDepth, EX, 0, (pS+1)->matHashkey, 100, 0);
return 0;
}
if (FILE(promote_sq) == 0 || FILE(promote_sq) == 7){
u64 bbCorners4;
switch(promote_sq){
case A1:
bbCorners4 = bbA1 | bbA2 | bbB1 | bbB2;
break;
case A8:
bbCorners4 = bbA8 | bbA7 | bbB8 | bbB7;
break;
case H1:
bbCorners4 = bbH1 | bbH2 | bbG1 | bbG2;
break;
case H8:
bbCorners4 = bbH8 | bbH7 | bbG8 | bbG7;
}
if (board->king[xp_color]->bb && bbCorners4){
//hash node after do()
hash(MaxDepth, EX, 0, (pS+1)->matHashkey, 100, 0);
return 0;//ok
}
}
j = k = 0;
if ((i = 8 - ROW_RANK(p_sq, p_color))
< pOnMove + DIST64(board->king[xp_color]->sq, promote_sq)
//is single king outrace pawn to prom-sq
|| ( j = DIST64(board->king[p_color]->sq, virtualPromoteSq))
< 1 + pOnMove
+ DIST64(board->king[xp_color]->sq, virtualPromoteSq)
//is single king outrace pawn-side king to prom-sq
|| ( k = DIST64(board->king[p_color]->sq, p_sq))
< 2 + pOnMove + DIST64(board->king[xp_color]->sq, p_sq)
//is single king nears pawn ahead of side king; extra step needed(dist + 3)
//as single king must avoid attack sq of pawn
){
//pawn side wins all 3 races
//!!!! codes may be bad here
i -= pOnMove;
//get an estimate score(ub/lb) relative to a queen
score = vQueen - vPawn - (j << 3) - (i + k)
- (DIST64(board->king[xp_color]->sq, promote_sq) <= 2) * v2Pawn;
score *= (1 - (p_color != side) * 2);//get score for proper side on move
i += j + k;//step to queen + king races to prot,etc
//i == num move to queen; depth to hash == i * 2 + p_color == side
i = i * 2 + (p_color == side);
//depth to hash = i;
assert(i > 0 && i < 64);
//hash node after move, i == depth
hash(i, score < 0 ? LB : UB, -score , (pS+1)->matHashkey, 100, 0);
}else{
//pawn side lost all 3 races
//hash node after do()
hash(MaxDepth, EX, 0 , (pS+1)->matHashkey, 100, 0);
score = 0;
}
return score;
}
Rasjid