       state.current.coins += 1
     if gained.isVictory
       state.current.drawCards(1)
-}
-
-makeCard 'Jester', action, {
-  cost: 5
-  coins: +2
-  isAttack: true
-
-  playEffect: (state) ->
-    state.log("#{state.current.ai} gets +$2")
-    state.attackOpponents (opp) ->
-      card = state.discardFromDeck(opp, 1)[0]
-      if card.isVictory
-        state.gainCard(opp, c.Curse)
-      else if state.current.ai.chooseGain(state, [card, null])
-        state.gainCard(state.current, card)
-      else
-        state.gainCard(opp, card)
 }
 
 makeCard 'Library', action, {

    cost
}

makeCard 'Pirate Ship', action, {
  cost: 4
  isAttack: true

  playEffect: (state) ->
    choice = state.current.ai.choose('pirateShip', state, ['coins', 'attack'])

    if choice is 'coins'
      state.current.coins += state.current.mats.pirateShip
      state.log("...getting +$#{state.current.mats.pirateShip}.")
    
    else if choice is 'attack'
      state.log("...attacking the other players.")
      attackSuccess = false

      state.attackOpponents (opp) ->
        drawn = opp.getCardsFromDeck(2)
        state.log("...#{opp.ai} reveals #{drawn}.")
        drawnTreasures = []
        for card in drawn
          if card.isTreasure
            drawnTreasures.push(card)
        treasureToTrash = state.current.ai.choose('trashOppTreasure', state, drawnTreasures)
        if treasureToTrash
          attackSuccess = true
          drawn.remove(treasureToTrash)
          state.log("...#{state.current.ai} trashes #{opp.ai}'s #{treasureToTrash}.")
        state.current.discard = state.current.discard.concat(drawn)
        state.log("...#{opp.ai} discards #{drawn}.")
        
      if attackSuccess
        state.current.mats.pirateShip += 1
        state.log("...#{state.current.ai} takes a Coin token (#{state.current.mats.pirateShip} on the mat).")
}

makeCard 'Saboteur', action, {
  cost: 5
  isAttack: true

  upgradeFilter: (state, oldCard, newCard) ->
    [coins1, potions1] = oldCard.getCost(state)
    [coins2, potions2] = newCard.getCost(state)
    return (potions1 >= potions2) and (coins1-2 >= coins2)

  playEffect: (state) ->
    state.attackOpponents (opp) ->
      cardsDrawn = 0;
      while cardsDrawn < 1
        drawn = opp.getCardsFromDeck(1)
        if drawn.length == 0
          if opp.setAside.length > 0
            state.log("#{opp.ai} reveals #{opp.setAside}, but has no cards costing $3 or more in the deck.")
          else
            state.log("#{opp.ai} has no more cards in the deck.")
          break
        card = drawn[0]
        cardCoinCost = card.getCost(state)[0]
        if cardCoinCost >= 3
          state.log("...#{opp.ai} reveals #{opp.setAside}, and #{card}.")
          cardsDrawn++
          choices = upgradeChoices(state, drawn, c.Saboteur.upgradeFilter)
          choices.push([card,null])
          choice = opp.ai.choose('upgrade', state, choices)
          drawn.remove(card)
          state.log("...#{state.current.ai} trashes #{opp.ai}'s #{card}.")
          if choice[1] isnt null
            [oldCard, newCard] = choice
            state.gainCard(opp, newCard, 'discard', true)
            state.log("...#{opp.ai} gains #{newCard}.")
          else
            state.log("...#{opp.ai} gains nothing.")
        else
          opp.setAside.push(card)
      if opp.setAside.length > 0
        state.log("...#{opp.ai} discards #{opp.setAside}.")
      opp.discard = opp.discard.concat(opp.setAside)
      opp.setAside = []  
}

makeCard 'Scout', action, {
  cost: 4
  actions: +1

      state.current.setAside = []
}

makeCard 'Shanty Town', action, {
  cost: 3
  actions: +2
