def setup_pre_phase(G, player_setup_path='config/faction_setup.yml'): player_setup = load(player_setup_path) # place fixed units for name, config in player_setup.items(): if 'units' not in config.setup: continue for unit in config.setup.units: add_unit(G, unit) # prep temp info G.temp = tdict() for name, faction in player_setup.items(): out = tdict() out.player = name if 'cadres' in faction.setup: out.info = faction.setup.cadres out.msg = 'Choose this many cadres to place into each of these territories' else: out.msg = 'Wait while other players place their cadres'
def USA_becomes_satellite(G, player='West'): assert player == 'West', 'The USA can only become a satellite of West' becomes_satellite(G, 'USA') # USA specific stuff faction = G.players[player] faction.members['USA'] = tset('USA') faction.homeland['USA'] = G.nations.territories['USA'].copy() G.nations.designations['USA'] = player unit = adict() unit.nationality = 'USA' unit.type = 'Fortress' unit.tile = 'Washington' unit.cv = 4 add_unit(G, unit) unit = adict() unit.nationality = 'USA' unit.type = 'Fortress' unit.tile = 'New_York' unit.cv = 2 add_unit(G, unit) faction.stats.factory_idx += 1 faction.stats.factory_cost = faction.stats.factory_all_costs[faction.stats.factory_idx] G.logger.write('{} factory cost decreases to {}'.format())
def setup_phase(G, action): # player, tilename, unit_type # place user chosen units # out: send message to all players to choose what tiles to place how many cadres on try: msg = io.get() assert msg.player in incomplete, 'Player {} is already done'.format( msg.player) reqs = player_setup[msg.player].setup.cadres placed = False for member, tiles in reqs.items(): if msg.tile in tiles: placed = True assert tiles[ msg. tile] > 0, 'No more cadres can be placed onto {}'.format( msg.tile) unit = tdict() unit.type = msg.type unit.tile = msg.tile unit.nationality = member unit.cv = 1 add_unit(G, unit) tiles[msg.tile] -= 1 if tiles[msg.tile] == 0: del tiles[msg.tile] assert placed, 'Tile {} not available for placement'.format(msg.tile) except (ActionError, AssertionError) as e: io.put({'error': 'Invalid Action', 'msg': str(e)}) # draw action cards for name, config in player_setup.items(): if 'action_cards' in config.setup: G.players[name].hand.extend( draw_cards(G.action_cards, config.setup.action_cards)) if 'investment_cards' in config.setup: G.players[name].hand.extend( draw_cards(G.investment_cards, config.setup.investment_cards))
def setup_phase(G, player, action): # player, nationality, tilename, unit_type # place user chosen units nationality, tilename, unit_type = action unit = adict() unit.nationality = nationality unit.tile = tilename unit.type = unit_type #print(unit) add_unit(G, unit) G.temp.setup[player].cadres[nationality][tilename] -= 1 if G.temp.setup[player].cadres[nationality][tilename] == 0: del G.temp.setup[player].cadres[nationality][tilename] if len(G.temp.setup[player].cadres[nationality]) == 0: del G.temp.setup[player].cadres[nationality] if len(G.temp.setup[player].cadres) == 0: # all cadres are placed del G.temp.setup[player].cadres if 'action_cards' in G.temp.setup[player]: draw_cards(G, 'action', player, N=G.temp.setup[player].action_cards) del G.temp.setup[player].action_cards if 'investment_cards' in G.temp.setup[player]: draw_cards(G, 'action', player, N=G.temp.setup[player].action_cards) del G.temp.setup[player].investment_cards return encode_setup_actions(G)
def setup_pre_phase(G, player_setup_path='config/faction_setup.yml'): player_setup = load(player_setup_path) # prep temp info - phase specific data temp = tdict() temp.setup = tdict() for name, faction in player_setup.items(): if 'units' in faction.setup: for unit in faction.setup.units: add_unit(G, unit) del faction.setup.units temp.setup[name] = faction.setup G.temp = temp # return action adict(faction: (action_keys, action_options)) return encode_setup_actions(G)
def convert_to_armed_minor(G, nation): if nation in G.diplomacy.neutrals: del G.diplomacy.neutrals[nation] G.nations.status[nation].is_armed = 1 desig = G.nations.designations[nation] # arming the minor for tilename in G.nations.territories[nation]: tile = G.tiles[tilename] tile.owner = desig if tile.muster > 0: unit = adict() unit.nationality = nation unit.type = 'Fortress' unit.tile = tilename unit.cv = tile.muster unit = add_unit(G, unit) G.nations.status[nation].units[unit._id] = unit G.logger.write('A Fortress of {} appears in {} with cv={}'.format(nation, unit.tile, unit.cv))
def setup_phase(G, player, action): # player, nationality, tilename, unit_type # place user chosen units if action is None: # pre phase player_setup = load(player_setup_path) # prep temp info - phase specific data temp = tdict() temp.setup = tdict() for name, faction in player_setup.items(): if 'units' in faction.setup: for unit in faction.setup.units: add_unit(G, unit) del faction.setup.units temp.setup[name] = faction.setup G.temp = temp # return action adict(faction: (action_keys, action_options)) return encode_setup_actions(G) nationality, tilename, unit_type = action unit = adict() unit.nationality = nationality unit.tile = tilename unit.type = unit_type add_unit(G, unit) G.temp.setup[player].cadres[nationality][tilename] -= 1 if G.temp.setup[player].cadres[nationality][tilename] == 0: del G.temp.setup[player].cadres[nationality][tilename] if len(G.temp.setup[player].cadres[nationality]) == 0: del G.temp.setup[player].cadres[nationality] if len(G.temp.setup[player].cadres) == 0: # all cadres are placed del G.temp.setup[player].cadres if 'action_cards' in G.temp.setup[player]: draw_cards(G, 'action', player, N=G.temp.setup[player].action_cards) del G.temp.setup[player].action_cards if 'investment_cards' in G.temp.setup[player]: draw_cards(G, 'action', player, N=G.temp.setup[player].action_cards) del G.temp.setup[player].investment_cards return encode_setup_actions(G)
def production_phase(G, player, action): if len(action) == 1: # card or upgrade unit if action == ('action_card', ): G.temp.prod[player].action_cards_drawn += 1 effect = 'drawing an action card' elif action == ('investment_card', ): G.temp.prod[player].invest_cards_drawn += 1 effect = 'drawing an investment card' elif action == ('pass', ): effect = 'passing' else: ID, = action G.temp.prod[player].upgraded_units.add(ID) unit = G.objects.table[ID] unit.cv += 1 G.objects.updated[ID] = unit effect = 'upgrading a unit in {}'.format(G.objects.table[ID].tile) else: # create new unit nationality, tilename, unit_type = action unit = adict() unit.nationality = nationality unit.tile = tilename unit.type = unit_type unit = add_unit(G, unit) G.temp.prod[player].upgraded_units.add(unit._id) effect = 'building a new cadre in {}'.format(unit.tile) G.temp.prod[player].production_remaining -= 1 G.logger.write( '{} spends 1 production on {} ({} production remaining)'.format( player, effect, G.temp.prod[player].production_remaining)) if G.temp.prod[player].production_remaining == 0: # draw cards draw_cards(G, 'action', player, N=G.temp.prod[player].action_cards_drawn) draw_cards(G, 'investment', player, N=G.temp.prod[player].invest_cards_drawn) G.logger.write('{} is done with production'.format(player)) # clean up temp del G.temp.prod[player] # move to next player G.temp.active_idx += 1 if G.temp.active_idx == len(G.players): raise PhaseComplete # phase is done active_player = G.game.turn_order[G.temp.active_idx] G.logger.write('{} may spend {} production points'.format( active_player, G.temp.prod[active_player].production_remaining)) return encode_production_actions(G)
def government_post_phase(G, player=None, action=None): if len(G.temp.move_to_post) and action is not None: action, = action if action == 'accept': G.temp.move_to_post[player] = False elif action in G.players[player].hand: discard_cards(G, action) elif action in G.players[player].secret_vault: reveal_tech(G, player, action) else: decrement_influence(G, action) action = None code = encode_post_gov_actions(G) if len(code): return code # diplomacy resolution (check for control, discard diplomacy_cards), handsize, update tracks # resolve diplomacy if 'diplomacy' in G.temp: discard_cards(G, *G.temp.diplomacy_cards) del G.temp.diplomacy_cards for nation, (fname, val) in G.temp.diplomacy.items(): for _ in range(val): increment_influence(G, fname, nation) del G.temp.diplomacy # check for control new_sats = tdict() for nation, dipl in G.diplomacy.neutrals.items(): if nation not in G.diplomacy.influence: if dipl.faction is None: continue else: faction = G.players[dipl.faction] faction.diplomacy[diplvl[dipl.value]].remove(nation) pop, res = compute_tracks(G.nations.territories[nation], G.tiles) faction.tracks.POP -= pop faction.tracks.RES -= res G.logger.write('{} lost influence over {} (losing POP={} RES={})'.format(dipl.faction, nation, pop, res)) dipl.value = 0 dipl.faction = None else: inf = G.diplomacy.influence[nation] val = min(inf.value, 3) gainer = None loser = None if nation == 'USA': # handle USA separately if dipl.faction is None: if G.players[inf.faction].stats.enable_USA: gainer = inf.faction elif dipl.faction == inf.faction: if G.players[dipl.faction].stats.enable_USA and dipl.value != val: G.players[dipl.faction].diplomacy[diplvl[dipl.value]].remove(nation) else: if G.players[dipl.faction].stats.enable_USA: loser = dipl.faction G.players[dipl.faction].diplomacy[diplvl[dipl.value]].remove(nation) if G.players[inf.faction].stats.enable_USA: gainer = inf.faction else: val = min(inf.value, 3) # cap influence at 3 if dipl.faction is None: gainer = inf.faction elif dipl.faction != inf.faction: loser = dipl.faction gainer = inf.faction G.players[dipl.faction].diplomacy[diplvl[dipl.value]].remove(nation) elif dipl.value == val: # no change required continue else: # value has changed G.players[inf.faction].diplomacy[diplvl[dipl.value]].remove(dipl.faction) faction = G.players[inf.faction] faction.diplomacy[diplvl[inf.value]].add(dipl.faction) dipl.faction = inf.faction dipl.value = inf.value if inf.value == 3: new_sats[nation] = inf.faction # update tracks tmsg = '' if gainer is not None or loser is not None: pop, res = compute_tracks(G.nations.territories[nation], G.tiles) if gainer is not None: G.players[gainer].tracks.POP += pop G.players[gainer].tracks.RES += res tmsg += ' ({} gains POP={}, RES={})'.format(gainer, pop, res) if loser is not None: G.players[loser].tracks.POP -= pop G.players[loser].tracks.RES -= res tmsg += ' (lost by {})'.format(loser) dname = dipname[inf.value] G.logger.write('{} becomes {} of {}{}'.format(nation, dname, inf.faction, tmsg)) if 'USA' in new_sats: name = new_sats['USA'] del new_sats['USA'] USA_becomes_satellite(G, name) sat_units = tdict() for nation, fname in new_sats.items(): becomes_satellite(G, nation) for tilename in G.nations.territories[nation]: tile = G.tiles[tilename] if 'muster' in tile: if fname not in sat_units: sat_units[fname] = tdict() sat_units[fname][tilename] = tile.muster G.temp.sat_units = sat_units # place garrison in new satellites if action is not None: unit = adict() unit.tile, unit.type = action unit.nationality = G.players[player].stats.great_power unit.cv = G.temp.sat_units[player][unit.tile] add_unit(G, unit) del G.temp.sat_units[player][unit.tile] if len(G.temp.sat_units[player]) == 0: del G.temp.sat_units[player] if len(G.temp.sat_units): return encode_sat_units(G) raise PhaseComplete
def violation_of_neutrality(G, declarer, nation): # including world reaction and placing armed minor units assert nation in G.diplomacy.neutrals, '{} is no longer neutral'.format(nation) G.players[declarer].stats.aggressed = True G.logger.write('{} has violated the neutrality of {}'.format(declarer, nation)) # world reaction reaction = G.tiles[G.nations.capitals[nation]].muster rivals = G.players[declarer].stats.rivals G.logger.write('{} draw {} cards for world reaction'.format(' and '.join(rivals, reaction))) for rival in rivals: draw_cards(G, 'action', rival, reaction) # remove influence if nation == 'USA': assert declarer not in {'West', 'USSR'}, 'West/USSR cannot violate the neutrality of the USA' if 'USA' in G.diplomacy.influence: inf = G.diplomacy.influence['USA'] del G.diplomacy.influence['USA'] del G.objects.table[inf._id] G.objects.removed[inf._id] = inf G.logger.write('{} loses {} influence in the USA'.format(inf.faction, inf.value)) # USA becomes a West satellite USA_becomes_satellite(G, 'West') if not G.players[declarer].stats.at_war_with['West']: declaration_of_war(G, declarer, 'West') return if nation in G.diplomacy.influence: inf = G.diplomacy.influence[nation] if inf.faction != declarer and inf.value == 2 and not G.players[declarer].stats.at_war_with[inf.faction]: G.logger.write('Since {} was a protectorate of {}, {} hereby declares war on {}'.format(nation, inf.faction, declarer, inf.faction)) declaration_of_war(G, declarer, inf.faction) # nation should now become a satellite of inf.faction - including placing units raise NotImplementedError lvl = diplvl[inf.value] G.players[inf.faction].diplomacy[lvl].remove(nation) decrement_influence(G, nation, inf.value) G.logger.write('{} loses {} influence in {}'.format(inf.faction, inf.value, nation)) # arming the minor for tilename in G.nations.territories[nation]: tile = G.tiles[tilename] if tile.muster > 0: unit = adict() unit.nationality = nation unit.type = 'Fortress' unit.tile = tilename unit.cv = tile.muster add_unit(G, unit) G.logger.write('A Fortress of {} appears in {} with cv={}'.format(nation, unit.tile, unit.cv))
def satellite_phase(G, player=None, action=None): if 'new_sats' in G.temp: new_sats = G.temp.new_sats if 'USA' in new_sats: name = new_sats['USA'] del new_sats['USA'] USA_becomes_satellite(G, name) sat_units = tdict() for nation, fname in new_sats.items(): becomes_satellite(G, fname, nation) if G.nations.status[nation].is_armed: # replace currently existing troops G.logger.write('{} may replace Armed Minor units in {}'.format(fname, nation)) removed = [] for uid, unit in G.nations.status[nation].units: if fname not in sat_units: sat_units[fname] = tdict() sat_units[fname][unit.tile] = unit.cv removed.append(unit) for unit in removed: remove_unit(G, unit) else: ts = [] for tilename in G.nations.territories[nation]: tile = G.tiles[tilename] if 'muster' in tile and tile.muster > 0: if fname not in sat_units: sat_units[fname] = tdict() sat_units[fname][tilename] = tile.muster ts.append(tilename) G.logger.write('{} may place units into {}'.format(fname, ', '.join(ts))) G.temp.sat_units = sat_units del G.temp.new_sats if action is not None: assert player in G.temp.sat_units, '{} has no garrison troops to place'.format(player) unit = adict() unit.tile, unit.type = action unit.nationality = G.players[player].stats.great_power unit.cv = G.temp.sat_units[player][unit.tile] add_unit(G, unit) del G.temp.sat_units[player][unit.tile] if len(G.temp.sat_units[player]) == 0: del G.temp.sat_units[player] if len(G.temp.sat_units): return encode_garrison_options(G) del G.temp.sat_units raise PhaseComplete
def production_phase(G, player, action): if action is None: if 'temp' in G: del G.temp G.temp = tdict() G.temp.active_idx = 0 G.temp.prod = tdict() # TODO: update/evaluate blockades for player, faction in G.players.items(): # TODO: check if production is zero because MainCapital is lost -> faction.stats.fallen flag G.temp.prod[player] = tdict() G.temp.prod[player].production_remaining = compute_production_level(faction) G.temp.prod[player].upgraded_units = tset() G.temp.prod[player].action_cards_drawn = 0 G.temp.prod[player].invest_cards_drawn = 0 # remove all blockades (not unsupplied markers) active_player = G.game.turn_order[G.temp.active_idx] G.logger.write( '{} may spend {} production points'.format(active_player, G.temp.prod[active_player].production_remaining)) return encode_production_actions(G) if len(action) == 1: # card or upgrade unit if action == ('action_card',): G.temp.prod[player].action_cards_drawn += 1 effect = 'drawing an action card' elif action == ('investment_card', ): G.temp.prod[player].invest_cards_drawn += 1 effect = 'drawing an investment card' elif action == ('pass',): effect = 'passing' else: ID, = action G.temp.prod[player].upgraded_units.add(ID) unit = G.objects.table[ID] unit.cv += 1 G.objects.updated[ID] = unit effect = 'upgrading a unit in {}'.format(G.objects.table[ID].tile) else: # create new unit nationality, tilename, unit_type = action unit = adict() unit.nationality = nationality unit.tile = tilename unit.type = unit_type unit = add_unit(G, unit) G.temp.prod[player].upgraded_units.add(unit._id) effect = 'building a new cadre in {}'.format(unit.tile) G.temp.prod[player].production_remaining -= 1 G.logger.write('{} spends 1 production on {} ({} production remaining)'.format(player, effect, G.temp.prod[player].production_remaining)) if G.temp.prod[player].production_remaining == 0: # draw cards draw_cards(G, 'action', player, N=G.temp.prod[player].action_cards_drawn) draw_cards(G, 'investment', player, N=G.temp.prod[player].invest_cards_drawn) G.logger.write('{} is done with production'.format(player)) # clean up temp del G.temp.prod[player] # move to next player G.temp.active_idx += 1 if G.temp.active_idx == len(G.players): raise PhaseComplete # phase is done active_player = G.game.turn_order[G.temp.active_idx] G.logger.write( '{} may spend {} production points'.format(active_player, G.temp.prod[active_player].production_remaining)) return encode_production_actions(G)