fixing CPW-engine

Discussion of anything and everything relating to chess playing software and machines.

Moderators: hgm, Rebel, chrisw

PK
Posts: 893
Joined: Mon Jan 15, 2007 11:23 am
Location: Warsza

fixing CPW-engine

Post by PK »

In 2008 me and Edmund Moshammer wrote a thing called CPW-Engine, attempting it to be a didactic piece of code for Chessprogramming Wiki. It succeeded only as a self-learning exercise, because at that time both of us knew next to nothing about chess programming. Nevertheless that sin against all principles of good coding has been accessible on the Chessprogramming Wiki, and sometimes even some of the code snippets were referred to on this very forum.

About a month ago I looked at that code again and decided that showing 2008 version to the public is plain wrong. Today a slightly less wrong version has been uploaded, both at the wiki and under the following link.

https://github.com/nescitus/cpw-engine

It is still wrong in many places, but at least some bad decisions were revoked and some misconceptions cleared. Changes include:

- adding late move reduction
- changing hash retrieval logic in PV nodes
- changing futility pruning logic
- adding static eval pruning
- deleting lots of garbage from eval function
- interpolating between midgame and endgame scores

Probably it does not make sense to test this engine, as its only purpose was to show a couple of chess programming techniques. It should perform a bit better than Sungorus, which makes it uninteresting from competitive standpoint. If somebody wants to improve it - fine, but IMHO the only thing that makes sense would be to make code more readable and gradually remove some more idiocies that are left in the source.
User avatar
cdani
Posts: 2204
Joined: Sat Jan 18, 2014 10:24 am
Location: Andorra

Re: fixing CPW-engine

Post by cdani »

In the starts of Andscacs, CPW-engine was of incredible help!! Thanks for it!!
sedicla
Posts: 178
Joined: Sat Jan 08, 2011 12:51 am
Location: USA
Full name: Alcides Schulz

Re: fixing CPW-engine

Post by sedicla »

Good job Pawel !
I also used CPW-Engine in the beginning, tremendous help. Keep it up!
Thanks.
User avatar
vittyvirus
Posts: 646
Joined: Wed Jun 18, 2014 2:30 pm
Full name: Fahad Syed

Re: fixing CPW-engine

Post by vittyvirus »

Is it a bitboard engine?
sedicla
Posts: 178
Joined: Sat Jan 08, 2011 12:51 am
Location: USA
Full name: Alcides Schulz

Re: fixing CPW-engine

Post by sedicla »

vittyvirus wrote:Is it a bitboard engine?
No, it uses 0x88 board representation.
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: fixing CPW-engine

Post by hgm »

How is "static eval pruning" different from "futility pruning"?
PK
Posts: 893
Joined: Mon Jan 15, 2007 11:23 am
Location: Warsza

Re: fixing CPW-engine

Post by PK »

eval pruning/ static null move prunes a node without searching forcing moves. It's like a stand pat with a margin. or like a null move with search replaced by eval - margin. I must admit I am surprised that it works at mediocre depths reached by CPW-engine.
User avatar
vittyvirus
Posts: 646
Joined: Wed Jun 18, 2014 2:30 pm
Full name: Fahad Syed

Re: fixing CPW-engine

Post by vittyvirus »

sedicla wrote:
vittyvirus wrote:Is it a bitboard engine?
No, it uses 0x88 board representation.
You guya should then create a bitboard CPW engine. It'd help much.
User avatar
hgm
Posts: 27790
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: fixing CPW-engine

Post by hgm »

PK wrote:eval pruning/ static null move prunes a node without searching forcing moves. It's like a stand pat with a margin. or like a null move with search replaced by eval - margin. I must admit I am surprised that it works at mediocre depths reached by CPW-engine.
But that is exactly what futility pruning does, right? Pruning a node because you already know that this node will fail high already by merely standing pat. Futilty pruning is just an efficient implemantation of standing pat.
Gerd Isenberg
Posts: 2250
Joined: Wed Mar 08, 2006 8:47 pm
Location: Hattingen, Germany

Re: fixing CPW-engine

Post by Gerd Isenberg »

hgm wrote:
PK wrote:eval pruning/ static null move prunes a node without searching forcing moves. It's like a stand pat with a margin. or like a null move with search replaced by eval - margin. I must admit I am surprised that it works at mediocre depths reached by CPW-engine.
But that is exactly what futility pruning does, right? Pruning a node because you already know that this node will fail high already by merely standing pat. Futilty pruning is just an efficient implemantation of standing pat.
Yep, static null move pruning (Stockfish term) is also called Reverse Futility Pruning, often implemented in conjunction with classical fultility pruning inside the move loop as pre-filter, see Texel or cpw-engine, here the relevant snippets:

Code: Select all

/************************************************************************
    * EVAL PRUNING / STATIC NULL MOVE                                       *
    ************************************************************************/
 
    if &#40;depth < 3
        && (!is_pv&#41;
        && (!flagInCheck&#41;
        && &#40;abs&#40;beta - 1&#41; > -INF+100&#41;) 
    &#123;
        int static_eval = eval&#40;alpha, beta, 1&#41;;
 
        int eval_margin = 120 * depth;
        if &#40;static_eval - eval_margin >= beta&#41;
            return static_eval - eval_margin;
    &#125;
 
    ...

    /************************************************************************
    *  Decide  if FUTILITY PRUNING  is  applicable. If we are not in check, *
    *  not searching for a checkmate and eval is below  &#40;alpha - margin&#41;,   *
    *  it  might  mean that searching non-tactical moves at  low depths     *
    *  is futile, so we set a flag allowing this pruning.                   *
    ************************************************************************/
 
    int fmargin&#91;4&#93; = &#123;0, 200, 300, 500&#125;;
 
    if ( depth <= 3
    &&   !is_pv
    &&   !flagInCheck
    &&   abs&#40;alpha&#41; < 9000
    &&   eval&#40;alpha,beta, 1&#41; + fmargin&#91;depth&#93; <= alpha )
    f_prune = 1;

    /************************************************************************
    *  Now it's time to loop through the move list.                         *
    ************************************************************************/

    for &#40;int i = 0; i < mcount; i++) &#123;
        move_make&#40;move&#41;;

        if ( f_prune
        &&  !move_iscapt&#40;move&#41;
        &&  !move_isprom&#40;move&#41; 
        &&  !isAttacked&#40; !b.stm, b.KingLoc&#91;b.stm&#93; )  ) &#123;
                move_unmake&#40;move&#41;;
                continue;
        &#125;