xr_a_y wrote: ↑Tue Jul 07, 2020 7:17 am
At top of your recursive Pvs or alphabeta routine you probably have
If depth <=0 then qsearch()
You can count nodes++ just after this.
In qsearch, you can do it at top of routine.
This way, you are counting all visited nodes.
Of course you can also count, legal move make, or anything else but what I described is what most engine does. Better to do the same as other do have a comparison point on this subject.
Thanks, this makes sense. I just changed to this method (increasing the nodes after the timeout code so nodes that time out and aren't searched aren't counted) and my search speed went from 711knps to 915knps. I always knew Raven was slow but maybe it's not quite as slow as I thought. Thanks!
hgm wrote: ↑Tue Jul 07, 2020 8:15 am
You cannot meaningfully compare node counts between different engines anyway. It depends too much on design details like this.
I'm aware of this and that engines have different ways of counting nodes. Still, it'll be nice to have my search speed be accurate when it compare it against changed to the engine which might affect speed.
In Demolito, I increment the node counter after checking for termination (max ply, repetition or 50 moves), and after HT pruning.
It seems to me that these are trivial exits, where no real work was done by the search, so shouldn't really count.
Anyway, this is arbitrary, doesn't matter.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
I think i am misinterpreting/misusing monad.
Have this now. Looks clumsy and overly complicated (understatement) . Just to update a counter.
Problem is there are many operations that affect nodecount. Like standing pat, futility pruning and now I have to make
functions for them in the proper format only for updating a counter.
public interface INodeCounted
{
int NCount
{
get;
}
}
public class NodeCounter<A>
{
public int NodeCount
{
get;
set;
}
public A Value
{
get;
set;
}
public NodeCounter(A val)
{
NodeCount = 0;
Value = val;
}
public void Init(A val)
{
Value = val;
}
public NodeCounter<B> Apply<B> (Func<A, NodeCounter<B>> func)
where B : INodeCounted
{
var result = func(Value);
NodeCount += result.Value.NCount;
result.NodeCount = NodeCount;
return result;
}
}
This is slightly better. Although still idiotic and overdone.
Otherwise I have to create a NodeCounter for each function with different signature.
So now I can use only one nodeCounter.
Nothing to do with monad by the way.
Only advantage is that you don't forget updating nodeCount.
public class NodeCounter
{
public int NodeCount
{
get;
set;
}
public B Apply<A, B> (Func<A, B> func, A arg)
where B : INodeCounted
{
var result = func(arg);
NodeCount += result.NCount;
return result;
}
}