LMR, Razoring, Futility.... with chess varient with drops?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by hgm »

micron wrote:A hash key is normally modified by bitwise xor, not by an arithmetic operation. A common way to change sides is to invert all the bits:
key ^= 0xffffffffffffffffULL;
Indeed, but for games with holdings this is a little inferior to an additive key. Because if you place two identical pieces on the same (holdings) square, the XOR would make both of them disappear, while + would simply add them and give a distinguishable key.
jdm64
Posts: 41
Joined: Thu May 27, 2010 11:32 pm

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by jdm64 »

Is it correct to save the value retuned by the null-move to the hash table if it's a beta cut-off? What would be the saved depth? Would I save the depth I would've searched that node, or (depth - R)?
jdm64
Posts: 41
Joined: Thu May 27, 2010 11:32 pm

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by jdm64 »

I think I implemented null-move right, but I did a quick test with 128 games and the engine with null-move scored 42.5 points, but the one without scored 85.5 points (wins + draws/2). Is that somewhere around a 153 elo difference?

Am I suppose to store the score in the hash table? I'm currently storing it, but thinking I shouldn't if it's playing this bad. The engines are set at a fixed depth search; the null-move search is 3x faster though.
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by hgm »

It depends on how you store it,and how you probe. In principle the hash table is just there to remember what you have done before, so if you later need to do it again, you can read the outcome without doing it. It does notreally matter what you store there. Just as long as you only use what you store for the same thing as it was originally derived from.
jdm64
Posts: 41
Joined: Thu May 27, 2010 11:32 pm

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by jdm64 »

One of the fields in the table is the depth the node was searched. Now regularly, I store (DepthLimit - CurrentDepth), but since the null-move was searched with R less depth, do I still store what I have been storing, or R less?
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by hgm »

If a null move from a node fails high, you should score the depth with which the node was called. Because that is the depth you will accept when you probe at the beginning of that node. The hash entry just says: "if you are requested to search this position to depth D, you will get this score". If the actual search wass less deep (e.g. D-2) because the nul move was sufficient for a cutoff, that does not matter. If you would not accept the hash probe for another depth=D search, you would again try nullmove, and again search D-2, and thus get exactly the same score as the hash already told you. So that would just be a waste of time.

The score of the node to which the null move leads will be stored with depth D-1-R, of course. But this is automatic. That node does not even know that it was reached by a null move, it only knows it was requested to do a D-1-R deep search, and it stores and propes with that depth.
jdm64
Posts: 41
Joined: Thu May 27, 2010 11:32 pm

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by jdm64 »

I added a new node-type to the hash table (NULL_NODE) which is like a cut-node, but without a best move. That improved the strength of my engine with null-move only ever so slightly (from -153 elo, to -136 elo). But still, the non-null-move version wins more (even if it's 3x slower).

What could I still be doing wrong? Is there any other test besides not being in check where I should not be doing null-move?

This is my null-move that I try right after hash lookup fails

Code: Select all

if (!incheck) {
    board->makeNull();
    score = -NullMoveSearch(-beta, -alpha, depth + 1, limit - 2);
    board->unmakeNull();

    if (score >= beta) {                                      
        tt->setItem(board->hash(), score, NULL_MOVE, limit - depth, NULL_NODE);
        return score;
    }
    // :Testing:
    // alpha = score;
}
And this is what a hash lookup looks like.

Code: Select all

if (tt->getItem(board->hash(), tt_item)) {
    if (tt_item->getScore(alpha, beta, limit - depth, score))
        return score;

    if (tt_item->getMove(move)) {
        if (!board->validMove(move, move))
            goto hashMiss;
        board->make(move);
        best = -NegaScout(-beta, -alpha, depth + 1, limit);
        board->unmake(move);

        if (best >= beta) {
            tt->setItem(board->hash(), best, move, limit - depth, CUT_NODE);
            return best;
        } else if (best > alpha) {
            alpha = best;
        }
    }
}
I'm going to try setting alpha = score, if the null-move doesn't cause a cut-off.
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by hgm »

How does the 'score' you return in the 3rd line of your probe code receive any value? It seems to me you would have had to pass a pointer to it to tt_item->getScore() to make that possible.
jdm64
Posts: 41
Joined: Thu May 27, 2010 11:32 pm

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by jdm64 »

hgm wrote:How does the 'score' you return in the 3rd line of your probe code receive any value? It seems to me you would have had to pass a pointer to it to tt_item->getScore() to make that possible.
I should've made that more clear. tt_item, move and score are passed by reference.

Code: Select all

bool TransTable::getItem(const uint64 hash, TransItem *&item);
bool TransItem::getScore(const int alpha, const int beta, const int inDepth, int &outScore) const;
bool TransItem::getMove(Move &inMove) const;
User avatar
hgm
Posts: 27808
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: LMR, Razoring, Futility.... with chess varient with drop

Post by hgm »

Ah, this was C++, not C.

Then I don't see anything wrong, really. Do you switch off null move in the late end-game (when the stm has no sliders left)? It might be counter-productive there.