Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions basicAI.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{c} = require './cards' if exports?

Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1

# The Basic AI
# ------------
# This class defines a rule-based AI of the kind that is popular
Expand Down Expand Up @@ -100,7 +102,7 @@ class BasicAI
if value > bestValue
bestValue = value
bestChoice = choice

# If we got a valid choice, return it.
if bestChoice in choices
return bestChoice
Expand Down Expand Up @@ -1149,10 +1151,20 @@ class BasicAI

# `wantsToTrash` returns the number of cards in hand that we would trash
# for no benefit.
wantsToTrash: (state) ->
# `skipCardName let you specify a card to ignore. In general
# this will be the card causing the trashing in the first place, and is
# needed in ai_playValue (since the card has not been played yet) but
# not in playEffect (where the card will no longer be in the bot's hand)
wantsToTrash: (state, skipCardName=null) ->
my = this.myPlayer(state)
trashableCards = 0
for card in my.hand
if skipCardName?
adjusted_hand = my.hand.slice 0
adjusted_hand.remove(c[skipCardName])
else
adjust_hand = my.hand # No need to copy

for card in adjusted_hand
if this.chooseTrash(state, [card, null]) is card
trashableCards += 1
return trashableCards
Expand Down
43 changes: 31 additions & 12 deletions cards.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,7 @@ makeCard 'Upgrade', c.Remodel, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, 'Upgrade')
if wantsToTrash >= multiplier
490
else
Expand All @@ -1045,7 +1045,7 @@ makeCard 'Remake', c.Remodel, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Remake")
if wantsToTrash >= multiplier*2
178
else
Expand Down Expand Up @@ -1191,13 +1191,13 @@ makeCard 'Ambassador', attack, {
state.log("...but #{cardName} is not in the Supply.")

ai_playValue: (state, my) ->
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Ambassador")
if wantsToTrash > 0
150
else
-20
ai_multipliedValue: (state, my) ->
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Ambassador")
if my.actions > 0 and wantsToTrash > 0
1100
else
Expand Down Expand Up @@ -2079,7 +2079,7 @@ makeCard 'Chapel', action, {
state.allowTrash(state.current, 4)

ai_playValue: (state, my) ->
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Chapel")
if wantsToTrash > 0
146
else
Expand Down Expand Up @@ -2769,7 +2769,7 @@ makeCard "Lookout", action, {
state.current.setAside = []

ai_playValue: (state, my) ->
if state.gainsToEndGame >= 5 or state.cardInfo.Curse in my.draw
if state.gainsToEndGame() >= 5 or state.cardInfo.Curse in my.draw
895
else
-5
Expand Down Expand Up @@ -2892,7 +2892,7 @@ makeCard "Mint", action, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state) # Does this statement have any effect?
if my.ai.choose('mint', state, my.hand)
140
else
Expand Down Expand Up @@ -3414,7 +3414,7 @@ makeCard "Trade Route", action, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Trade Route")
if wantsToTrash >= multiplier
160
else
Expand All @@ -3439,7 +3439,7 @@ makeCard "Trader", action, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Trader")
if wantsToTrash >= multiplier
142
else
Expand All @@ -3455,7 +3455,7 @@ makeCard "Trading Post", action, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
wantsToTrash = my.ai.wantsToTrash(state, "Trading Post")
if wantsToTrash >= multiplier*2
148
else
Expand All @@ -3480,8 +3480,8 @@ makeCard "Transmute", action, {

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state)
if my.ai.choose('mint', state, my.hand)
wantsToTrash = my.ai.wantsToTrash(state) # Does this statement have any effect?
if my.ai.choose('mint', state, my.hand) # What is 'mint' doing here?
106
else
-27
Expand Down Expand Up @@ -3698,6 +3698,25 @@ makeCard 'Workshop', action, {
ai_playValue: (state, my) -> 112
}

makeCard 'Forager', action, {
cost: 3
buys: 1
actions: 1

playEffect: (state) ->
state.requireTrash(state.current, 1)
state.current.coins += Set(card for card in state.trash\
when card.isTreasure).size

ai_playValue: (state, my) ->
multiplier = my.getMultiplier()
wantsToTrash = my.ai.wantsToTrash(state, 'Forager')
if wantsToTrash >= multiplier
489 # One less than Upgrade
else
-25
}

# Utility functions
# -----------------

Expand Down