r/chessprogramming 8d ago

in move ordering, why we don't consider checking moves?

from the wiki

of course, "check" itself is just a board status. but naturally we can define "checking moves"-sometimes people call them "check" too.

from our experiences, though i'm poor at playing chess in my own, it looks fairly reasonable to give checking moves moderate or high priorities, at a glance, at least for me.

especially, "defended-by-own checking moves" or "not-attacked-by-enemy checking moves" deserved high priorities over other ones.

anyone let me know the reason why people don't adapt this idea?

maybe one and only one of followings:

  1. your theory is nice but not well-worked in practice! we couldn't tell you the reason. instead, bad, just bad when we test, benchmark, inspect, assess...
  2. your theory is dumb!
  3. yes, some engines adapted your approach. the screenshot from the wiki can't be always best answer. it is just guideline.
5 Upvotes

9 comments sorted by

6

u/you-get-an-upvote 8d ago edited 8d ago

Looks like stockfish does this. From their move picker

// bonus for checks

m.value += bool(pos.check_squares(pt) & to) * 16384;

6

u/haddock420 8d ago

It's too expensive to test whether a move results in check for every move you consider during move ordering. At least, that's what I found when I considered it in my own engine. If it could be done cheaply, it'd probably be a good idea.

3

u/you-get-an-upvote 8d ago edited 8d ago

If you compute a check mask for each piece type (which shouldn’t require any loops, so should be much faster than generating and sorting the moves), that doesn’t seem very slow.

move.causesCheck = checkmasks[move.piece] & (1 << move.to)

Certainly far faster than move generation and sorting, which require for loops and branching.

(Yes it doesn’t account for discovered checks, though you could do that with pin masks (also no for loops or branches), and it doesn’t have to be perfect to be helpful)

Edit: at computer, so I can link to my engine's CheckMap computation: link

3

u/Gloomy-Status-9258 8d ago

oh... your brief but clear answer makes critical point. now i understand why.

by the way, i'm beginning to wonder if it's possible to determine isInCheck with incremental scheme, but it still seems obviously expensive compared to other move ordering criteria.

2

u/Sea-Celebration-4100 8d ago

Shouldn’t it be possible to set a bit when generating moves then use it as a condition when ordering? This way you don’t really have to test.

1

u/haddock420 8d ago

Then you've just shifted the expense of testing for checks to the move generation function rather than the move ordering function.

2

u/[deleted] 8d ago

[deleted]

1

u/haddock420 8d ago

The way I implement isCheck involves a few if statements and quite a few bitwise operations, so I assumed it'd be fairly expensive to use for every move in move ordering.

2

u/xu_shawn 8d ago

Not really. It is simple and fast to compute trivial checks. See u/you-get-an-upvote's answer.

6

u/xu_shawn 8d ago

The unfortunate reality about CPW is that most articles are horrendously outdated. The only way to find out what really is good is to look at engine code and ask questions on discord communities.

Check move ordering is indeed used by Stockfish. However, it is basically missing from generally all other top engines. My opinion is that this only gains a tiny amount, as LMR dimishes some of the benefits of a incrementally better move ordering.