Syntax error?

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
Eelco de Groot
Posts: 4669
Joined: Sun Mar 12, 2006 2:40 am
Full name:   Eelco de Groot

Syntax error?

Post by Eelco de Groot »

Hello,

I was experimenting a bit with King Safety in Toga and tried a simple experiment with the idea that if, from the viewpoint of White, the eval so far is good, White probably can pay less attention to any King Safety problems. It may be a bit risky in case of large differences in material but I tried a small correction at first.

In Glaurung you seem to be able to get away with just subtracting the full eval! Here in Toga I divided first by 0x28 but positionally that seems to give worse results already. But there was another problem;

When dividing the pointer *opening holding the eval result so far, something seems to go wrong with divisions of 2^n, that the compiler probably translates in a direct bitshift routine.

For instance with the following king safety code in Toga

Code: Select all

         // scoring

         ASSERT(piece_nb>=0&&piece_nb<16);

			kingdanger = (attack_tot * KingAttackOpening * KingAttackWeight[piece_nb] + 1000 * pawn_nb) / 256;
			kingdanger -= ((colour == 0)? 1 : -1) * ((*opening) / 0x28);
			op[colour] -= kingdanger;

         }
      }
   }

   // update

   *opening += ((op[White] - op[Black]) * KingSafetyWeight) / 256;
   *endgame += ((eg[White] - eg[Black]) * KingSafetyWeight) / 256;
there are no problems, evaluation is correct, Kasparov is winning:


[d]rb6/1p2rpk1/pP2p1p1/P1PpP2p/q2n3P/2BQ2P1/4RP2/2R3K1 w - -

Engine: Toga Mara Beta 1/Toga 1.4 Checkov Beta_4 (256 MB)

1/04 0:00 +0.20 36.Bxd4 Qxa5 (40)

2/12 0:00 +0.06 36.Bxd4 Qxa5 37.c6 (979)

3/16 0:00 +0.52 36.Bxd4 Kf8 37.Bc3 Kg8 (2.799)

4/20 0:00 +0.26 36.Bxd4 Qc6 37.Qf3 Kg8 38.Rd1 (10.116)

5/20 0:00 +0.56 36.Bxd4 Qb5 37.Qf3 Kg8 38.c6 bxc6
39.Bc5 (18.068)

6/20 0:00 +0.27 36.Bxd4 Qc6 37.Qf3 Kg8 38.Qf6 Rd7
39.Rd1 (35.986)

7/20 0:00 +0.59 36.Bxd4 Qc6 37.Qf3 Rd7 38.Rd2 Kg8
39.Qf6 Qb5 (64.049)

8/22 0:00 +0.64 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Rd2 Kg8 40.Rcd1 Qb5 (119.304)

9/25 0:00 +0.50 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Rd2 Qa4 40.c6 bxc6 41.Qg5 Qxa5
42.Rxc6 (244.438)

10/40 0:01 +0.72 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Rb2 Kg8 40.Be3 Kh7 41.Rd1 Kg8 (567.215) 295

11/40 0:03 +0.66 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Rb2 Kg8 40.Be3 Kh7 41.Rd2 Kg8
42.Bh6 (1.119.323) 293

12/40 0:07 +0.91 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Rb2 Kg8 40.Be3 Kh7 41.Rd2 Qc8
42.c6 bxc6 43.Rd3 (2.257.252) 309

13/40 0:16 +1.67 36.Bxd4 Qc6 37.Qf3 Rd7 38.Qf6+ Kh7
39.Be3 Qc8 40.c6 bxc6 41.Bd4 Qh8
42.Qxh8+ Kxh8 43.Rec2 Kg7 44.Rxc6 Rb7
45.Rc8 (5.223.282) 310

but if I divide the pointer by 32, or 0x20, or 0x40, something goes wrong

Code: Select all

         // scoring

         ASSERT(piece_nb>=0&&piece_nb<16);

			kingdanger = (attack_tot * KingAttackOpening * KingAttackWeight[piece_nb] + 1000 * pawn_nb) / 256;
			kingdanger -= ((colour == 0)? 1 : -1) * ((*opening) / 0x20);
			op[colour] -= kingdanger;

         }
      }
   }

   // update

   *opening += ((op[White] - op[Black]) * KingSafetyWeight) / 256;
   *endgame += ((eg[White] - eg[Black]) * KingSafetyWeight) / 256;
Toga gives an incorrect evaluation in the Kasparov - DeepBlue position, Kasparov is supposed to be better here after 35...Nxd4

