endgame:980


980 restricted_genmove white E4 F4 Q19
#? [F4]





















In this position, GNU Go (as of version 3.7.7) rejects W:F4, mainly because it is considered unsafe. B:E4 does indeed capture F4, but the tactical reading code misses the fact that White can sacrifice this stone and force the capture of the surrounding Black string (after W:F4 B:E4 W:H5 B:G4 W:G3, Black is caught in a ladder)

Gunnar: I agree that black has to fall back. The move is 3 points sente.

The tactical reading code already knows about immediate recaptures (snapbacks), but lacks support for forced (in the sense of the simple_ladder() function in reading.c), non-immediate recaptures like this one.

Leaving aside the rhetorical question of whether such a feature logically belongs to the tactical reading code or not, I quickly made a test (it's quite simple to implement) and got disappointing results. While I managed to get the performance penalty under control (down to an acceptable amount), the change didn't have any positive effect on the regressions besides helping in this particular testcase, and brought up a few issues with connection reading and dragon amalgamation (read 3~4 failures, nothing catastrophic, though still bothersome)

Gunnar: I don't think the tactical reading should concern itself with more complex tactical backlashes than the common snapback.

A less generic way of solving the problem could be to alter the relevant patterns (CE29 and Sente22), by adding s attributes where needed and changing some oplay_attack() constraints to more general ones like oplay_attack_either(). But the move still wouldn't get properly valued because of the safety safeguards at move valuation stage.

A proposal (and a question at the same time): would it make sense to introduce the notion of "known safe move", similar to the "known good attack threats" (see pattern Sente22 and related helper function) ?

Gunnar: Sounds reasonable to me.