Futility pruning, Ext futility pruning and Limited Razoring.

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

jhaglund
Posts: 173
Joined: Sun May 11, 2008 7:43 am

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by jhaglund »

But for chess, no one has found anything that is tractable, because you have to recognize the pattern, and then still do some sort of directed search.
What about a condition statement...

if(current_position == closed)
do attack_pawn_structure;
do increase knight_value;

closed:
check_for_pawn_chains();
count_open_files;
count_semi_open_files;

check_for_pawn_chains() {
if pawns_are_on_squares xyz
if pawns_are_on_squares abc
return true
else
false
}

Coming up with as many conditions, check_for_piece_position_squares is worthy to me.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by bob »

jhaglund wrote:
But for chess, no one has found anything that is tractable, because you have to recognize the pattern, and then still do some sort of directed search.
What about a condition statement...

if(current_position == closed)
do attack_pawn_structure;
do increase knight_value;

closed:
check_for_pawn_chains();
count_open_files;
count_semi_open_files;

check_for_pawn_chains() {
if pawns_are_on_squares xyz
if pawns_are_on_squares abc
return true
else
false
}

Coming up with as many conditions, check_for_piece_position_squares is worthy to me.
"position == closed" is the problem. That's a non-trivial calculation. And it is just the tip of the iceberg for this topic. You can't check against every possible type of pattern, and it is hard to figure out which patters are relevant until you have checked them.
jhaglund
Posts: 173
Joined: Sun May 11, 2008 7:43 am

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by jhaglund »

"position == closed" is the problem. That's a non-trivial calculation. And it is just the tip of the iceberg for this topic. You can't check against every possible type of pattern, and it is hard to figure out which patters are relevant until you have checked them.
That is the whole point. Patterns don't have to be trivial. They can be generalized. You have to check for certain pieces, on certain squares, and flag it as closed. Then do something about it. Starting with basics, and adding to the number of patterns is what would have to be done.

Defining what it means to have a closed position isn"t that hard...

Check for open files and maybe count them to determine true or false.
Check pawn structure.
Increase value of knights for closed positions.
Flag opening book line possibly even...

The only problem I see is that the speed of the search will be a bit slower, if it has to keep checking to see if the position search is closed or any other pattern of pieces on the board.

It doesn't have to be too much different than determining an outpost for a knight, a bad bishop penalty, or even your tropism scaling can be introduced if a certain set of rules occur
jesper_nielsen

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by jesper_nielsen »

jhaglund wrote:
"position == closed" is the problem. That's a non-trivial calculation. And it is just the tip of the iceberg for this topic. You can't check against every possible type of pattern, and it is hard to figure out which patters are relevant until you have checked them.
That is the whole point. Patterns don't have to be trivial. They can be generalized. You have to check for certain pieces, on certain squares, and flag it as closed. Then do something about it. Starting with basics, and adding to the number of patterns is what would have to be done.

Defining what it means to have a closed position isn"t that hard...

Check for open files and maybe count them to determine true or false.
Check pawn structure.
Increase value of knights for closed positions.
Flag opening book line possibly even...

The only problem I see is that the speed of the search will be a bit slower, if it has to keep checking to see if the position search is closed or any other pattern of pieces on the board.

It doesn't have to be too much different than determining an outpost for a knight, a bad bishop penalty, or even your tropism scaling can be introduced if a certain set of rules occur
A perhaps crazy idea I had at one point, was to calculate a set of piece square tables for non pawns for each pawn position. Then store these piece square tables in a pawn hash table.

Since the hit rate for the pawn hash is pretty high, the cost of calculating the tables could be evened out over a search.

So IF (and that is a pretty big IF! :) ) one could look at the pawns only, and assign values for each square as to the value of having a particular piece on it, then the evaluation function becomes a summation of a few piece square tables and the pawn evalaution itself!

Something to try, when I start my new experimental engine! :evil:

There are of course a whole number of issues with this approach, particularly the interaction between pieces.

Kind regards,
Jesper
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by bob »

jhaglund wrote:
"position == closed" is the problem. That's a non-trivial calculation. And it is just the tip of the iceberg for this topic. You can't check against every possible type of pattern, and it is hard to figure out which patters are relevant until you have checked them.
That is the whole point. Patterns don't have to be trivial. They can be generalized. You have to check for certain pieces, on certain squares, and flag it as closed. Then do something about it. Starting with basics, and adding to the number of patterns is what would have to be done.

Defining what it means to have a closed position isn"t that hard...

Check for open files and maybe count them to determine true or false.
Check pawn structure.
Increase value of knights for closed positions.
Flag opening book line possibly even...

The only problem I see is that the speed of the search will be a bit slower, if it has to keep checking to see if the position search is closed or any other pattern of pieces on the board.