[d]rb6/1p2rpk1/pP2p1p1/P1PpP2p/q2n3P/2BQ2P1/4RP2/2R3K1 w - -

Engine: Toga Mara Beta 1/Toga 1.4 Checkov Beta_4 (256 MB)

1/04 0:00 +0.18 36.Bxd4 Qxa5 (40)

2/13 0:00 +0.06 36.Bxd4 Qxa5 37.c6 (1.386)

3/13 0:00 +0.51 36.Bxd4 Qb5 37.Qf3 Kg8 (3.316)

4/13 0:00 +0.26 36.Bxd4 Qc6 37.Qf3 Kg8 38.Rd1 (7.416)

5/15 0:00 +0.46 36.Bxd4 Kh7 37.Qe3 Qb5 38.Bc3 Kg8 (20.314)

6/20 0:00 +0.27 36.Bxd4 Qc6 37.Qf3 Kg8 38.Qf6 Rd7
39.Rd1 (48.108)

7/34 0:02 -4.63 36.Bxd4 Qb5 37.Qa3 Qxe2 38.c6 bxc6
39.Qb4 Rb7 40.f4 Qg4 (891.031) 355

7/34 0:02 -4.06 36.Ree1 Nb3 37.Qf3 Rd7 38.Rcd1 d4
39.Bd2 Nxd2 40.Rxd2 Qxa5 (925.399) 355

8/34 0:04 -4.49 36.Ree1 Qc4 37.Qe3 Nb3 38.Rcd1 Qxc5
39.Qf3 Kg8 40.Qf6 (1.693.568) 364

9/34 0:04 -4.58 36.Ree1 Qc4 37.Qe3 Nb3 38.Rcd1 Qxc5
39.Qf3 Kg8 40.Qf6 d4 41.Bb2 (1.752.417) 369

10/34 0:05 -5.07 36.Ree1 Qc4 37.Qe3 Nb3 38.Rcd1 Qxc5
39.Qf3 Kg8 40.Kg2 Nxa5 41.Bxa5 Qxa5
42.Rc1 (1.922.693) 363

11/45 0:14 -4.96 36.Ree1 Qc4 37.Qd1 Nb3 38.Rc2 d4
39.Bb2 Qd5 40.Rce2 d3 41.Re4 d2
42.R1e3 Nxc5 43.Rf4 (5.141.453) 364

12/45 0:20 -6.39 36.Ree1 Qc4 37.Qd1 Bxe5 38.Kg2 Nc6
39.Bd2 Qg4 40.Re2 Rc8 41.Bg5 Rd7 (7.273.204) 365

best move: Re2-e1 time: 2:22.594 min n/s: 370.113 CPU 100.0% n/s(1CPU): 370.113 nodes: 52.660.000

Does anybody have an idea what exactly went wrong? Is it a compiler (this was compiled with MSVC 2005) error or can't I just use this syntax, when *opening is too large a number, instead of directly /32 do I better first multiply by say 8 and then divide by a bigger number say 256?

If the division in the second case always is wrong, I would expect different evals right from the start but the position score only deteriorates from ply 7 onwards beyond?


Thanks for advice,

Eelco
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan
User avatar
Eelco de Groot
Posts: 4669
Joined: Sun Mar 12, 2006 2:40 am
Full name:   Eelco de Groot

Re: Syntax error?

Post by Eelco de Groot »

Eelco de Groot wrote:
In Glaurung you seem to be able to get away with just subtracting the full eval! Here in Toga I divided first by 0x28
Sorry about that, that was not really correct and rather misleading, too strange to be true, I need to exercise my plusses and minuses, had to look closer and finally saw in the same modification of Glaurung actually a much smaller fraction of the eval is subtracted, because of a division by 256. The equivalent code in Ancalagon originally looked a bit like this, but the factor 1000 is now I believe 0x300:

Code: Select all

      // Finally, extract the king safety score from the SafetyTable[] array.
      // Add the score to the evaluation, and also to ei.futilityMargin.  The
      // reason for adding the king safety score to the futility margin is
      // that the king safety scores can sometimes be very big, and that
      // capturing a single attacking piece can therefore result in a score
      // change far bigger than the value of the captured piece.
      assert(inc < 100);
      ei.mgValue -= ((1000 - sign * ei.mgValue) * sign * Value(SafetyTable[inc])/256);
      if(c == p.side_to_move())
        ei.futilityMargin += Value(2 * SafetyTable[inc]);
    }
  }
Eelco
Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it.
-- Brian W. Kernighan