From 7ff7ad1f77f21f7171b3952422dab921c4b198e5 Mon Sep 17 00:00:00 2001 From: H.G.Muller Date: Wed, 22 Feb 2017 20:34:36 +0100 Subject: [PATCH] Implement Makruk counting rules Adjudication is now performed based on the Makruk counting rules, assuming the players count in the way most favorable for them. This means that when the maximum count is N, the game is adjudicated draw immediately after the Nth move since the counting could have started when the opponent is bared, but only on the next move when not, to give him the opportunity to checkmate when he was not counting. This adjudication is switched off if -ruleMoves is set to a negative value, (normally this would be 0 in Makruk), and is also dependent on legality testing being on. --- backend.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/backend.c b/backend.c index 9281e7e..6d29691 100644 --- a/backend.c +++ b/backend.c @@ -8507,6 +8507,32 @@ Adjudicate (ChessProgramState *cps) return 1; } } else moveCount = 6; + + if(gameInfo.variant == VariantMakruk && // Makruk counting rules + (nrW == 1 || nrB == 1 || nr[WhitePawn] + nr[BlackPawn] == 0)) { // which only kick in when pawnless or bare King + int maxcnt, his, mine, c, wom = WhiteOnMove(forwardMostMove); + count = forwardMostMove; + while(count >= backwardMostMove) { + int np = nr[WhitePawn] + nr[BlackPawn]; + if(wom) mine = nrW, his = nrB, c = BlackPawn; + else mine = nrB, his = nrW, c = WhitePawn; + if(mine > 1 && np) { count++; break; } + if(mine > 1) maxcnt = 64; else + maxcnt = (nr[WhiteRook+c] > 1 ? 8 : nr[WhiteRook+c] ? 16 : nr[WhiteMan+c] > 1 ? 22 : + nr[WhiteKnight+c] > 1 ? 32 : nr[WhiteMan+c] ? 44 : 64) - his - 1; + while(boards[count][EP_STATUS] != EP_CAPTURE && count > backwardMostMove) count--; // seek previous character + if(count == backwardMostMove) break; + if(forwardMostMove - count >= 2*maxcnt + 1 - (mine == 1)) break; + Count(boards[--count], nr, &nrW, &nrB, &staleW, &staleB, &bishopColor); + } + if(forwardMostMove - count >= 2*maxcnt + 1 - (mine == 1)) { + boards[forwardMostMove][EP_STATUS] = EP_RULE_DRAW; + if(canAdjudicate && appData.ruleMoves >= 0) { + GameEnds( GameIsDrawn, "Xboard adjudication: counting rule", GE_XBOARD ); + return 1; + } + } + } } // Repetition draws and 50-move rule can be applied independently of legality testing -- 1.7.0.4