avoiding long code question

Programming Topics (Computer Chess) and technical aspects as test techniques, book building, program tuning etc

Moderator: Andres Valverde

avoiding long code question

Postby Uri Blass » 18 Nov 2005, 18:55

In Movei every makemove ends with the function
generatepinarray()

generatepinarray() update information about pins that may be used for pruning or generating moves in the next ply.


Note that I thought to take generatepinarray() out of makemove.
The reason is that there are some cases when I prune after makemove
without using the information that generatepinarrays() have.

I have the following problem:

In most of the cases that I call makemove I need to call immediately after it generatepinarray() so the code is longer and uglier if I replace almost every makemove by

makemove(...)
generatepinarray();

My question is what is the best way to solve it.

I can change my makemove to get another boolean parameter that is going to tell it if to generate pin information and in this case the number of lines in the code is almost the same.

I am not sure if this is the best thing to do or there is a better idea.
What is your opinion about it?

Note that my undomove ends with
if (pinnumber[ply]>0) generatepinarray();

pinnumber[ply] is the number of pinned pieces of the side to move and again I can save time by doing it only when I need it when makemove did not update the pin array and again doing it in that way is going to do the code longer.

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: avoiding long code question

Postby Gerd Isenberg » 18 Nov 2005, 21:08

Hide implementation details as far as possible inside your search, only use make/unmake and do all neccessary updates there.

Passing an artifical, boolean parameter to perform some special update in make/unmake sounds a bit weird to me. If you like to delay some "expensive" updates, like getting lists or sets of pinned pieces per side, use own caches with some validity-flags, initialized as "invalid" in makemove.

Gerd
Gerd Isenberg
 
Posts: 285
Joined: 31 Jan 2005, 20:31
Location: Hattingen, Germany

Re: avoiding long code question

Postby Uri Blass » 18 Nov 2005, 21:42

Gerd Isenberg wrote:Hide implementation details as far as possible inside your search, only use make/unmake and do all neccessary updates there.

Passing an artifical, boolean parameter to perform some special update in make/unmake sounds a bit weird to me. If you like to delay some "expensive" updates, like getting lists or sets of pinned pieces per side, use own caches with some validity-flags, initialized as "invalid" in makemove.

Gerd


I understand that you suggest not to add another parameter to my makemove.

The only solution that I thought about except doing it is simply to have longer code because after most of my makemove I need to have also generatepinarray() but not after all of them(I have something like 30 makemove() and I do not see how to avoid adding generatepinarray() in almost 30 places in my code if I do not add another parameter to my makemove.

I do not understand what you mean by
"use own caches with some validity-flags, initialized as "invalid" in makemove"

Does it prevent the longer code and if it prevents it then how it does it?



Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: avoiding long code question

Postby Piotr Cichy » 18 Nov 2005, 21:43

You can change the name of function makemove to makemovefast and remove the call to generatepinarray from it. Then you create new function:

Code: Select all
inline void makemove(...)
{
  makemovefast(...);
  generatepinarray();
}


In places of code, where generatepinarray is not needed, you just change makemove to makemovefast.

This should be enough short, readable and efficient.
User avatar
Piotr Cichy
 
Posts: 47
Joined: 03 Oct 2004, 11:30
Location: Kalisz, Poland

Re: avoiding long code question

Postby Uri Blass » 18 Nov 2005, 21:48

Piotr Cichy wrote:You can change the name of function makemove to makemovefast and remove the call to generatepinarray from it. Then you create new function:

Code: Select all
inline void makemove(...)
{
  makemovefast(...);
  generatepinarray();
}


In places of code, where generatepinarray is not needed, you just change makemove to makemovefast.

This should be enough short, readable and efficient.


Thanks
It seems to be a simple and better solution.

Uri
User avatar
Uri Blass
 
Posts: 727
Joined: 09 Oct 2004, 05:59
Location: Tel-Aviv

Re: avoiding long code question

Postby Gerd Isenberg » 19 Nov 2005, 01:38

Uri Blass wrote:I understand that you suggest not to add another parameter to my makemove.


Yes. after reading Piotr's post i finally understand your initial question ;-)

An additional boolean parameter requires runtime checking, while using two function incarnations is like calling the same callee from different places with implicit constant compile/link-time parameter.

If you know exactly before which routine you need, that is fine.

If - depending on the design and structure (flow and dependency of information) of your program (lazy eval, hashing, etc) - there is a big chance that you don't need information about pinned pieces for some side at all, the caching approach comes in mind.

Assume you have two places in your code where you need the pinned piece information. In eval for both sides, in movegen only for the side to move. Computing once and storing for possible later use - caching.
Flags are needed, to ask whether the stored values are already present or not.

Uri Blass wrote:The only solution that I thought about except doing it is simply to have longer code because after most of my makemove I need to have also generatepinarray() but not after all of them(I have something like 30 makemove() and I do not see how to avoid adding generatepinarray() in almost 30 places in my code if I do not add another parameter to my makemove.

I do not understand what you mean by
"use own caches with some validity-flags, initialized as "invalid" in makemove"

Does it prevent the longer code and if it prevents it then how it does it?
Uri


It is about avoiding to compute conditionally needed and relative expensive things multiple times per node. Like a hashtable with one slot (per ply?) where a set flag indicates "valid, already calculated".

During making a move the flags (for both sides) must be initialized with "invalid, not yet calculated".

Gerd
Gerd Isenberg
 
Posts: 285
Joined: 31 Jan 2005, 20:31
Location: Hattingen, Germany


Return to Programming and Technical Discussions

Who is online

Users browsing this forum: No registered users and 4 guests