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 _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 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 _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 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 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 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, player_order, real_estate): super().__init__() self.available = tset(real_estate) # C.state.world.corners self.settled = None self.on_second = False self.player_order = player_order + player_order[::-1]
def _find_next(self, players): mn = None options = tset() # check order of available players with markets for player in players: if player not in self.done and len(player.marker): total = sum(card.value for card in player.market) if mn is None and mn > total: options.clear() options.add(player) elif mn == total: options.add(player) if len(options) == 1: return options.pop() # tie break with herald order mn = None best = None for player in options: if mn is None or player.order < mn: mn, best = player.order, player return best
def get_main_turn(self, C): out = GameActions('You rolled: {}. Take your turn.'.format(self.roll)) with out('pass', 'End your turn'): out.add('pass') options = check_building_options(self.player, C.state.costs) for bldname, opts in options.items(): with out('build-{}'.format(bldname), C.state.msgs.build[bldname]): out.add(opts) if len(C.state.dev_deck) and can_buy(self.player, C.state.costs.devcard): with out('buy', desc='Buy a development card'): out.add(C.state.dev_deck) with out('maritime-trade', desc='Maritime Trade (with the bank)'): options = bank_trade_options(self.player, C.state.bank_trading) if len(options): out.add('offer', tset((num, res) for res, num in options.items())) 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)) with out('play', desc='Play a development card'): if len(self.player.devcards) and self.devcard is None: res = tset(self.player.resources.keys()) for card in self.player.devcards: if card in self.bought_devcards: pass elif card.name == 'Monopoly': out.add(card, res) elif card.name == 'Year of Plenty': out.add(card, res) elif card.name == 'Victory Point': pass else: out.add(card) return tdict({self.player: out})
def draw(self, n=None, player=None): num = 1 if n is None else n if len(self) < num: self.refill() cardset=super().draw(n=n, player=player) for c in cardset: c.visible = tset([player]) return cardset
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 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 finalize(self, C, player, action=None): if len(self.responses): if action is None: accepts = tset() counters = tset() for p in self.responses: (counters if p in self.counter_offers else accepts).add(p) for c in counters: self.display_trade(C.log[self.player], c, *self.counter_offers[c], counter=True) raise stg.Decide('commit', accepts=accepts, counters=counters) cmd, = action if cmd in self.responses: offer, demand = self.offer, self.demand if cmd in self.counter_offers: C.log[self.player].writef('You accept {}\'s counter-trade', cmd) offer, demand = self.counter_offers[cmd] execute_trade(offer, demand, C.state.bank, from_player=self.player, to_player=cmd, log=C.log) else: C.log[self.player].write('You cancel the trade.') else: C.log[self.player].write('No one has accepted your trade offer.') C.log.dindent() raise PhaseComplete
def __init__( self, player, **other ): # TODO: make sure only one dev card can be played, and not the ones bought super().__init__(player=player, **other) self.roll = None self.devcard = None self.card_info = None # for processing multi decision devcards self.bought_devcards = tset()
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 __init__(self, player, **other): super().__init__(player=player, **other) self.roll = None self.devcard = None self.card_info = None # for processing multi decision devcards self.bought_devcards = tset() self.pre_check = 'check'
def get_offer(self, C): offer, demand = self.offer, self.demand out = GameActions('You are proposing a trade') with out('cancel', 'Cancel trade'): out.add('cancel') with out('submit', 'Submit trade'): out.add('submit') with out('trade', 'Change trade'): out.add('demand', tset(res for res in demand)) out.add( 'offer', tset(res for res, num in self.player.resources.items() if num - offer[res] > 0)) # TODO: add trade to info return tdict({self.player: 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 build_catan_map(G, hex_info, ports, number_info, RNG): start_field = None for field in G.fields: if field.val == 'A': start_field = field assert start_field is not None, 'could not find the start field' outside = get_outside_corners(start_field) for idx, port_type in ports.items(): outside[idx].port = port_type # set hex types hextypes = tlist() for res, num in hex_info.items(): hextypes.extend([res] * num) RNG.shuffle(hextypes) for field, hextype in zip(G.fields, hextypes): field.res = hextype del field.val hinums = number_info.hi options = tlist(f for f in G.fields if f.res != 'desert') assert len(options) == ( len(number_info.hi) + len(number_info.reg)), 'not the right number of tiles' remaining = tset() for num in hinums: idx = RNG.randint(0, len(options) - 1) f = options[idx] f.num = num options.remove(f) for n in f.neighbors: if n is not None and n in options: remaining.add(n) options.remove(n) remaining.update(options) regnums = number_info.reg RNG.shuffle(regnums) for f, num in zip(remaining, regnums): f.num = num
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 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 encode_locs(self, C): out = GameActions() if 'knight' in self: with out('cancel', desc='Cancel playing knight'): out.add('cancel') with out('loc', desc='Choose where to move the robber'): 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.') return tdict({self.player: out})
def encode(self, C): # complete trade if 'trade' in self: out = GameActions('Choose second card to exchange') with out('cancel', 'Cancel trade'): out.add('cancel') with out('trade', 'Second card to exchange'): cards = tset() if self.trade not in C.state.market: cards.update(C.state.market) for p in C.players: if self.trade not in p.market: cards.update(p.market) out.add(cards) else: out = GameActions('You have {} actions left'.format(self.num)) # trade # 1. can choose card from some other market # 2. can choose card from my own market # get cards from all markets except my own (self.player) with out('trade', 'Select card from other player markets'): for p, cards in self.market.items(): if p == self.player and 'trade' not in self: continue elif 'trade' in self and p != self.player: continue opts = cards if len(opts): out.add(opts) print('market phase out', out) # pickup # can pickup card from my own market # play royal # can play any royal from my hand # royal action # can take action of current royal, let's say king # exchange building # 1. can pick up one card from one of my buildings # 2. pick one card from my market OR my hand 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() 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})
def get_counter(self, C): outs = tdict() for p, r in self.responses.items(): if r is None: offer, demand = self.offer, self.demand status = 'Respond to trade' if p in self.counter_offers: offer, demand = self.counter_offers[p] status = 'Respond to trade with your counter-trade' out = GameActions(status) with out('reject', 'Reject trade'): out.add('reject') with out( 'accept', 'Accept {}trade'.format( 'counter-' if p in self.counter_offers else '')): if trade_available(p, demand): out.add('accept') if 'allow_counter_trades' not in C.state or C.state.allow_counter_trades: # TODO: add this to config/settings with out('counter', 'Counter by amending the trade'): out.add('demand', tset(res for res in demand)) out.add( 'offer', tset(res for res, num in p.resources.items() if num - offer[res] > 0)) outs[p] = out # TODO: add trades to out.info for AIs return outs
def execute(self, C, player=None, action=None): if self.available is None: self.available = tset(C.state.world.corners) if action is not None: loc, = action if loc.obj_type == 'Edge': build(C, 'road', player, loc) self.settled = None self.player_order.pop() if len(self.player_order) == 0: raise SwitchPhase('main', stack=False) if len(self.player_order) == len(C.players): self.on_second = True elif loc.obj_type == 'Corner': build(C, 'settlement', player, loc) self.settled = loc for e in loc.edges: if e is not None: for c in e.corners: self.available.discard(c) if self.on_second: res = tlist() for f in loc.fields: if f is not None and f.res != 'desert': res.append(f.res) for r in res: gain_res(r, C.state.bank, player, 1) if len(res) == 3: s = '{}, {}, and {}'.format(*res) elif len(res) == 2: s = '{} and {}'.format(*res) elif len(res) == 1: s = '{}'.format(*res) else: s = 'no resources' C.log.writef('{} gains: {}', player, s)
def encode(self, C): out = GameActions() if self.settled is None: loc_name = 'settlement' with out('loc-settlement', 'Available Locations'): out.add(self.available) else: loc_name = '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), ) out.set_status('Choose a location to place a {}'.format(loc_name)) return tdict({self.player_order[-1]: out})
def _init_game(self, config): cards = tlist() for n, c in config.cards.items(): cards.extend([c]) self.state.deck = self.table.create(obj_type='deck52', cards=cards, seed=self.RNG.getrandbits(64), default='card') self.state.deck.shuffle() for i, player in enumerate(self.players): player.order = i + 1 player.hand = tset() for k in range(5): c1 = self.state.deck.draw() c1.face_down(player) #c1.visible = tset([player]) player.hand.add( c1 ) #bei 1 card kann add nehmen, bei set of cards muss update nehmen! self.state.deck.count = len(self.state.deck)
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')