def test_buy(self): store = Store(2) count = 8 while count > 0: buy_res = store.buy("PROVINCE") count -= 1 self.assertEqual(store.base_inventory["PROVINCE"], count) self.assertEqual(buy_res, "PROVINCE") self.assertEqual(store.buy("PROVINCE"), None) self.assertEqual(store.buy("PROVINCE"), None) self.assertEqual(store.base_inventory["PROVINCE"], 0)
class Game: # default switches is only mid game def __init__(self, switches=(0, 100)): # initialize the starting deck here instead self.deck = Deck() self.turn = 0 self.deck.fullPrint(self.turn) self.earlyBuy = priorityBuy(Card.money_types + ['LABORATORY']) self.midBuy = priorityBuy(Card.money_types + ['LABORATORY'] + ['PROVINCE']) self.lateBuy = priorityBuy(Card.victory_types) self.switches = switches self.store = Store() # self.earlyBuy = priorityBuy(Card.money_types) # self.midBuy = priorityBuy(Card.money_types + ['PROVINCE']) # self.lateBuy = self.midBuy if ASSERTS: assert self.midBuy(1) == '' assert self.earlyBuy(3) == 'SILVER' assert self.earlyBuy(5) == 'LABORATORY' assert self.earlyBuy(6) == 'GOLD' assert self.earlyBuy(8) == 'GOLD' assert self.midBuy(1) == '' assert self.midBuy(3) == 'SILVER' assert self.midBuy(5) == 'LABORATORY' assert self.midBuy(6) == 'GOLD' assert self.midBuy(8) == 'PROVINCE' assert self.lateBuy(1) == '' assert self.lateBuy(3) == 'ESTATE' # assert self.lateBuy(5) == 'DUCHYzz' # test to fail assert self.lateBuy(6) == 'DUCHY' assert self.lateBuy(8) == 'PROVINCE' def buyCardType(self, newCard): """ same as the old self.deck.addCardType(newCard) but ... also remove the corresponding card from the Store if the store buy fails, then will return None, otherwise the card """ if not self.store.buy(newCard): return None return self.deck.addCardType(newCard) # ABC # Action # Buy # Collect def takeTurn(self): return_info = { } # for playing around with events - to get feedback in main self.turn += 1 self.deck.drawHand() self.deck.fullPrint(self.turn) # hand right after drawing it return_info['money'] = self.deck.calcHandMoney() return_info['turn'] = self.turn return_info['vp'] = self.deck.total_vp stats = self.simpleCalcPlay() dp(stats) # self.moneyBuy(stats['money'], True) self.phaseBuys(stats['money'] ) # before turn 8, early game, before turn 10, mid game self.deck.cleanUp() return return_info def takeTurnProv(self): """ take money, and provinces """ money = self.deck.calcHandMoney() result = self.moneyBuyWithStore(money, True) if result != "GAMEOVER": dp("take turn prov END GAME") return result # smart buy - switches is a tuple signaling when to switch strategies # ex - (5, 10) - before turn 5 early game, before turn 10 mid game, then late game (all VPs) # goal - find the optimal constants def phaseBuys(self, money): # init idea # early game - no vps no matter what # mid game - best buy, including provinces # late game - all points if self.turn < self.switches[0]: dp("early") newCard = self.earlyBuy(money) elif self.turn < self.switches[1]: dp("mid") newCard = self.midBuy(money) else: dp("late") newCard = self.lateBuy(money) dp("New Card: " + newCard) # *** multiple buys later self.buyCardType(newCard) # choose what to buy... # if provinces is set to true, buy provinces in addition to silvers and golds def moneyBuy(self, money, provinces=False): # money = self.deck.calcHandMoney() dp("money: " + str(money)) if money >= 8 and provinces: dp("province") self.deck.addCardType('PROVINCE') elif money < 3: dp("no money, no buy") elif money < 6: dp("silver") self.deck.addCardType('SILVER') else: dp("gold") self.deck.addCardType('GOLD') def moneyBuyWithStore(self, money, provinces=False): """ same as the original moneyBuy, but use the store instead of adding the cards directly to the deck """ dp("money: " + str(money)) if money >= 8 and provinces: dp("province") card_type = 'PROVINCE' elif money < 3: dp("no money, no buy") card_type = 'no buy' elif money < 6: dp("silver") card_type = 'SILVER' else: dp("gold") card_type = 'GOLD' return self.buyCardType(card_type) # Calculate and play the entire hand # the simple playing code - play everything possible - random order # *** tbd strat - take into account: being able to play everything, more valuable actions (expensive first?) # use a dictionary to keep track of everything for all cards (not just actions) def simpleCalcPlay(self): # start with one action and one buy and no money stats = {'actions': 1, 'buys': 1, 'money': 0, 'vp': 0} i = 0 while (i < len(self.deck.hand) and (stats['actions'] > 0)): # print("i is " + str(i)) card = self.deck.hand[i] # dp("this card is worth " + str(card.money)) if card.name in Card.action_types: stats['actions'] -= 1 # it's an action card stats = card.play(self.deck, stats) elif card.name in Card.money_types: stats['money'] += card.money else: stats['vp'] += card.vp i += 1 # add a play action for each card later - # *** - dictionary maps card names to the methods themselves... return stats # play takes a strategy function for how to play action cards (basically everything other than the buying def play(self, strat): pass # buy does the buying, also taking a strategy function for the best card(s) to buy def buy(self, strat, *args): strat(args)
class Game: # default switches is only mid game def __init__(self, switches=(0, 100)): # initialize the starting deck here instead self.deck = Deck() self.turn = 0 self.deck.fullPrint(self.turn) self.earlyBuy = priorityBuy(Card.money_types + ['LABORATORY']) self.midBuy = priorityBuy(Card.money_types + ['LABORATORY'] + ['PROVINCE']) self.lateBuy = priorityBuy(Card.victory_types) self.switches = switches self.store = Store() # self.earlyBuy = priorityBuy(Card.money_types) # self.midBuy = priorityBuy(Card.money_types + ['PROVINCE']) # self.lateBuy = self.midBuy if ASSERTS: assert self.midBuy(1) == '' assert self.earlyBuy(3) == 'SILVER' assert self.earlyBuy(5) == 'LABORATORY' assert self.earlyBuy(6) == 'GOLD' assert self.earlyBuy(8) == 'GOLD' assert self.midBuy(1) == '' assert self.midBuy(3) == 'SILVER' assert self.midBuy(5) == 'LABORATORY' assert self.midBuy(6) == 'GOLD' assert self.midBuy(8) == 'PROVINCE' assert self.lateBuy(1) == '' assert self.lateBuy(3) == 'ESTATE' # assert self.lateBuy(5) == 'DUCHYzz' # test to fail assert self.lateBuy(6) == 'DUCHY' assert self.lateBuy(8) == 'PROVINCE' def buyCardType(self, newCard): """ same as the old self.deck.addCardType(newCard) but ... also remove the corresponding card from the Store if the store buy fails, then will return None, otherwise the card """ if not self.store.buy(newCard): return None return self.deck.addCardType(newCard) # ABC # Action # Buy # Collect def takeTurn(self): return_info = {} # for playing around with events - to get feedback in main self.turn += 1 self.deck.drawHand() self.deck.fullPrint(self.turn) # hand right after drawing it return_info['money'] = self.deck.calcHandMoney() return_info['turn'] = self.turn return_info['vp'] = self.deck.total_vp stats = self.simpleCalcPlay() dp(stats) # self.moneyBuy(stats['money'], True) self.phaseBuys(stats['money']) # before turn 8, early game, before turn 10, mid game self.deck.cleanUp() return return_info def takeTurnProv(self): """ take money, and provinces """ money = self.deck.calcHandMoney() result = self.moneyBuyWithStore(money, True) if result != "GAMEOVER": dp("take turn prov END GAME") return result # smart buy - switches is a tuple signaling when to switch strategies # ex - (5, 10) - before turn 5 early game, before turn 10 mid game, then late game (all VPs) # goal - find the optimal constants def phaseBuys(self, money): # init idea # early game - no vps no matter what # mid game - best buy, including provinces # late game - all points if self.turn < self.switches[0]: dp("early") newCard = self.earlyBuy(money) elif self.turn < self.switches[1]: dp("mid") newCard = self.midBuy(money) else: dp("late") newCard = self.lateBuy(money) dp("New Card: " + newCard) # *** multiple buys later self.buyCardType(newCard) # choose what to buy... # if provinces is set to true, buy provinces in addition to silvers and golds def moneyBuy(self, money, provinces=False): # money = self.deck.calcHandMoney() dp("money: " + str(money)) if money >= 8 and provinces: dp("province") self.deck.addCardType('PROVINCE') elif money < 3: dp("no money, no buy") elif money < 6: dp("silver") self.deck.addCardType('SILVER') else: dp("gold") self.deck.addCardType('GOLD') def moneyBuyWithStore(self, money, provinces=False): """ same as the original moneyBuy, but use the store instead of adding the cards directly to the deck """ dp("money: " + str(money)) if money >= 8 and provinces: dp("province") card_type = 'PROVINCE' elif money < 3: dp("no money, no buy") card_type = 'no buy' elif money < 6: dp("silver") card_type = 'SILVER' else: dp("gold") card_type = 'GOLD' return self.buyCardType(card_type) # Calculate and play the entire hand # the simple playing code - play everything possible - random order # *** tbd strat - take into account: being able to play everything, more valuable actions (expensive first?) # use a dictionary to keep track of everything for all cards (not just actions) def simpleCalcPlay(self): # start with one action and one buy and no money stats = {'actions': 1, 'buys': 1, 'money': 0, 'vp': 0} i = 0 while (i < len(self.deck.hand) and (stats['actions'] > 0)): # print("i is " + str(i)) card = self.deck.hand[i] # dp("this card is worth " + str(card.money)) if card.name in Card.action_types: stats['actions'] -= 1 # it's an action card stats = card.play(self.deck, stats) elif card.name in Card.money_types: stats['money'] += card.money else: stats['vp'] += card.vp i += 1 # add a play action for each card later - # *** - dictionary maps card names to the methods themselves... return stats # play takes a strategy function for how to play action cards (basically everything other than the buying def play(self, strat): pass # buy does the buying, also taking a strategy function for the best card(s) to buy def buy(self, strat, *args): strat(args)