First output from evaluate_board_control()

Discussion of computer chess matches and engine tournaments.

Moderator: Ras

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

First output from evaluate_board_control()

Post by Eelco de Groot »

(Quoting Marco from the Stockfish 1.4 thread, I answer in a different thread because it is all a bit off-topic to the other material there:)
mcostalba wrote:The function definition is in material.h

Code: Select all

/// MaterialInfo::space_weight() simply returns the weight for the space
/// evaluation for this material configuration.

inline int MaterialInfo::space_weight() const {

  return spaceWeight;
}
There it is! I missed that completely :oops:, thanks Marco

In the mean time the prototype function evaluate_board_control() was finished and I think it is something that might be usable; it does not throw the evaluation function off and seems to lead to slightly different PVs so that seems to indicate it mainly has a positional effect. Only tested on the same testposition so it does not tell me much maybe. Swami and Dann's new testsuite would seem a good candidate for testing this function.

I promised to post the code when it was finished so here it is :)

Everything was kept as simple as I could imagine it and following the outline of evaluate_space() as an example. No UCI input for the weights yet and therefore no internal weighting is necessary.

Code: Select all

  int WeightBoardControlMidgame  = 0x100;

Code: Select all

  evaluate_board_control(pos, WHITE, ei);
  evaluate_board_control(pos, BLACK, ei);

Code: Select all

 void evaluate_board_control(const Position &pos, Color us, EvalInfo &ei) {

    Color them = opposite_color(us);

    // A square is declared under our control if it is attacked by an own
    // pawn, but not by an enemy pawn, or if it is defended by us 
	 // and not attacked by an enemy piece.

    Bitboard controlledSquares =  ei.attacked_by(us, PAWN)
                               & ~ei.attacked_by(them, PAWN)
                               |(ei.attacked_by(us) & ~ei.attacked_by(them));


    int boardControl =  count_1s_max_15(controlledSquares);
                 
    ei.mgValue += Sign[us] * apply_weight(Value(boardControl), WeightBoardControlMidgame);
  }
Simply using a default 0x100 for WeightBoardControlMidgame gives the following output in Swami's first position, there is a slight instability when the search goes back to Rxc5 but on the whole I was not disappointed with it and I think especially the deep line is interesting. I would need to look at it with other programs and of course the evaluate_board_control() still needs to be tuned.

[d]6k1/p2pp2p/bp4n1/q1r4R/1RP1P3/2P2B2/P2Q2P1/4K3 w - - bm Rd5; c0 "Rd5=10, Rf5=6, g4=7"; id "STS(v4.0) Square Vacancy.001";

6k1/p2pp2p/bp4n1/q1r4R/1RP1P3/2P2B2/P2Q2P1/4K3 w - -

Engine: Ancalagon 1.3 WS180 board control Build 182 (Athlon 2009 MHz, 256 MB)
by Romstad, Costalba, Kiiski, de Groot

2.00 0:00 +1.94 1.Qh6 Rxh5 2.Bxh5 Qxa2 (1.113) 4

2.00 0:00 +2.03 1.Rxc5 Qxc5 2.Qd5+ Qxd5 3.cxd5 (2.995) 12

3.00 0:00 +1.90 1.Rxc5 Qxc5 2.Qd5+ e6 3.Qxc5 bxc5
4.Ra4 (67.202) 195

3.00 0:00 +1.90 1.Rd5 (142.661) 304

3.00 0:00 +1.94 1.Rh3 Rxc4 2.Be2 Rxb4 3.cxb4 Qa4
4.Bxa6 Qxa6 (252.942) 368

4.00 0:00 +1.84 1.Rh3 Rxc4 2.Be2 Rxb4 3.cxb4 (300.598) 400

4.00 0:00 +1.96 1.Rd5 Rxd5 2.exd5 Qc5 3.Qd4 (307.036) 401

5.01 0:01 +2.07 1.Rd5 Rxd5 2.exd5 Qc5 3.Qd4 Qc7 (691.033) 502

6.01 0:01 +2.15 1.Rd5 Rxd5 2.exd5 Qc5 3.Qd4 Qa5
4.Rb2 (924.352) 528

