This one:
{
name: 'Haven + Treasure Map + Cutpurse'
author: 'DStu'
requires: ['Haven', 'Treasure Map', 'Cutpurse']
gainPriority: (state, my) -> [
"Province" if my.countInDeck("Gold") >= 4
"Duchy" if state.gainsToEndGame() <= 4
"Estate" if state.gainsToEndGame() <= 2
"Gold" if my.countInDeck("Gold") > 0
"Treasure Map" if my.countInDeck("Gold") == 0 and my.countInDeck("Treasure Map") < 2
"Cutpurse" if my.countInDeck("Gold") > 0 and my.countInDeck("Cutpurse") <2
"Haven" if my.countInDeck("Gold") == 0
"Silver"
"Haven"
]
actionPriority: (state, my) -> [
"Haven" if my.countInHand("Treasure Map") < 2
"Treasure Map" if my.countInHand("Treasure Map") >= 2
"Cutpurse"
]
putOnDeckPriority: (state, my) ->
cls = my.ai.coinLossMargin(state)
[
"Copper" if my.countInHand("Copper") < 4 and my.countInDeck("Gold")==0 and my.countInDeck("Treasure Map") < 2
"Treasure Map" if my.countInDeck("Treasure Map") >= 2 and my.countInDeck("Gold") == 0 and my.countInHand("Haven")==0 and my.countInHand("Treasure Map") < 2
"Cutpurse" if my.countInHand("Cutpurse") >= 2
"Gold" if cls >= 3
"Siver" if cls >= 2
"Cutpurse" if cls >= 2
"Copper" if cls >= 1
"Treasure Map"
"Province"
"Duchy"
"Estate"
]
}
beats 2 Cutpurses 56:44, and the Haven-play can certainly get some optimization in real life. On the other hand, Cutpurse alone is a quite good counter to Haven+TM, if Haven+TM ignores Cutpurse it loses, while it wins against e.g. Smithy. This is not that surprising, as you rely on these Coppers to get the second TM.
Geronimoo's sim doesn't play the Haven right (does not put sole TMs in Haven), but also with "wrong" Havening it wins by about the same amount, so probably it also does something better than me. Maybe you should take care of if the other TM is in the discard.
Edit: Updated code, some performance and logic improvement for the coinLossMargin, now its 62:38 vs 2 Cutpurses