It doesn't have to be too much different than determining an outpost for a knight, a bad bishop penalty, or even your tropism scaling can be introduced if a certain set of rules occur
The problem is in the "matching". You first have to figure out which pieces and pawns are critical to the question you are asking, and exclude the rest. This isn't easy. Then you have to do some sort of "fuzzy match" which is much harder. For example,just recognizing the potential for smothered mates in the position I posted needs the following:

1. losing king at h1. Or able to be driven there (which is also hard).

2. g1-a7 diagonal open, at least to the square that contains a friendly queen.

3. knight that can reach f2 to give the first check in the sequence.

4. losing pawns at g2-h2.

5. no enemy pieces attacking f2, or else you have more knights attacking f2 than the opponent has pieces defending it.

6. Enemy rook on its first rank, which will become the piece that "smothers" the king. Or an enemy knight that defends g1 to become the smothering piece.

That is a lot of work to do, just to answer the question "is this a potential smothered mate position?"
User avatar
Greg Strong
Posts: 388
Joined: Sun Dec 21, 2008 6:57 pm
Location: Washington, DC

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by Greg Strong »

jesper_nielsen wrote:A perhaps crazy idea I had at one point, was to calculate a set of piece square tables for non pawns for each pawn position. Then store these piece square tables in a pawn hash table.

Since the hit rate for the pawn hash is pretty high, the cost of calculating the tables could be evened out over a search.

So IF (and that is a pretty big IF! :) ) one could look at the pawns only, and assign values for each square as to the value of having a particular piece on it, then the evaluation function becomes a summation of a few piece square tables and the pawn evalaution itself!

Something to try, when I start my new experimental engine! :evil:

There are of course a whole number of issues with this approach, particularly the interaction between pieces.

Kind regards,
Jesper
Interesting idea, but I see some significant additional cost beyond just filling out the piece-square-tables for each piece type when you get a pawn hash table miss...

For one thing, your pawn hash table entries will be really big, so you might not be able to have a large enough hash table to get a good hit rate.

Also, you lose the ability to have the piece-square-table part of your eval incrementally updated for virtually no cost.
jhaglund
Posts: 173
Joined: Sun May 11, 2008 7:43 am

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by jhaglund »

For example,just recognizing the potential for smothered mates in the position
I don't find using time to look for a smothered mate useful enough at the moment.

I was thinking more of the lines of where a strategy needs to be known if a position/pattern occurs. Not, let's look for a fancy mate that rarely happens.

What about forcing the search to look or just check for forks, pins, skewers only?

Say your Queen is infront of your King.
If Queen on same diagonal or rank as king,
Check if we can find a supported bishop or rook to attack queen to pin.

Check for any attacks on pieces infront of the King for that matter.

That seems easy enough...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by bob »

jhaglund wrote:
For example,just recognizing the potential for smothered mates in the position
I don't find using time to look for a smothered mate useful enough at the moment.

I was thinking more of the lines of where a strategy needs to be known if a position/pattern occurs. Not, let's look for a fancy mate that rarely happens.

What about forcing the search to look or just check for forks, pins, skewers only?

Say your Queen is infront of your King.
If Queen on same diagonal or rank as king,
Check if we can find a supported bishop or rook to attack queen to pin.

Check for any attacks on pieces infront of the King for that matter.

That seems easy enough...
I only took that example because of the position I posted from the Slate/Scherzer paper. There are lots of patterns. Stonewall. Kingside attacks. Minority attacks. Weak squares inviting attack on them, etc. And the patterns are not exact piece placement, but rather are the "fuzzy sum" of several components (number of attackers on a square, number of pieces that can get to square, number of defenders, etc...) Trying to make these general is what leads to the computational complexity I was mentioning...
jhaglund
Posts: 173
Joined: Sun May 11, 2008 7:43 am

Re: RomiChessX64P3k vs Crafty-23.1-win64 learning test under

Post by jhaglund »

I only took that example because of the position I posted from the Slate/Scherzer paper. There are lots of patterns. Stonewall. Kingside attacks. Minority attacks. Weak squares inviting attack on them, etc. And the patterns are not exact piece placement, but rather are the "fuzzy sum" of several components (number of attackers on a square, number of pieces that can get to square, number of defenders, etc...) Trying to make these general is what leads to the computational complexity I was mentioning...
Can/Did you ever try these in Crafty?

