def compute_debt(self, C, player, action=None): if 'debt' not in self: self.debt = tdict() self.choices = tdict() lim = C.state.hand_limit for player in C.players: if player.num_res > lim: self.debt[player] = player.num_res // 2 self.choices[player] = tlist() elif action is not None: res, = action self.choices[player].append(res) gain_res(res, C.state.bank, player, -1) C.log[player].writef('1 of your {} is stolen.', res) self.debt[player] -= 1 if self.debt[player] < 1: del self.debt[player] C.log.writef('{} loses: {}', player, ', '.join(self.choices[player])) del self.choices[player] if len(self.debt): raise Decide('debt') raise Switch('loc')
def encode(self, C): if 'debt' in self and len(self.debt): outs = tdict() for player, topay in self.debt.items(): outs[player] = GameActions('You are robbed, choose {} resources to discard.'.format(topay)) with outs[player]('robbed', desc='Choose resource to discard'): outs[player].add(tset(res for res, num in player.resources.items() if num > 0)) return outs out = GameActions() if 'loc' not in self: with out('loc', desc='Choose where to move the robber'): if 'knight' in self: out.add('cancel') options = tset(f for f in C.state.world.fields if 'robber' not in f) out.add(options) out.set_status('Choose where to move the robber.') else: with out('target', desc='Choose which player to steal from'): if 'knight' in self: out.add('cancel') out.add(self.steal_options) out.set_status('Choose what player to steal from.') return tdict({self.player: out})
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 check_building_options(player, costs): locs = tdict( road=tset(), settlement=tset(), city=tset(), ) for road in player.buildings.road: for c in road.loc.corners: if 'building' not in c: if _settle_available(c): locs.settlement.add(c) elif c.building.player == player: if c.building.get_type() == 'settlement': locs.city.add(c.building) else: continue for e in c.edges: if e is not None and 'building' not in e: locs.road.add(e) options = tdict() for bld, opts in locs.items(): if _payable(player, costs[bld]) and player.reserve[bld] > 0: options[bld] = opts return options
def encode(self, C): if self.maritime is not None: out = GameActions('What resource would you like for {} {}'.format(*self.maritime_msg)) with out('cancel', desc='Cancel trade'): out.add('cancel') with out('maritime-trade', desc='Select the resource to receive'): out.add(tset(self.demand.keys())) return tdict({self.player:out}) if self.partners is not None: out = GameActions('Some players accepted your offer') with out('cancel', desc='Cancel trade'): out.add('cancel') with out('domestic-confirm', desc='Select player to confirm trade'): out.add(self.partners) return tdict({self.player:out}) if self.responses is not None: outs = tdict() for p, resp in self.responses.items(): if resp is None: out = GameActions(writef('Do you accept the trade proposed by {}.', self.player)) out.info.offer = self.offer out.info.demand = self.demand with out('domestic-response', desc='Choose to accept or reject trade'): if trade_available(p, self.demand): out.add('accept') out.add('reject') outs[p] = out return outs out = GameActions('Choose what resources to trade') with out('cancel', desc='Cancel trade'): out.add('cancel') with out('send', desc='Send trade offer to opponents'): out.add('send') with out('domestic-trade', desc='Domestic Trade (with players)'): out.add('demand', tset(res for res in self.player.resources)) if self.player.num_res: out.add('offer', tset(res for res, num in self.player.resources.items() if num > 0)) return tdict({self.player:out})
def _end_game(self): val = self.state.winner if val is None: return tdict(winner=None) for p in self.players.values(): if p.val == val: return tdict(winner=p.name) raise Exception('No player with val: {}'.format(val))
def __init__(self, player, bank_trades=None, **info): super().__init__(**info) self.player = player self.demand = tdict({res:0 for res in player.resources.keys()}) self.offer = tdict({res:0 for res in player.resources.keys()}) self.maritime = bank_trades self.maritime_msg = None self.responses = None self.partners = None
def compute_missing(resources, costs): dists = tdict() missing_res = tdict() for building, cost in costs.items(): dists[building] = 0 missing = tdict() for res, num in cost.items(): if num > resources[res]: diff = num - resources[res] dists[building] += diff missing[res] = diff missing_res[building] = missing return missing_res, dists
def _end_game(self): val = self.state.winner if val is None: self.log.writef('Game over! Draw game!') return tdict(winner=None) for player in self.players: if player.val == val: self.log.writef('Game Over! {} wins!', player) return tdict(winner=player.name) raise Exception('No player with val: {}'.format(val))
def _init_game(self, config): cards = tlist() num = config.rules.num_numbers for n, c in config.cards.items(): if n in config.rules.num_royals: cards.extend([c]*config.rules.num_royals[n]) else: cards.extend([c]*num) self.state.discard_pile = self.create_object('discard_pile', top_face_up=config.rules.discard_market, seed=self.RNG.getrandbits(32), default='card') self.state.deck = self.create_object('draw_pile', discard_pile=self.state.discard_pile, cards=cards, seed=self.RNG.getrandbits(32), default='card') self.state.deck.shuffle() self.state.market = self.create_object('market', neutral=tset(), _log=self.log, _deck=self.state.deck) self.state.royal_phases = config.rules.royal_phases for i, player in enumerate(self.players): player.hand = tset(self.state.deck.draw(config.rules.hand_size.starting)) player.buildings = tdict({bld:tlist() for bld in config.rules.counts}) player.vps = 0 player.hand_limit = config.rules.hand_size.max player.coins = 3 player.order = i + 1 if i == 0: self.state.herald = player
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 _end_game(self): out = tdict() winners = tlist() for name in self.players.values(): winners.append(name) out.winner = random.choice(winners) print('winner is {}'.format(out.winner)) return out
def get_road(self, C): out = GameActions('Choose a location to place a road') with out('loc-road', 'Available Locations'): out.add( tset(e for e in self.settled.edges if e is not None and 'building' not in e), ) return tdict({self.active: out})
def bank_trade_options(player, bank_trading): bank_options = tdict() default = bank_trading['3to1'] if '3to1' in player.ports else bank_trading.default for res, num in player.resources.items(): ratio = bank_trading[res] if res in player.ports else default if num >= ratio: bank_options[res] = ratio return bank_options
def decide_claim(self, C): out = GameActions( 'You have fulfilled the requirements to claim victory.') with out('end', 'End the game?'): out.add(tset(['yes', 'no'])) return tdict({p: out for p in self.candidates})
def _init_game(self, C, config, settings): for name in config.rules.counts: register_object(game='aristocracy', name=name, cls=Building) KingPhase.neutral_num = config.neutral_market.king QueenPhase.neutral_num = config.neutral_market.queen JackPhase.neutral_num = config.neutral_market.jack cards = tlist() num = config.rules.num_numbers for n, c in config.cards.items(): if n in config.rules.num_royals: cards.extend([c] * config.rules.num_royals[n]) else: cards.extend([c] * num) C.state.discard_pile = C.create_object( 'discard_pile', top_face_up=config.rules.discard_market, seed=C.RNG.getrandbits(32), default='card') C.state.deck = C.create_object('draw_pile', discard_pile=C.state.discard_pile, cards=cards, seed=C.RNG.getrandbits(32), default='card') C.state.discard_pile._draw_pile = C.state.deck C.state.deck.shuffle() C.state.market = C.create_object('market', neutral=tset(), _log=C.log, _deck=C.state.deck) for i, player in enumerate(C.players): player.hand = tset() player._draw_increment = config.rules.draw_cards player._deck = C.state.deck player.hand = tset() player.market = tset() player.buildings = tdict( {bld: tset() for bld in config.rules.counts}) player.vps = 0 player.hand_limit = config.rules.max_hand_size player.money = config.rules.starting.coins player.order = i - 1 if i == 0: C.state.herald = player
def collect(self, C): player = self.winners[len(self.picks)] out = GameActions('What card do you choose in the auction?') with out('pick', 'Claim card'): out.add(C.state.market.neutral) return tdict({player: out})
def _end_game(self): out = tdict() vps = tdict({player.name: player.vps for player in self.players}) out.vps = vps mx = max(vps.values()) winners = tlist() for name, V in vps.items(): if V == mx: winners.append(name) if len(winners) == 1: out.winner = winners[0] return out out.winners = winners return out
def pick_target(self, C): out = GameActions() with out('target', desc='Choose which player to steal from'): if 'knight' in self: out.add('cancel') out.add(self.steal_options) out.set_status('Choose what player to steal from.') return tdict({self.player: out})
def get_maritime(self, C): out = GameActions('What resource would you like for {} {}'.format( *self.maritime_msg)) with out('cancel', desc='Cancel trade'): out.add('cancel') with out('maritime-trade', desc='Select the resource to receive'): out.add(tset(self.demand.keys())) return tdict({self.player: out})
def decide_tax(self, C): outs = tdict() for p, num in self.taxable.items(): out = GameActions( 'You have too many cards, you must discard {} due to tax'. format(util.format_quantity('card', num))) with out('tax', 'Discard card'): out.add(p.hand) outs[p] = out return outs
def _end_game(self, C): out = tdict() vps = tdict({player.name: player.vps for player in C.players}) out.vps = vps mx = max(vps.values()) # TODO: break ties with money and hand card values winners = tlist() for name, V in vps.items(): if V == mx: winners.append(name) if len(winners) == 1: out.winner = winners[0] return out out.winners = winners return out
def decide_steal(self, C): outs = tdict() for player, topay in self.debt.items(): outs[player] = GameActions( 'You are robbed, choose {} resources to discard.'.format( topay)) with outs[player]('robbed', desc='Choose resource to discard'): outs[player].add( tset(res for res, num in player.resources.items() if num > 0)) return outs
def get_preroll(self, C, knight): out = GameActions('You can play your knight before rolling') with out('continue', 'Continue with your turn'): out.add('continue') with out('knight', 'Play your knight'): out.add( knight) # TODO: maybe allow user to pick which knight to use return tdict({self.player: out})
def encode(self, C): out = GameActions('Place a tick into one of free spots') free = C.state.board.get_free() with out('actionType1', desc='First kind of action'): out.add(tset({'a', 'b', 'c'})) with out('actionType2', desc='Second kind of action'): out.add(tset({1, 2, 3})) return tdict({self.player: out})
def choose_bid(self, C): outs = tdict() for p in C.players: if p not in self.bids: out = GameActions( 'How much do you want to bid in the auction?') with out('bid', 'Your bid'): out.add(tset(range(p.money + 1))) outs[p] = out return outs
def get_road_building(self, C): out = GameActions( 'You activated Road Building, and can now build a second road') with out('cancel', desc='Undo playing dev card'): out.add('cancel') options = check_building_options(self.player, C.state.costs) with out('dev-road', C.state.msgs.build.road): out.add(options.road) return tdict({self.player: out})
def get_year_of_plenty(self, C): out = GameActions( 'You activated Year of Plenty, choose a second resource to collect' ) with out('cancel', desc='Undo playing dev card'): out.add('cancel') with out('dev-res', desc='Select a second resource'): out.add(tset(self.player.resources.keys())) return tdict({self.player: out})
def get_sites(self, options, table): sites = np.array( [tdict(ID=a[0].ID) for a in options['loc-settlement']]) for site in sites: c = table[site['ID']] site.nums = tlist(n.num for n in c.fields if n is not None and 'num' in n) site.ress = tlist(n.res for n in c.fields if n is not None and 'res' in n) site.val = sum(6 - abs(n - 7) for n in site.nums) if 'port' in c: site.port = c.port return sites
def encode(self, C): out = GameActions('Place a tick into one of free spots') free = C.state.board.get_free() if not len(free): C.state.winner = None raise GameOver with out('tic', desc='Available spots'): out.add(tset(free)) return tdict({self.player: out})