Permalink
Browse files

Merge pull request #60 from bilts/scheme

Implement Scheme
  • Loading branch information...
2 parents c4e034b + 04bb12d commit 423e2174bfa5baf0634dc42fd5990daa8b3b8c3f @rspeer committed Jan 20, 2012
Showing with 50 additions and 3 deletions.
  1. +15 −0 basicAI.coffee
  2. +13 −0 cards.coffee
  3. +7 −3 gameState.coffee
  4. +15 −0 strategies/SchemeWitch.coffee
View
@@ -272,6 +272,7 @@ class BasicAI
"Conspirator" if my.inPlay.length >= 2 or multiplier > 1
"Familiar"
"Highway"
+ "Scheme"
"Wishing Well"
"Great Hall" if state.cardInfo.Crossroads not in my.hand
"Spice Merchant" if state.cardInfo.Copper in my.hand
@@ -455,6 +456,7 @@ class BasicAI
"Crossroads" if (not my.crossroadsPlayed) or (my.actions > 0)
"Torturer" if my.actions > 0 and state.countInSupply("Curse") >= 2
"Young Witch" if my.actions > 0 and state.countInSupply("Curse") >= 2
+ "Scheme" if my.countInDeck("King's Court") >= 2
"Scrying Pool"
"Wharf" if my.actions > 0
"Bridge" if my.actions > 0
@@ -881,6 +883,19 @@ class BasicAI
return this.upgradeValue(state, [card, gained], my)
+ # Scheme uses the same priority function as multiplied actions. Good actions
+ # to multiply this turn are typically good actions to have around next turn.
+ schemePriority: (state, my) ->
+ # Project a little of what the state will look like at the beginning of the
+ # next turn. This keeps multipliedActionPriority from evaluating a card
+ # as though it will be used in the current (finished) turn.
+ myNext = {}
+ myNext[key] = value for key, value of my
+ myNext.actions = 1
+ myNext.buys = 1
+ myNext.coins = 0
+ this.multipliedActionPriority(state, myNext)
+
# `scryingPoolDiscardValue` is like `discardValue`, except it strongly
# prefers to discard non-actions.
scryingPoolDiscardValue: (state, card, my) ->
View
@@ -2210,6 +2210,19 @@ makeCard 'Salvager', action, {
state.current.coins += coins
}
+makeCard 'Scheme', action, {
+ cost: 3
+ actions: 1
+ cards: 1
+ cleanupEffect: (state) ->
+ choices = (card for card in state.current.inPlay when card.isAction)
+ choices.push(null)
+ choice = state.current.ai.choose('scheme', state, choices)
+ if choice isnt null
+ state.log("#{state.current.ai} uses Scheme to put #{choice} back on the deck.")
+ transferCardToTop(choice, state.current.inPlay, state.current.draw)
+}
+
makeCard 'Scout', action, {
cost: 4
actions: +1
View
@@ -897,6 +897,13 @@ class State
@current.duration.push(card)
@current.multipliedDurations.splice(i, 1)
+
+ # Handle effects of cleaning up the card, which may involve moving it
+ # somewhere else. We do this before removing cards from play because
+ # cards such as Scheme and Herbalist need to consider cards in play.
+ cardsToCleanup = @current.inPlay.concat()
+ card.onCleanup(this) for card in cardsToCleanup
+
# Clean up cards in play.
while @current.inPlay.length > 0
card = @current.inPlay[0]
@@ -907,9 +914,6 @@ class State
@current.duration.push(card)
else
@current.discard.push(card)
- # Handle effects of cleaning up the card, which may involve moving it
- # somewhere else.
- card.onCleanup(this)
# Discard the remaining cards in hand.
@current.discard = @current.discard.concat(@current.hand)
@@ -0,0 +1,15 @@
+{
+ name: 'SchemeWitch'
+ requires: ['Witch', 'Scheme']
+ gainPriority: (state, my) -> [
+ "Colony" if my.countInDeck("Platinum") > 0
+ "Province" if state.countInSupply("Colony") <= 6 and my.countInDeck("Gold") > 0
+ "Witch" if my.countInDeck("Witch") == 0
+ "Duchy" if 0 < state.gainsToEndGame() <= 5
+ "Estate" if 0 < state.gainsToEndGame() <= 2
+ "Platinum"
+ "Gold"
+ "Scheme" if my.countInDeck('Scheme') < 2 and my.countInDeck('Silver') > 0
+ "Silver"
+ ]
+}

0 comments on commit 423e217

Please sign in to comment.