Code: Select all

  else {
        if (square == sqflip[side][A7]) {
          if (SetMask(sqflip[side][B6]) & Pawns(enemy)) {
            score_eg -= bishop_trapped;
            score_mg -= bishop_trapped;
          }
          if (square == sqflip[side][H7]) {
        } else if (SetMask(sqflip[side][G6]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
        if (square == sqflip[side][B8]) {
        }else if (SetMask(sqflip[side][C7]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
        if (square == sqflip[side][G8]) {
        }else if (SetMask(sqflip[side][F7]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
        if (square == sqflip[side][A2]) {
        }else if (SetMask(sqflip[side][B3]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
        if (square == sqflip[side][H2]) {
        }else if (SetMask(sqflip[side][G3]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
               if (square == sqflip[side][B1]) {
        }else if (SetMask(sqflip[side][C2]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        }
                if (square == sqflip[side][G1]) {
        }else if (SetMask(sqflip[side][F2]) & Pawns(enemy)) {
          score_eg -= bishop_trapped;
          score_mg -= bishop_trapped;
        } 
            if (square == sqflip[side][A6]) {
        }else if (SetMask(sqflip[side][B5]) & Pawns(enemy)) {
          score_eg -= bishop_trapped / 2;
          score_mg -= bishop_trapped / 2;
        }
           if (square == sqflip[side][H6]) {
        }else if (SetMask(sqflip[side][G5]) & Pawns(enemy)) {
          score_eg -= bishop_trapped / 2;
          score_mg -= bishop_trapped / 2;
        }
                if (square == sqflip[side][A3]) {
        }else if (SetMask(sqflip[side][B4]) & Pawns(enemy)) {
          score_eg -= bishop_trapped / 2;
          score_mg -= bishop_trapped / 2;
        }
                if (square == sqflip[side][H3]) {
        }else if (SetMask(sqflip[side][G4]) & Pawns(enemy)) {
          score_eg -= bishop_trapped / 2;
          score_mg -= bishop_trapped / 2;
        }
        }
      }
    }

Code: Select all

 if (PcOnSq(sqflip[side][B1]) == pieces[side][knight] &&
      PcOnSq(sqflip[side][A1]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
  if (PcOnSq(sqflip[side][G1]) == pieces[side][knight] &&
      PcOnSq(sqflip[side][H1]) == pieces[side][rook])
    score_mg -= undeveloped_piece;

  if (PcOnSq(sqflip[side][B8]) == pieces[side][knight] &&
      PcOnSq(sqflip[side][A8]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
  if (PcOnSq(sqflip[side][G8]) == pieces[side][knight] &&
      PcOnSq(sqflip[side][H8]) == pieces[side][rook])
    score_mg -= undeveloped_piece;   
 
   if (PcOnSq(sqflip[side][C1]) == pieces[side][bishop] &&
      PcOnSq(sqflip[side][A1]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
  if (PcOnSq(sqflip[side][C8]) == pieces[side][bishop] &&
      PcOnSq(sqflip[side][H8]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
    
  if (PcOnSq(sqflip[side][F1]) == pieces[side][bishop] &&
      PcOnSq(sqflip[side][H1]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
  if (PcOnSq(sqflip[side][F8]) == pieces[side][bishop] &&
      PcOnSq(sqflip[side][H8]) == pieces[side][rook])
    score_mg -= undeveloped_piece;
// remove knight_outpost code

Code: Select all

 // */   if (!(mask_no_pattacks[enemy][square] & Pawns(enemy))) {
  //    if (knight_outpost[side][square]) {
  //      score_eg += knight_outpost[side][square];
   //     score_mg += knight_outpost[side][square];
  //      if (knight_outpost[side][square] &&
  //          pawn_attacks[enemy][square] & Pawns(side)) {
  //        score_eg += knight_outpost[side][square] / 2;
   //       score_mg += knight_outpost[side][square] / 2;
   //       if (!Knights(enemy) && !(Color(square) & Bishops(enemy))) {
   //         score_eg += knight_outpost[side][square];
   //         score_mg += knight_outpost[side][square];
  //        }
  //      }
  //    }
  //  }
//remove the use of:

Code: Select all

//extern int qval[2][2][64];
User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Futility pruning, Ext futility pruning and Limited Razor

Post by Don »

Michael,

What is your book learning idea? When you lose a game you give every move you played a slight bonus and when you win you give it a slight penalty? And you record all move played in all game?

Do you give the same bonus and penalty? It seems like you have what is called the credit assignment problem and one method used here is to give higher bonus or penalty to later moves. Do you do something like that?


Michael Sherwin wrote:
jwes wrote:
metax wrote:
bob wrote:The change to null-move suggested by Cleveland was another 5-10.
Which change?
Not doing null-move when the depth remaining is 1.
Just one more example of something that I have posted about years ago, that has been in RomiChess for years and that has been migrated to Crafty and other engins. And everyone else gets the credit for it.

I posted that history tables were useless for move ordering shortly after RomiChess was first released. Later they were dropped from Crafty.

I posted that IID is of no benefit. Later it was removed from Crafty.

I posted way before Bob that LMR as done in Fruit did not add to Fruits strength. I was pooh poohed.

There were a few other things that made it into Crafty or was dropped from Crafty sometimes years after I had posted about them. If I had the time I would go back through all my post and catalog them.

I posted many times that various ideas were left in engines just because they did not seem to hurt. Much later Bob post the same conclusion.

Yet Bob posted once at the old winboard site that he did not believe that there was any possibility that there was anything of value that he could learn from me concerning chess programming. :roll:

But that is just how the world works!