I started to code all sorts of different scenarios where you wouldn't want to trash a copper (like when you have $5 for a Duchy, but only late in the game when you're in Duchy mode) and it was getting really complicated. Then I found coinLossMargin and reduced many lines of code to a single expression. This significantly improves the BM Masquerade bot on Dominiate (buy rules were taken from Geronimoo's BM Masquerade bot).
# Big Money Masquerade bot.
#
# The bot plays a typical BM strategy with some intelligence on when to trash coppers.
# Basically, if there is an important buy available that needs every copper in hand,
# it passes on the trash ability.
{
name: 'BM Masquerade'
requires: ['Masquerade']
author: 'vandergus'
gainPriority: (state, my) ->
[
"Province"
"Duchy" if state.countInSupply("Province") <= 4
"Estate" if state.countInSupply("Province") <= 2
"Gold"
"Duchy" if state.countInSupply("Province") <= 5
"Masquerade" if my.countInDeck("Masquerade") < 1
"Silver"
]
trashPriority: (state, my) -> [
"Curse"
"Estate" if state.gainsToEndGame() > 4
"Copper" if this.coinLossMargin(state) > 0
"Potion" if my.turnsTaken >= 10
"Estate" if state.gainsToEndGame() > 2
null
]
}
The only questionable play I saw in the logs was something like this.
== BM Masquerade's turn 11 ==
BM Masquerade plays Masquerade.
BM Masquerade draws 2 cards: [Estate, Province].
BM Masquerade passes Copper.
DoubleJack passes Copper.
BM Masquerade plays Gold.
BM Masquerade plays Gold.
BM Masquerade plays Copper.
BM Masquerade plays Copper.
Buying Province will cause BM Masquerade to lose the game
Coins: 8, Potions: 0, Buys: 1
BM Masquerade buys Duchy.
BM Masquerade draws 5 cards: [Copper, Gold, Gold, Copper, Silver].
The bot wanted to buy a Province so it didn't trash the 8th coin. But then ended up buying a Duchy instead because a Province would've ended in a loss. This seems like a rather small corner case.
Not sure about the null choice turning mandatory trashes into optional trashes. But in the above case, the Masquerade bot still passes a copper when, according to the trash priority list, it wouldn't if it didn't have to.