def main_market(self, C, player, action=None): if action is not None: self.actions -= 1 cmd, = action if cmd == 'pass': pass elif cmd == 'royal': raise NotImplementedError elif action.obj_type == 'trade': raise stg.Switch('trade', send_action=True) elif action.obj_type == 'sell': raise stg.Switch('sell', send_action=True) elif action.obj_type == 'favor': raise stg.Switch(self.royal_actions[cmd._royal]) if self.actions == 0: raise stg.Switch('prep') raise stg.Decide('action')
def run_auction(self, C, player, action=None): if action is None: self.bids = tdict({p: 0 for p in C.players if p.money == 0}) else: bid, = action self.bids[player] = bid if len(self.bids) == len(C.players): # resolve auction mx, cost = None, None for p, bid in self.bids.items(): C.log.writef('{} bids {}', p, bid) if mx is None or bid > mx: cost = mx mx = bid if cost is None: cost = 0 if mx > 0: self.cost = cost winners = tlist(p for p, bid in self.bids.items() if bid == mx) self.winners = util.sort_by(winners, [p.order for p in winners]) raise stg.Switch('collection') else: C.log.writef('No one bid anything') raise stg.Switch('market') raise stg.Decide('auction')
def update_offer(self, C, player, action): assert_(action is not None, 'trade phase should always have an action') cmd, *rest = action if cmd == 'cancel': C.log[self.player].write('You cancel the trade') C.log.dindent() raise PhaseComplete if self.maritime is not None: num, res = rest self.offer[res] = num self.maritime_msg = num, res raise stg.Switch('maritime') if cmd == 'submit': C.log[self.player].write('Asking other players for response.') self.responses = tdict( {p: None for p in C.players if p != self.player}) self.counter_offers = tdict() for p in self.responses: self.display_trade(C.log[p], self.player, self.offer, self.demand) raise stg.Switch('counter') C.log[player].writef('You {} a {}', cmd, rest[0]) self[cmd][rest[0]] += 1 raise stg.Decide('propose')
def pre_phase(self, C, player, action=None): for p in C.players: if len(p.hand) > 0: raise stg.Switch('ball') raise stg.Switch('market')
def pre(self, C, player, action=None): for p in C.players: if p.money > 0: raise stg.Switch('auction') C.log.writef('No one has any money, so the auction is skipped') raise stg.Switch('market')
def prep_market(self, C, player, action=None): self.active = self._find_next(C.players) if self.active is None: # C.log.write('Market phase complete') raise stg.Switch('cleanup') self.actions = len(self.active.market) self.done.add(self.active) raise stg.Switch('main')
def set_counter(self, C, player, action=None): if action is not None: cmd, *rest = action if cmd == 'reject': del self.responses[player] elif cmd == 'accept': self.responses[player] = 'accept' else: if player not in self.counter_offers: self.counter_offers[player] = tlist( [self.offer.copy(), self.demand.copy()]) res, = rest delta = -1**(cmd == 'demand') self.give(res, delta, *self.counter_offers[player]) # check if some players havent responded yet for r in self.responses.values(): if r is None: raise stg.Switch('commit') raise stg.Decide('counter')
def select_stand(self, C, player, action=None): if action is None: players = tlist(p for p in C.players if len(p.hand)) if len(players) == 0: raise PhaseComplete self.sel = Selection( players, log=C.log, option_fn=lambda p: p.hand, status='You may choose cards for your market stand.') else: stands = self.sel.step(player, action) if stands is not None: for p, stand in stands.items(): if len(stand): self.done = tset() for p, stand in stands.items(): p.market.update(stand) C.log.writef( '{}\'s stand contains: {}', p, ', '.join(str(card) for card in stand)) for card in stand: p.hand.remove(card) card.visible.update(C.players) raise stg.Switch('prep') raise PhaseComplete raise stg.Decide('select')
def init(self, C, player, action=None): C.neutral.reset(self.neutral_num) for p in C.players: p.draw_cards(log=C.log) raise stg.Switch('pre')
def post_phase(self, C, player, action=None): if 'candidates' not in self: self.candidates = tlist( p for p in C.players if satisfies_vic_req(p, C.config.rules.victory_conditions)) if len(self.candidates): raise stg.Switch('claim') raise SwitchPhase('queen')
def set_road_building(self, C, player, action=None): if action is not None: loc, = action if loc == 'cancel': if self.card_info is not None: unbuild(C, self.card_info.building) self.card_info = None self.devcard = None raise stg.Switch('main') if self.card_info is None: bld = build(C, 'road', self.player, loc) self.card_info = bld else: bld = build(C, 'road', self.player, loc) play_dev(self.player, self.devcard) C.log.writef('{} plays {}, and builds: {} and {}', self.player, self.devcard, self.card_info, bld) self.card_info = None raise stg.Switch('main') raise stg.Decide('road-building')
def claim(self, C, player, action=None): if action is None: raise stg.Decide('claim') cmd, = action if cmd == 'yes': C.log.writef('{} claims victory', player) C.state.claim = player raise GameOver self.candidates.remove(player) if len(self.candidates): raise stg.Decide('claim') raise stg.Switch('post')
def run_tax(self, C, player, action=None): if action is not None: card, = action player.hand.remove(card) card.discard() self.taxable[player] -= 1 if self.taxable[player] == 0: del self.taxable[player] if len(self.taxable): raise stg.Decide('tax') raise stg.Switch('market')
def roll_dice(self, C, player, action=None): if action is not None: cmd, = action if cmd != 'continue': self.pre_check = 'played' # can't play another dev card this turn self.devcard = cmd raise SubPhase('robber', player=self.player, knight=cmd) elif 'pre_check' not in self: self.pre_check = 'done' self.devcard = get_knight(self.player.devcards) if self.devcard is not None: # knight available raise stg.Decide('pre-knight', knight=self.devcard) if self.devcard is not None: # coming back from playing a knight if self.devcard in self.player.devcards: # check if knight was actually played self.devcard = None self.roll = roll_dice(C.RNG) if len(C.state.rolls): self.roll = C.state.rolls.pop() # TODO: delay telling other players (info leak, pre-knight) C.log.zindent() C.log.writef('{} rolled: {}.', self.player, self.roll) C.log.iindent() if self.roll == 7: self.set_current_stage( 'main') # when coming back, go straight to main stage raise SubPhase('robber', player=self.player) hexes = C.state.numbers[self.roll] for hex in hexes: if hex != C.state.robber.loc: for c in hex.corners: if 'building' in c and c.building.obj_type in C.state.production: gain = C.state.production[c.building.obj_type] gain_res(hex.res, C.state.bank, c.building.player, gain, C.log) raise stg.Switch('main')
def pre_phase(self, C, player, action=None): # increment herald for p in C.players: p.order += 1 p.order %= len(C.players) if p.order == 0: C.state.herald = p C.log.writef('{} becomes herald', p) # prep tax extra = tdict() for p in C.players: if len(p.hand) > p.hand_limit: extra[p] = len(p.hand) - p.hand_limit self.taxable = extra raise stg.Switch('tax')
def set_year_of_plenty(self, C, player, action=None, res=None): if action is None: self.card_info = res raise stg.Decide('year-plenty') res, = action if res != 'cancel': gain_res(self.card_info, C.state.bank, self.player, 1, log=C.log) gain_res(res, C.state.bank, player, 1, log=C.log) C.log.writef('{} plays {}, and receives: {} and {}', self.player, self.devcard, self.card_info, res) play_dev(self.player, self.devcard) else: self.devcard = None self.card_info = None raise stg.Switch('main')
def run_ball(self, C, player, action=None): if action is None: self.sel = Selection(tlist(p for p in C.players if len(p.hand)), log=C.log, option_fn=lambda p: p.hand, status='You may choose cards to attend the ball.') else: done = self.sel.step(player, action) if done is not None: # run ball ball = tlist(C.state.market) for p, sel in done: p.hand -= sel ball.extend(sel) C.RNG.shuffle(ball) C.log.writef('The ball features: {}'.format(', '.join(map(str, ball)))) C.RNG.shuffle(ball) ball = tset(ball) for p, sel in done: for _ in range(len(sel)): card = ball.pop() card.visible.clear() card.visible.add(p) p.hand.add(card) C.state.market.clear() C.state.market.update(ball) for card in C.state.market: card.visible.update(C.players) raise stg.Switch('market') raise stg.Decide('ball')
def buy_action(self, C, player, action=None): raise stg.Switch('main')
def main_turn(self, C, player, action=None): if action is None: raise stg.Decide('main') # self.null_op(2) # TESTING obj, *rest = action if obj == 'pass': raise SwitchPhase('main') if obj == 'offer' or obj == 'demand': C.log[self.player].write('You start a trade') C.log.iindent() raise SubPhase('trade', send_action=True, player=self.player, bank_trades=bank_trade_options( self.player, C.state.bank_trading) if 'maritime' in action.get_type() else None) obj_type = obj.get_type() if 'build' in action.get_type(): if obj_type == 'settlement': # replace this settlement unbuild(C, obj, silent=False) bld = build(C, 'city', self.player, obj.loc) else: bld = build(C, 'settlement' if obj_type == 'Corner' else 'road', self.player, obj) pay_cost(self.player, C.state.costs[bld.get_type()], C.state.bank) elif obj_type == 'devcard': if obj.name == 'Victory Point': raise Exception('Shouldnt have played a Victory point card') elif obj.name == 'Knight': raise SubPhase('robber', send_action=False, knight=obj, player=self.player) elif obj.name == 'Monopoly': res, = rest for opp in C.players.values(): if opp != self.player and opp.resources[res] > 0: self.player.resources[res] += opp.resources[res] C.log.writef('{} receives {} {} from {}', self.player, opp.resources[res], res, opp) C.log.writef('{} plays {}, claiming all {}', self.player, obj, res) play_dev(self.player, obj) self.devcard = obj elif obj.name == 'Year of Plenty': res, = rest self.devcard = obj raise stg.Switch('year-plenty', res=res) elif obj.name == 'Road Building': self.devcard = obj raise stg.Switch('road-building') else: raise Exception('unknown card: {} {}'.format(obj, obj.name)) elif obj_type == 'devdeck': card = C.state.dev_deck.draw() self.player.devcards.add(card) self.bought_devcards.add(card) C.log.writef('{} buys a development card', self.player) msg = '' if card.name == 'Victory Point': msg = ' (gaining 1 victory point)' self.player.vps += 1 C.log[self.player].writef('You got a {}{}', card, msg) pay_cost(self.player, C.state.costs.devcard, C.state.bank) else: raise Exception('Unknown obj {}: {}'.format(type(obj), obj)) if check_victory(C): raise GameOver raise stg.Decide('main')
def sell_cards(self, C, player, action=None): raise stg.Switch('main')