7.01 0:03 +2.29 1.Rd5 Rxd5 2.exd5 Kf7 3.Bd1 Qc5
4.Qd4 Qc7 (2.187.224) 564

8.01 0:08 +2.47 1.Rd5 Rxd5 2.exd5 Bc8 3.Be4 d6 4.Qf2 Qa3
5.Kd2 Qxa2+ 6.Bc2 (5.418.816) 614

9.01 0:26 +2.05 1.Rd5 Rxd5 2.Qxd5+ Qxd5 3.cxd5 Ne5
4.Be2 Bxe2 5.Kxe2 Kf7 6.Rb1 d6
7.Rf1+ Kg6 8.Ke3 (17.094.492) 653


9.04 0:38 +2.21 1.Rxc5 bxc5 2.Rb8+ Kg7 3.Be2 Qc7
4.Re8 Kf7 5.Ra8 Bb7 6.Rxa7 Qg3+
7.Kd1 Bxe4 8.Rxd7 Qxg2 (25.696.506) 662

10.01 1:33 +2.19 1.Rxc5 bxc5 2.Qd5+ Kg7 3.Kd1 Qxa2
4.Qxc5 d6 5.Qd4+ Ne5 6.c5 Qa1+ 7.Kd2 Qa2+
8.Ke3 Qc2 9.cxd6 exd6 10.Qxd6 Qxc3+
11.Kf4 (63.372.044) 681


10.02 1:37 +2.21 1.Rd5 Rxd5 2.Qxd5+ Qxd5 3.exd5 Ne5
4.Be2 Bb7 5.a4 Kg7 6.a5 Ba6 7.axb6 axb6 (66.791.539) 681

11.01 2:59 +2.47 1.Rd5 (119.161.783) 662

12.01 4:06 +2.58 1.Rd5 Rxd5 2.exd5 Bc8 3.Be4 Qc5
4.Qg5 Qd6 5.Qf5 e6 6.Qg5 Qf4 7.Qxf4 Nxf4
8.dxe6 dxe6 (160.783.747) 651

13.01 23:03 +2.50 1.Rd5 Rxd5 2.exd5 Bc8 3.Be4 Qc5
4.Qg5 Qd6 5.Bxg6 Qxg6 6.Qxg6+ hxg6
7.c5 Bb7 8.c4 Ba6 9.cxb6 axb6 (844.270.198) 610

14.01 59:31 +2.47 1.Rd5 Rxd5 2.Qxd5+ Qxd5 3.exd5 Ne5
4.Be2 Bb7 5.a4 Kf7 6.a5 Ba6 7.axb6 axb6
8.Ra4 Bb7 9.Kd2 (2.194.107.027) 614

15.01 210:13 +2.31 1.Rd5 d6 2.Bg4 Rxd5 3.Be6+ Kg7
4.exd5 Qc5 5.Qd4+ Ne5 6.Ra4 Bxc4
7.Rxa7 Qxd4 8.cxd4 Nd3+ 9.Kd2 Kf6
10.Rc7 b5 11.a4 Nf4 12.axb5 Bxb5 (7.610.622.095) 603


Eelco

mcostalba wrote:
The variable spaceWeight is not undefined but is set to zero in the MaterialInfo c'tor through the MaterialInfo::clear() function. So it is always at zero.

It can assume a value different then zero only here:

Code: Select all

  // Compute the space weight
  if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >=
      2*QueenValueMidgame + 4*RookValueMidgame + 2*KnightValueMidgame)
  {
      int minorPieceCount =  pos.piece_count(WHITE, KNIGHT)
                           + pos.piece_count(BLACK, KNIGHT)
                           + pos.piece_count(WHITE, BISHOP)
                           + pos.piece_count(BLACK, BISHOP);

      mi->spaceWeight = minorPieceCount * minorPieceCount;
  }
But from the if () condition you see that you need a good chunk of material to change the value of spaceWeight to something different then zero.

So if you have tested in a endgame or almost endgame position you should have not triggered this code.

If you test using starting position you will see that spaceWeight become bigger then zero.