In your search, it is also mostly bad to include things such as "if my position contains such and so, then do this", because these things are too general. If you include those, you could actually make blatantly wrong decisions.
The one thing you can do, for example, is include some rule of thumbs in your evaluation function:
- If ahead at least X points, then give a higher bonus with less material on the board (causes engine to exchange pieces)
- if behind at least X points, then give a higher bonus with more material on the board (causes engine to keep its pieces)
- If your pawns are still on d2 and e2, don't place a bishop in front of them (I have this in the PSQT: square d2 and e2 are "bad" for pawns to be on, squares d3 and e3 are bad for bishops... but a pawn on d2 is "more bad" than a bishop on d3. Having a pawn on d4 is very good. Thus, the program will play d2-d4 first, before considering Bf1-d3.)
- Don't exchange bishops with knights (bishop @ 325, knight @ 300)
- Give a bonus for the bishop pair
- ... and so on
Personally, I wouldn't take position characteristics into account in the search; I think it's the task of the evaluation to determine if a position is good or not.
Non-quiet position after quiescence...
Moderator: Ras
-
- Posts: 28354
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Non-quiet position after quiescence...
It would be pretty hard to incorporate "if my position contains such and so, then do this" behavior in the search, as it conflicts with the principle that you want to pick the move with the best score. I suppose you could give a bonus to some moves. Implicitly you could do that by adding something to the incrementally updated evaluation that strictly speaking should not have been added to calculate the evaluation change. Then it will affect all leaf nodes of the entire sub-tree. You would get inconsistencies when you hash the score of the nodes in that tree, and probe them in a sub-tree where you did not add the move bonus. But you could of course prevent that by also spoiling the hash key in the sub-tree.
In micro-Max I actually do something like that, and take the inconsistency for granted: I penalize King moves in the middle-game. This makes it avoid being checked in such a way that it would have to move his King, and thus provides an incentive to keep its King safe.
Note that the rules you give need to be a bit more subtle, as for Pawns the opposit applies as to other material: when ahead, trade pieces, but preserve Pawns. When behind, trade Pawns, but preserve pieces. A tapered evaluation can be used to encourage the trading of pieces, by making all endgame values a certain factor larger as the opening values. Then an advantage in material will provide an incentive to advance the game phase by trading pieces. You would have to program the Pawn thing in the evaluation explicitly, as trading those doesn't affect the game phase. In the extreme case of having no or only a single Pawn, you might want to apply huge corrections to the 'naive' evaluation, but even with many Pawns you could scale it more towards zero if you have fewer Pawns. That would encourage the lagging player to destroy your Pawns.
In micro-Max I actually do something like that, and take the inconsistency for granted: I penalize King moves in the middle-game. This makes it avoid being checked in such a way that it would have to move his King, and thus provides an incentive to keep its King safe.
Note that the rules you give need to be a bit more subtle, as for Pawns the opposit applies as to other material: when ahead, trade pieces, but preserve Pawns. When behind, trade Pawns, but preserve pieces. A tapered evaluation can be used to encourage the trading of pieces, by making all endgame values a certain factor larger as the opening values. Then an advantage in material will provide an incentive to advance the game phase by trading pieces. You would have to program the Pawn thing in the evaluation explicitly, as trading those doesn't affect the game phase. In the extreme case of having no or only a single Pawn, you might want to apply huge corrections to the 'naive' evaluation, but even with many Pawns you could scale it more towards zero if you have fewer Pawns. That would encourage the lagging player to destroy your Pawns.
-
- Posts: 1784
- Joined: Wed Jul 03, 2019 4:42 pm
- Location: Netherlands
- Full name: Marcel Vanthoor
Re: Non-quiet position after quiescence...
Yes, that is why I mentioned that it would be very specific information. You conceivably could code something like:
- find all pawn attacks by my opponent
- If one of my pieces is attacked by a pawn, then keep the moves by that piece
- if a piece is not attacked, then remove the piece from the move list
That would make your engine move a piece out of the attack, but it would ALSO miss a mate in one that can be done by a different piece. The fact that the first piece hangs, is irrelevant in that situation, as the game is over. If you steer the search to avoid specific situations (which is certainly possible to do), you will miss possible opportunities.
-
- Posts: 28354
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Non-quiet position after quiescence...
Well, deciding what and what not to prune based on static criteria is normal. It is just a matter what on the average is worth searching and what not. But it only works near the tips of the tree. If you prune irrespective of the depth you will overlook many things. This is why people invented reductions, and especially Late-Move Reductions: you just search unpromising moves less deep than others, but eventually you will search them to any depth. So that you sooner or later always will discover it when they are good after all, and can then undo the reduction. In principle it is all OK to do that based on static criteria.
But a threat extension of the type you describe has never worked for me, since the days computers could only reach 2 or 3 ply brute force. It always made the engine weaker.
Part of the problem is that it is usually costly to even detect the threats. Perhaps it would pay to forbid moves that are not related to solving the threat at d=1, becaus then you gain some time back, rather than just taking extra time. It is the unrelated counter threats that usually cause horizon effect: if you are forked at d=1, you would in principle detect the loss, because you are forced to move, and whatever you move, the opponnet will then capture one of the pieces. But when you can trade a heavier piece somewhere else on the board first, you keep the tempo. Which doesn't solve the fork, but has delayed it to d=0, so that you will ignore it. If unrelated trades where pruned, such delaying tactics would not be possible, and you would feel the pain of the fork. That you would miss mate in one is not very harmful: which fraction of the tree position would offer you the opportunity to mate in 1? You should probably make an exception for obviously winning captures. At least when they gain more than what is at stake. When I can play N x Q or R x unprotected R it would be an excellent cure for a Pawn fork against my B + N. But making threats at other pieces, even checking, is just delaying tactic. The opponent would solve that new threat first, and you would still face the original problem, but would have burned the depth you needed to see it.
But a threat extension of the type you describe has never worked for me, since the days computers could only reach 2 or 3 ply brute force. It always made the engine weaker.
Part of the problem is that it is usually costly to even detect the threats. Perhaps it would pay to forbid moves that are not related to solving the threat at d=1, becaus then you gain some time back, rather than just taking extra time. It is the unrelated counter threats that usually cause horizon effect: if you are forked at d=1, you would in principle detect the loss, because you are forced to move, and whatever you move, the opponnet will then capture one of the pieces. But when you can trade a heavier piece somewhere else on the board first, you keep the tempo. Which doesn't solve the fork, but has delayed it to d=0, so that you will ignore it. If unrelated trades where pruned, such delaying tactics would not be possible, and you would feel the pain of the fork. That you would miss mate in one is not very harmful: which fraction of the tree position would offer you the opportunity to mate in 1? You should probably make an exception for obviously winning captures. At least when they gain more than what is at stake. When I can play N x Q or R x unprotected R it would be an excellent cure for a Pawn fork against my B + N. But making threats at other pieces, even checking, is just delaying tactic. The opponent would solve that new threat first, and you would still face the original problem, but would have burned the depth you needed to see it.