def main(): chosenCards = random.sample([ Chancellor.Chancellor(), Council_room.Council_room(), Feast.Feast(), Festival.Festival(), Laboratory.Laboratory(), Market.Market(), Mine.Mine(), Moneylender.Moneylender(), Remodel.Remodel(), Smithy.Smithy(), Throne_room.Throne_room(), Village.Village(), Woodcutter.Woodcutter(), Workshop.Workshop() ], 10) stacks = CardCounts(zip(chosenCards, [10] * len(chosenCards))) stacks[Copper.Copper()] = 60 stacks[Silver.Silver()] = 40 stacks[Gold.Gold()] = 30 stacks[Estate.Estate()] = 24 stacks[Duchy.Duchy()] = 12 stacks[Province.Province()] = 12 startDeck = CardCounts({Copper.Copper(): 7, Estate.Estate(): 3}) NUMPLAYERS = 1 stacks -= startDeck * NUMPLAYERS players = [GUMDRP(stacks, (0, 5, 1, 0, 3), (1, -1, 2))] #players = [Simple_Player()] play(stacks, startDeck, players)
def generateMiniDeck(stacks, cards, params, deckSize=13, reps=2, turns=5): best = (-1, -1, None) t = 0 initCards = itertools.combinations_with_replacement([ c for c in cards if c.cost < 5 and c != Copper.Copper() and c != Estate.Estate() ], deckSize - 10) for cs in initCards: deck = CardCounts({Copper.Copper(): 7, Estate.Estate(): 3}) for c in cs: deck[c] += 1 player = GeneticDeckHelper(params) aquireFilter = lambda c: c.cost >= 5 deckVal = sum([ sum( evalDeck(player, stacks, deck, trials=turns, coinsPerBuy=6, aquireFilter=aquireFilter)) for i in xrange(reps) ]) best = max(best, (deckVal, t, deck)) t += 1 return best[2] '''
def revealCard(self, stop=False, keep=(lambda x: True)): tempCards = CardCounts() tempHand = CardCounts() while not stop: if not self.deck: if not self.discard: break else: self.discardToDeck() card = random.choice(self.deck.keys()) if keep(card): tempHand[card] += 1 else: tempCards[card] += 1 yield card self.discard += tempCards self.hand += tempHand
def setup(cards, initialDeck, players): state = GameState() state.players = players state.pcards = [PlayerCards(deck=initialDeck) for p in players] for c in state.pcards: c.draw(5) state.abcs = [{'actions': 0, 'buys': 0, 'coins': 0} for p in players] state.stacks = cards state.turn = 0 state.trash = CardCounts() return state
def handCardSet(gameState, number='ALL', filtered=None): hand = gameState.pcards[gameState.turn].hand if filtered: hand = CardCounts({k: hand[k] for k in hand if filtered(k)}) handCards = itertools.chain.from_iterable( (itertools.repeat(c, hand[c]) for c in hand)) if number == 'ALL': return set( itertools.chain.from_iterable([ itertools.combinations(handCards, i) for i in range(hand.size + 1) ])) else: return set(itertools.combinations(handCards, number))
def play(self): sys.stdout.write('Iterating') startDeck = CardCounts({Copper.Copper(): 7, Estate.Estate(): 3}) for chrm in self.chromosomes: sys.stdout.write('.') sys.stdout.flush() if chrm.gamesPlayed == self.times_to_play: continue who_to_play = filter( (lambda x: x.gamesPlayed < self.times_to_play), self.chromosomes) tourn = random.sample(who_to_play, 2) tourn.insert(0, chrm) gameType = random.choice(self.games) players = [] for player in tourn: players.append(GUMDRP(gameType[1], *player.genes)) gs = GameState.setup(gameType[0], startDeck, players) numPlayers = len(gs.players) numDepleted = 0 numMoves = 0 while (gs.stacks[Province.Province()] != 0) and numDepleted < 3 and not self.suboptimalDeck( gs, gameType[1]) and numMoves < 80: curPlayer = gs.players[gs.turn] gs.abcs[gs.turn] = {'actions': 1, 'buys': 1, 'coins': 0} gs = curPlayer.playActionPhase(gs) bought = gs.stacks.copy() gs = curPlayer.playBuyPhase(gs) gs = curPlayer.playDiscardPhase(gs) gs.turn = (gs.turn + 1) % numPlayers numDepleted = len( filter(lambda c: gs.stacks[c] == 0, gs.stacks)) numMoves += 1 cards_left = [((gameType[1] - gs.pcards[i].allCards()).count, i) for i in xrange(numPlayers)] cards_left.sort() for people in cards_left: tourn[people[1]].incr(people[0]) print ''
def main(): cards = [ Chancellor.Chancellor(), Council_room.Council_room(), Feast.Feast(), Festival.Festival(), Laboratory.Laboratory(), Market.Market(), Mine.Mine(), Moneylender.Moneylender(), Remodel.Remodel(), Smithy.Smithy(), Throne_room.Throne_room(), Village.Village(), Woodcutter.Woodcutter(), Workshop.Workshop() ] cards = [Estate.Estate(), Copper.Copper(), Silver.Silver(), Gold.Gold()] + random.sample(cards, 10) stacks = CardCounts(zip(cards, [20] * len(cards))) stacks[Province.Province()] = 20 params = ( 0, 5, 1, 0, 3 ) #[35, -2, -10, -17, 45], [27,-19,-3,-5,100], [73, 28, -3, 42, -20] print[c.name for c in cards[4:]] goalD = generateGoalDeck(stacks, cards, params, reps=1, deckSize=17) print sum([ evalDeck(GeneticDeckHelper(params), stacks, goalD)[0] for xx in xrange(5) ]) / 5., goalD miniD = generateMiniDeck(stacks, cards, params, reps=1) print sum([ sum(evalDeck(GeneticDeckHelper(params), stacks, miniD)) for xx in xrange(5) ]) / 5., miniD '''
def discardToDeck(self): self.deck += self.discard self.discard = CardCounts()
def __init__(self, deck=CardCounts(), discard=CardCounts(), hand=CardCounts(), currInPlay=CardCounts()): self.deck = CardCounts(deck) self.discard = CardCounts(discard) self.hand = CardCounts(hand) self.currInPlay = CardCounts(currInPlay)
def getDeck(cards, probs, size): nums = array([int(round(p)) for p in probs * size]) deck = CardCounts(zip(cards, nums)) return deck - deck * 0
def deckToDiscard(self): self.discard += self.deck self.deck = CardCounts()
def discardHand(self): self.discard += self.hand self.hand = CardCounts()
class PlayerCards(object): ''' A deck is a tuple/list of a CardCounts of cards, number of cards. The discard, hand and currentlyInPlay also share a similar structure ''' def __init__(self, deck=CardCounts(), discard=CardCounts(), hand=CardCounts(), currInPlay=CardCounts()): self.deck = CardCounts(deck) self.discard = CardCounts(discard) self.hand = CardCounts(hand) self.currInPlay = CardCounts(currInPlay) ''' This is method that returns all the cards ''' def allCards(self): return self.deck + self.discard + self.hand + self.currInPlay ''' This method returns a copy of self ''' def copy(self): return PlayerCards(deck=self.deck.copy(), discard=self.discard.copy(), hand=self.hand.copy(), currInPlay=self.currInPlay.copy()) ''' This method simulates the discard phase of the game. ''' def discardPhase(self): self.discardcurrInPlay() self.discardHand() self.draw(5) ''' This method puts the discard pile as the deck ''' def discardToDeck(self): self.deck += self.discard self.discard = CardCounts() ''' This method puts the deck into the discard pile ''' def deckToDiscard(self): self.discard += self.deck self.deck = CardCounts() ''' This method discards the currently in play cards into the discard pile ''' def discardcurrInPlay(self): self.discard += self.currInPlay self.currInPlay = CardCounts() ''' This method discards the hand into the discard pile ''' def discardHand(self): self.discard += self.hand self.hand = CardCounts() ''' This method discards from hand several cards passed in as arguments. ''' def discardFromHand(self, *args): for card in args: if (self.hand[card] > 0): self.discard[card] += 1 self.hand[card] -= 1 ''' This method discards from hand several cards passed in as arguments. ''' def playFromHand(self, *args): for card in args: if (self.hand[card] > 0): self.currInPlay[card] += 1 self.hand[card] -= 1 ''' This method trashes from hand several cards passed in as arguments. Another class should keep track of trashed cards ''' def trashFromHand(self, *args): for card in args: self.hand[card] -= 1 ''' This method allows a player to reveal a card in the deck. This is implemented as a generator so that a player can keep revealing cards until a stop signal has been sent. Keep is a function which states which cards should be revealed and put in hand, and which cards should be discarded ''' def revealCard(self, stop=False, keep=(lambda x: True)): tempCards = CardCounts() tempHand = CardCounts() while not stop: if not self.deck: if not self.discard: break else: self.discardToDeck() card = random.choice(self.deck.keys()) if keep(card): tempHand[card] += 1 else: tempCards[card] += 1 yield card self.discard += tempCards self.hand += tempHand ''' This method allows a person to gain a card ''' def gain(self, card): self.discard[card] += 1 ''' This method draws N cards from the deck. If there are no more cards during the drawing, the discard pile is shuffled and made into the deck. If there are also no more cards in the discard pile, then the drawing is done since there are no more cards to draw ''' def draw(self, N): drawCards = [] if self.deck: drawDeck = reduce(list.__add__, [[c] * self.deck[c] for c in self.deck]) drawCards = random.sample(drawDeck, min(self.deck.count, N)) N -= self.deck.count #In the case that there are no more cards to draw if (N > 0): if self.discard: discardDeck = reduce(list.__add__, [[c] * self.discard[c] for c in self.discard]) drawCards += random.sample(discardDeck, min(self.discard.count, N)) self.discardToDeck() for card in drawCards: self.hand[card] += 1 self.deck[card] -= 1
def discardcurrInPlay(self): self.discard += self.currInPlay self.currInPlay = CardCounts()
def __init__(self): #Parameters for Genetic Algorithm Tournament self.chromosomes = [] self.generations = 0 self.times_to_play = 10 self.population_size = 40 #Parameters for Crossing Genes self.mutate_by = 5 self.mutation_rate = .2 self.breeding_factor = .2 self.crossover_rate = .3 #Cards and Decks to test self.basic_cards = CardCounts({ Copper.Copper(): 49, Silver.Silver(): 40, Gold.Gold(): 30, Estate.Estate(): 15, Duchy.Duchy(): 12, Province.Province(): 12 }) self.gameA = CardCounts({ Market.Market(): 10, Village.Village(): 10, Woodcutter.Woodcutter(): 10, Smithy.Smithy(): 10, Laboratory.Laboratory(): 10, Festival.Festival(): 10, Council_room.Council_room(): 10, Mine.Mine(): 10, Feast.Feast(): 10, Chancellor.Chancellor(): 10 }) + self.basic_cards self.goal_deckA = CardCounts({ Gold.Gold(): 4, Silver.Silver(): 2, Village.Village(): 3, Market.Market(): 2, Festival.Festival(): 4, Laboratory.Laboratory(): 4, Woodcutter.Woodcutter(): 1 }) self.gameB = CardCounts({ Throne_room.Throne_room(): 10, Remodel.Remodel(): 10, Mine.Mine(): 10, Workshop.Workshop(): 10, Feast.Feast(): 10, Festival.Festival(): 10, Market.Market(): 10, Smithy.Smithy(): 10, Moneylender.Moneylender(): 10, Chancellor.Chancellor(): 10 }) + self.basic_cards self.goal_deckB = CardCounts({ Gold.Gold(): 4, Throne_room.Throne_room(): 1, Smithy.Smithy(): 2, Festival.Festival(): 3, Mine.Mine(): 1, Market.Market(): 3, Remodel.Remodel(): 1 }) self.gameC = CardCounts() + self.basic_cards self.goal_deckC = CardCounts() self.games = [[self.gameA, self.goal_deckA], [self.gameB, self.goal_deckB], [self.gameC, self.goal_deckC]]
class PlayerCards(object): ''' A deck is a tuple/list of a CardCounts of cards, number of cards. The discard, hand and currentlyInPlay also share a similar structure ''' def __init__(self, deck=CardCounts(), discard=CardCounts(), hand=CardCounts(), currInPlay=CardCounts()): self.deck = CardCounts(deck) self.discard = CardCounts(discard) self.hand = CardCounts(hand) self.currInPlay = CardCounts(currInPlay) ''' This is method that returns all the cards ''' def allCards(self): return self.deck + self.discard + self.hand + self.currInPlay ''' This method returns a copy of self ''' def copy(self): return PlayerCards(deck=self.deck.copy(), discard=self.discard.copy(), hand=self.hand.copy(), currInPlay=self.currInPlay.copy()) ''' This method simulates the discard phase of the game. ''' def discardPhase(self): self.discardcurrInPlay() self.discardHand() self.draw(5) ''' This method puts the discard pile as the deck ''' def discardToDeck(self): self.deck += self.discard self.discard = CardCounts() ''' This method puts the deck into the discard pile ''' def deckToDiscard(self): self.discard += self.deck self.deck = CardCounts() ''' This method discards the currently in play cards into the discard pile ''' def discardcurrInPlay(self): self.discard += self.currInPlay self.currInPlay = CardCounts() ''' This method discards the hand into the discard pile ''' def discardHand(self): self.discard += self.hand self.hand = CardCounts() ''' This method discards from hand several cards passed in as arguments. ''' def discardFromHand(self,*args): for card in args: if (self.hand[card] > 0): self.discard[card] += 1 self.hand[card] -= 1 ''' This method discards from hand several cards passed in as arguments. ''' def playFromHand(self,*args): for card in args: if (self.hand[card] > 0): self.currInPlay[card] += 1 self.hand[card] -= 1 ''' This method trashes from hand several cards passed in as arguments. Another class should keep track of trashed cards ''' def trashFromHand(self, *args): for card in args: self.hand[card] -= 1 ''' This method allows a player to reveal a card in the deck. This is implemented as a generator so that a player can keep revealing cards until a stop signal has been sent. Keep is a function which states which cards should be revealed and put in hand, and which cards should be discarded ''' def revealCard(self, stop=False, keep=(lambda x : True)): tempCards = CardCounts() tempHand = CardCounts() while not stop: if not self.deck: if not self.discard: break else: self.discardToDeck() card = random.choice(self.deck.keys()) if keep(card): tempHand[card] += 1 else: tempCards[card] += 1 yield card self.discard += tempCards self.hand += tempHand ''' This method allows a person to gain a card ''' def gain(self, card): self.discard[card] += 1 ''' This method draws N cards from the deck. If there are no more cards during the drawing, the discard pile is shuffled and made into the deck. If there are also no more cards in the discard pile, then the drawing is done since there are no more cards to draw ''' def draw(self, N): drawCards = [] if self.deck: drawDeck = reduce(list.__add__, [[c]*self.deck[c] for c in self.deck]) drawCards = random.sample(drawDeck, min(self.deck.count, N)) N -= self.deck.count #In the case that there are no more cards to draw if (N > 0): if self.discard: discardDeck = reduce(list.__add__, [[c]*self.discard[c] for c in self.discard]) drawCards += random.sample(discardDeck, min(self.discard.count, N)) self.discardToDeck() for card in drawCards: self.hand[card] += 1 self.deck[card] -= 1