Page 1 of 2

a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 6:10 pm
by wgarvin
To try and understand how Ippolit works, I have been reformatting it to make it readable (renaming things, grouping related functions in files, etc).

Anyone who has looked at the Ippolit code knows that it looks a bit machine-generated. In particular, there are parts which could only be the output of some kind of macro expander (probably the C preprocessor, though it could be other things as well). I came across a real gem of one of these, which I spent the last two hours translating back into something human-readable! So I will describe it here.

The code in question can be found in IPP_ENG.c around line 6169. It looks like this:

Code: Select all

  if ((tower_dynamics->flag & 128))
    {
      if (score > 0)
 {
    if (position_fixed.bitboard[enumerated_white_bright])
        score -= 20 * (((((((((((((A8) & 7) - ((position_fixed.black_king) & 7)) >= 0) ? (((A8) & 7) - ((pos....
     else
     score -= 20 * (((((((((((((A1) & 7) - ((position_fixed.black_king) & 7)) >= 0) ? (((A1) & 7) - ((pos....
   }
      else
   {
    if (position_fixed.bitboard[enumerated_black_bright])
        score += 20 * (((((((((((((A8) & 7) - ((position_fixed.white_king) & 7)) >= 0) ? (((A8) & 7) - ((pos....
     else
     score += 20 * (((((((((((((A1) & 7) - ((position_fixed.white_king) & 7)) >= 0) ? (((A1) & 7) - ((pos....
   }
    }
...Well actually, it only looks like that in a text editor that doesnt wrap lines. The full code is so long I'll put it in a separate reply. But just to give you an idea, its over 22KB of source code, and contains 5,162 parentheses characters. It also contains 168 usages of the ternary operator (x ? y : z).

More after the break.

Re: a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 6:11 pm
by wgarvin
Here's the full mess. From IPP_ENG.c around line 6169.

Code: Select all

  if ((tower_dynamics->flag & 128))
    {
      if (score > 0)
	{
	  if (position_fixed.bitboard[enumerated_white_bright])
	    score -= 20 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))));
	  else
	    score -= 20 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))));
	&#125;
      else
	&#123;
	  if &#40;position_fixed.bitboard&#91;enumerated_black_bright&#93;)
	    score += 20 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))));
	  else
	    score += 20 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))));
	&#125;
    &#125;

Re: a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 6:12 pm
by wgarvin
Okay, so what in the world does that code do?

Well, one thing it should do is convince programmers to be careful whenever they use min, max or abs macros!

Many compilers including Microsoft's, supply min(a,b) and max(a,b) as macros, something like this (from WinDef.h):

Code: Select all

#ifndef max
#define max&#40;a,b&#41;            ((&#40;a&#41; > &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)
#endif

#ifndef min
#define min&#40;a,b&#41;            ((&#40;a&#41; < &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)
#endif
It seems the authors of Ippolit were also using a macro for abs. And their min/max macros are slightly different from Microsoft's. Anyway, here's the form that was used in Ippolit:

Code: Select all

#define max&#40;a,b&#41;            ((&#40;a&#41; >= &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)

#define min&#40;a,b&#41;            ((&#40;a&#41; <= &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)

#define abs&#40;a&#41;              ((&#40;a&#41; >= 0&#41; ? &#40;a&#41; &#58; -&#40;a&#41;)
I started with the abs() calls, searching for >= 0 and extracting expressions and converting them to abs. Then max and min. Anyway, after a while I had something that looked like this:

Code: Select all

//inline int RankOf&#40;x&#41; &#123; return &#40;x >> 3&#41;; &#125;
//inline int FileOf&#40;x&#41; &#123; return &#40;x & 7&#41;; &#125;

    if (&#40;tower_dynamics->flag & 128&#41;)
    &#123;
        if &#40;score > 0&#41;
        &#123;
            int bkRank = &#40;position_fixed.black_king >> 3&#41;;
            int bkFile = &#40;position_fixed.black_king & 7&#41;;

            if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
                score -= 20 * min&#40;max&#40;abs&#40;FileOf&#40;A8&#41; - bkFile&#41;, abs&#40;RankOf&#40;A8&#41; - bkRank&#41;), max&#40;abs&#40;FileOf&#40;H1&#41; - bkFile&#41;, abs&#40;RankOf&#40;H1&#41; - bkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A8&#41; - bkFile&#41;, abs&#40;RankOf&#40;A8&#41; - bkRank&#41;), min&#40;abs&#40;FileOf&#40;H1&#41; - bkFile&#41;, abs&#40;RankOf&#40;H1&#41; - bkRank&#41;));
            else
                score -= 20 * min&#40;max&#40;abs&#40;FileOf&#40;A1&#41; - bkFile&#41;, abs&#40;RankOf&#40;A1&#41; - bkRank&#41;), max&#40;abs&#40;FileOf&#40;H8&#41; - bkFile&#41;, abs&#40;RankOf&#40;H8&#41; - bkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A1&#41; - bkFile&#41;, abs&#40;RankOf&#40;A1&#41; - bkRank&#41;), min&#40;abs&#40;FileOf&#40;H8&#41; - bkFile&#41;, abs&#40;RankOf&#40;H8&#41; - bkRank&#41;));
        &#125;
        else
        &#123;
            int wkRank = &#40;position_fixed.white_king >> 3&#41;;
            int wkFile = &#40;position_fixed.white_king & 7&#41;;

            if &#40;position_fixed.bb&#91;eBlackBright&#93;)
                score += 20 * min&#40;max&#40;abs&#40;FileOf&#40;A8&#41; - wkFile&#41;, abs&#40;RankOf&#40;A8&#41; - wkRank&#41;), max&#40;abs&#40;FileOf&#40;H1&#41; - wkFile&#41;, abs&#40;RankOf&#40;H1&#41; - wkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A8&#41; - wkFile&#41;, abs&#40;RankOf&#40;A8&#41; - wkRank&#41;), min&#40;abs&#40;FileOf&#40;H1&#41; - wkFile&#41;, abs&#40;RankOf&#40;H1&#41; - wkRank&#41;));
            else
                score += 20 * min&#40;max&#40;abs&#40;FileOf&#40;A1&#41; - wkFile&#41;, abs&#40;RankOf&#40;A1&#41; - wkRank&#41;), max&#40;abs&#40;FileOf&#40;H8&#41; - wkFile&#41;, abs&#40;RankOf&#40;H8&#41; - wkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A1&#41; - wkFile&#41;, abs&#40;RankOf&#40;A1&#41; - wkRank&#41;), min&#40;abs&#40;FileOf&#40;H8&#41; - wkFile&#41;, abs&#40;RankOf&#40;H8&#41; - wkRank&#41;));
        &#125;
    &#125;
That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:

Code: Select all

//inline int RankOf&#40;x&#41; &#123; return &#40;x >> 3&#41;; &#125;
//inline int FileOf&#40;x&#41; &#123; return &#40;x & 7&#41;; &#125;

    if (&#40;tower_dynamics->flag & 128&#41;)
    &#123;
        if &#40;score > 0&#41;
        &#123;
			int bkRank = &#40;position_fixed.black_king >> 3&#41;;
			int bkFile = &#40;position_fixed.black_king & 7&#41;;
			int bkRanksFrom1 = abs&#40;RANK_1 - bkRank&#41;;
			int bkRanksFrom8 = abs&#40;RANK_8 - bkRank&#41;;
			int bkFilesFromA = abs&#40;FILE_A - bkFile&#41;;
			int bkFilesFromH = abs&#40;FILE_H - bkFile&#41;;
			
            if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
                score -= 20 * min&#40;max&#40;bkFilesFromA, bkRanksFrom8&#41;, max&#40;bkFilesFromH, bkRanksFrom1&#41;)
                       + 10 * min&#40;min&#40;bkFilesFromA, bkRanksFrom8&#41;, min&#40;bkFilesFromH, bkRanksFrom1&#41;);
            else
                score -= 20 * min&#40;max&#40;bkFilesFromA, bkRanksFrom1&#41;, max&#40;bkFilesFromH, bkRanksFrom8&#41;)
                       + 10 * min&#40;min&#40;bkFilesFromA, bkRanksFrom1&#41;, min&#40;bkFilesFromH, bkRanksFrom8&#41;);
        &#125;
        else
        &#123;
			int wkRank = &#40;position_fixed.white_king >> 3&#41;;
			int wkFile = &#40;position_fixed.white_king & 7&#41;;
			int wkRanksFrom1 = abs&#40;RANK_1 - wkRank&#41;;
			int wkRanksFrom8 = abs&#40;RANK_8 - wkRank&#41;;
			int wkFilesFromA = abs&#40;FILE_A - wkFile&#41;;
			int wkFilesFromH = abs&#40;FILE_H - wkFile&#41;;

            if &#40;position_fixed.bb&#91;eBlackBright&#93;)
                score += 20 * min&#40;max&#40;wkFilesFromA, wkRanksFrom8&#41;, max&#40;wkFilesFromH, wkRanksFrom1&#41;)
                       + 10 * min&#40;min&#40;wkFilesFromA, wkRanksFrom8&#41;, min&#40;wkFilesFromH, wkRanksFrom1&#41;);
            else
                score += 20 * min&#40;max&#40;wkFilesFromA, wkRanksFrom1&#41;, max&#40;wkFilesFromH, wkRanksFrom8&#41;)
                       + 10 * min&#40;min&#40;wkFilesFromA, wkRanksFrom1&#41;, min&#40;wkFilesFromH, wkRanksFrom8&#41;);
        &#125;
    &#125;
Now its much easier to see what's going on.

The min/max stuff is being used to calculate some approximate distances from certain corners of the board. I have no idea why this isn't just a pre-computed table, but whatever.

Note that min, max and abs can all be implemented in a branchless fashion on most platforms. I think Microsoft compilers always do this for abs(), but I'm not sure about min/max. Anyways, if you use your own macro you make it a lot harder for the compiler, which now has to try and do common-subexpression elimination on your stuff and turn it back into something sensible.

As we've seen here, nesting 2 or 3 levels of these macros quickly gets out of hand. Rather than assume your compiler can work miracles with recklessly-expanded macro code, you might prefer to use a non-macro version. Maybe something like this:

Code: Select all

// These could be optimized further to be branchless &#40;though good compilers will do it themselves anyhow&#41;
template<class T> __forceinline T min&#40;const T& a, const T& b&#41; &#123; return a <= b? a &#58; b; &#125;
template<class T> __forceinline T max&#40;const T& a, const T& b&#41; &#123; return a >= b? a &#58; b; &#125;
template<class T> __forceinline T abs&#40;const T& a&#41;             &#123; return a >= 0? a &#58; -a; &#125;

Re: a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 9:53 pm
by Daniel Shawul
I recently tried to replace max,min, and abs with branchless inline functions. What prompted me to do that was the first time I profiled scorpio line by line with intel amplifier , the hot spots in eval in decreasing order were magics, popcnt, distance (and anywhere I have max,min,abs), score (mid/end game). I really did not expect distance to burn as much cycles for instance as popcnt. There was really nothing I can do about the first two, but I managed to improve very little by writing the manahattan distance calculator to use already calculated file and ranks. Branchless max,min, and abs did not bring anything though probably because msvc uses a branchless solution anyway.

Hot spots elsewhere were get_move (I pick the best move from scored move list), capture move generator etc.. I do not know if pre-sorting the list say using insertion sort would be better in some cases (at least on ALL nodes where all moves have to be searched), the capture generator was much faster with bitboards compared to my piece list engine.

I can see why top engines do spend time optimizing more or less these critical sections of an engine. But it was good to see for my self indeed this parts are time critical.

Re: a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 10:46 pm
by mcostalba
wgarvin wrote: That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:
We could do some further step, here is rewritten in SF style.

Code: Select all

if (&#40;tower_dynamics->flag & 128&#41;)
&#123;
    if &#40;score > 0&#41;
    &#123;
        Square ksq = position_fixed.black_king;

        if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;);
        else
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
    else
    &#123;
        Square ksq = position_fixed.white_king;

        if &#40;position_fixed.bb&#91;eBlackBright&#93;)
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;));
        else
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
&#125;
It seems to me that it is some code to penalize king when it is near to some board edge and penalize even more if it is near to corners of the same color of the enemy bishop.

Re: a cautionary tale about simple-looking macros

Posted: Sun Jul 03, 2011 11:20 pm
by wgarvin
I guess I should emphasize that there's nothing wrong with min/max macros if you are careful with the arguments. But they expand both arguments twice, and three of the four expanded arguments are executed. If you nest them like that Ippolit code did, or if you call functions with side effects inside, then expect some ugly surprises. ;) Back in the 80's, macros Of this sort were faster than a function. But that hasn't mattered for at least 10 years now.

Inline functions will not have those drawbacks, and with a good compiler they will be optimized at least as well as the macro versions.

Re: a cautionary tale about simple-looking macros

Posted: Mon Jul 04, 2011 12:05 am
by michiguel
mcostalba wrote:
wgarvin wrote: That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:
We could do some further step, here is rewritten in SF style.

Code: Select all

if (&#40;tower_dynamics->flag & 128&#41;)
&#123;
    if &#40;score > 0&#41;
    &#123;
        Square ksq = position_fixed.black_king;

        if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;);
        else
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
    else
    &#123;
        Square ksq = position_fixed.white_king;

        if &#40;position_fixed.bb&#91;eBlackBright&#93;)
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;));
        else
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
&#125;
It seems to me that it is some code to penalize king when it is near to some board edge and penalize even more if it is near to corners of the same color of the enemy bishop.
Yes, there was a thread about this long time ago, in which Zach Wegner explained it. One example of Macro's horror.

Miguel

Re: a cautionary tale about simple-looking macros

Posted: Mon Jul 04, 2011 12:07 am
by rbarreira
I believe macros should never be supplied by an API unless there's a very good reason for it, particularly when they evaluate arguments more than once...

Making a macro to be used by other people (possibly not very knowledgeable people) is simply asking for trouble, especially when people might not even notice that they're macros.

Re: a cautionary tale about simple-looking macros

Posted: Tue Jul 05, 2011 5:13 pm
by AlvaroBegue
If you give the compiler the opportunity to inline the function calls, is there any reason to use macros for these things? I haven't done that in years...

Re: a cautionary tale about simple-looking macros

Posted: Tue Jul 05, 2011 10:53 pm
by bob
AlvaroBegue wrote:If you give the compiler the opportunity to inline the function calls, is there any reason to use macros for these things? I haven't done that in years...
One has to still be clever at times. Functions like "Lock() and "Unlock()" can be problematic if you are not careful, as the optimizer can do unexpected things there as well.

well-written macros work just fine, IMHO. Of course, any sort of syntactical construction can be abused and byte you in the azz if you go overboard. :)