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.
fixing CPW-engine
Moderators: hgm, Rebel, chrisw
-
- Posts: 893
- Joined: Mon Jan 15, 2007 11:23 am
- Location: Warsza
-
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: fixing CPW-engine
In the starts of Andscacs, CPW-engine was of incredible help!! Thanks for it!!
Daniel José - http://www.andscacs.com
-
- Posts: 178
- Joined: Sat Jan 08, 2011 12:51 am
- Location: USA
- Full name: Alcides Schulz
Re: fixing CPW-engine
Good job Pawel !
I also used CPW-Engine in the beginning, tremendous help. Keep it up!
Thanks.
I also used CPW-Engine in the beginning, tremendous help. Keep it up!
Thanks.
-
- Posts: 646
- Joined: Wed Jun 18, 2014 2:30 pm
- Full name: Fahad Syed
Re: fixing CPW-engine
Is it a bitboard engine?
-
- Posts: 178
- Joined: Sat Jan 08, 2011 12:51 am
- Location: USA
- Full name: Alcides Schulz
Re: fixing CPW-engine
No, it uses 0x88 board representation.vittyvirus wrote:Is it a bitboard engine?
-
- Posts: 27796
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: fixing CPW-engine
How is "static eval pruning" different from "futility pruning"?
-
- Posts: 893
- Joined: Mon Jan 15, 2007 11:23 am
- Location: Warsza
Re: fixing CPW-engine
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.
Pawel Koziol
http://www.pkoziol.cal24.pl/rodent/rodent.htm
http://www.pkoziol.cal24.pl/rodent/rodent.htm
-
- Posts: 646
- Joined: Wed Jun 18, 2014 2:30 pm
- Full name: Fahad Syed
Re: fixing CPW-engine
You guya should then create a bitboard CPW engine. It'd help much.sedicla wrote:No, it uses 0x88 board representation.vittyvirus wrote:Is it a bitboard engine?
-
- Posts: 27796
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: fixing 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.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.
-
- Posts: 2250
- Joined: Wed Mar 08, 2006 8:47 pm
- Location: Hattingen, Germany
Re: fixing CPW-engine
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:hgm wrote: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.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.
Code: Select all
/************************************************************************
* EVAL PRUNING / STATIC NULL MOVE *
************************************************************************/
if (depth < 3
&& (!is_pv)
&& (!flagInCheck)
&& (abs(beta - 1) > -INF+100))
{
int static_eval = eval(alpha, beta, 1);
int eval_margin = 120 * depth;
if (static_eval - eval_margin >= beta)
return static_eval - eval_margin;
}
...
/************************************************************************
* Decide if FUTILITY PRUNING is applicable. If we are not in check, *
* not searching for a checkmate and eval is below (alpha - margin), *
* it might mean that searching non-tactical moves at low depths *
* is futile, so we set a flag allowing this pruning. *
************************************************************************/
int fmargin[4] = {0, 200, 300, 500};
if ( depth <= 3
&& !is_pv
&& !flagInCheck
&& abs(alpha) < 9000
&& eval(alpha,beta, 1) + fmargin[depth] <= alpha )
f_prune = 1;
/************************************************************************
* Now it's time to loop through the move list. *
************************************************************************/
for (int i = 0; i < mcount; i++) {
move_make(move);
if ( f_prune
&& !move_iscapt(move)
&& !move_isprom(move)
&& !isAttacked( !b.stm, b.KingLoc[b.stm] ) ) {
move_unmake(move);
continue;
}