SEE and MVV/LVA

Discussion of chess software programming and technical issues.

Moderator: Ras

laurietunnicliffe
Posts: 23
Joined: Wed Nov 17, 2021 1:19 am
Full name: Laurie Tunnicliffe

SEE and MVV/LVA

Post by laurietunnicliffe »

Hey folks,

If I only have MVV/LVA and NO SEE, can I work out the bad capturess ?so that I can do killers before them.
User avatar
Bo Persson
Posts: 259
Joined: Sat Mar 11, 2006 8:31 am
Location: Malmö, Sweden
Full name: Bo Persson

Re: SEE and MVV/LVA

Post by Bo Persson »

laurietunnicliffe wrote: Sun May 07, 2023 7:59 am Hey folks,

If I only have MVV/LVA and NO SEE, can I work out the bad capturess ?so that I can do killers before them.
Yes, only with less precision. Just save QxP and similar for later.

You will have to set the line somewhere, without knowing exactly where you are.
laurietunnicliffe
Posts: 23
Joined: Wed Nov 17, 2021 1:19 am
Full name: Laurie Tunnicliffe

Re: SEE and MVV/LVA

Post by laurietunnicliffe »

But QxR could be good if the rook is not protected. ???
JoAnnP38
Posts: 253
Joined: Mon Aug 26, 2019 4:34 pm
Location: Clearwater, Florida USA
Full name: JoAnn Peeler

Re: SEE and MVV/LVA

Post by JoAnnP38 »

Until I had implemented a SEE, I treated all captures the same except they were sorted by the MVV/LVA method. At least all of them are potentially forcing which typically can quickly lead to better or worse positions. If there is any chance that the capture move could be pruned because it falls later in the move order, I definitely would not try to assume anything.
User avatar
hgm
Posts: 28354
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: SEE and MVV/LVA

Post by hgm »

Postponing HxL captures without knowing whether the victim is protected never did me any good.

I did often use BLIND instead of SEE; this postpones HxL captures of protected pieces, without worrying about how the remainder of the exchange would go. That worked pretty well; I guess the major benefit of SEE is to recognize the unprotected case.

Of course that still leaves the problem of how to know whether a victim is protected. Normally you would generate only moves for the side to move. This could detect which of your own pieces are protected as a cheap side effect, but doesn't tell you anything about the opponen't pieces. One could argue that the need to evaluate mobility would require you to generate opponent moves anyway, but in most nodes you would be so far below alpha that there is no need to calculate small evaluation terms like mobility to be sure you won't have a stand-pat cutoff.

One trick I tried is to allow the search to abort a node, returning a special code outside the valid score range to make the parent reschedule the search of that move to a later stage. This could be used in HxL cases, by aborting the daughter if move generation there discovers a recapture to the same square. E.g. you could pass the to-square of a HxL capture as an extra parameter to Search(), and abort when a move captures there. When the re-search of that moves come up later, you pass an invalid square for that parameter, so that no abort can occur.

Disadvantage is that you would have to generate moves a second time when you re-search. This could be prevented by not storing move lists in the local variables of the node itself, but in the variables of the parent, so it only gets discarded when the parent returns. The re-search could then use the move list it already generated in the original (aborted) search. This is useful for other re-searches too (e.g. for PVS or LMR). It doesn't help for moves that you would want to prune, though.

An approximate method is to use the 'protected' status from the parent, which could have been calculated as a nearly free side effect of the move generation there. This would err in cases where the move leading to the current node would have changed the protection. Especially in large chess variants this is unlikely to happen, as a move only affects a small fraction of the board there. Note that when your reference case is pure MVV-LVA, unjustly classifying a victim as 'unprotected' doesn't hurt any (it would remain in the MVV-LVA ordering), but unjustly classifying it as 'protected' would postpone a potentially easy beta cutoff.

So you could try to beef up the accuracy by recognizing cases where a piece would lose its protection by the move leading to the node. If you don't only keep track of whether a piece is protected, but also which piece(s) protected it, e.g. as a bitmap for each victim where each bit corresponds to a specific attacker, you can cheaply recognize cases where an single protector abandoned the piece, and assume that this would leave the piece unprotected. This is not 100% accurate, as the move could have discovered a new (formerly x-ray) protector. But this is very rare even in orthodox chess.

So building an 'attack map' during move generation on friendly pieces, and using that after masking away the last-moved piece in the daughter to determine if a victim is protected, would be a comparatively cheap way for detecting unprotected pieces. Note that the attack map on enemy pieces could come in very handy in the node itself, as it could be used for staged move generation in MVV order.