def load_map(G, tiles='config/tiles.yml', borders='config/borders.yml'): tiles = load(tiles) borders = load(borders) for b in borders: n1, n2 = b.tile1, b.tile2 t = b.type if 'borders' not in tiles[n1]: tiles[n1].borders = tdict() tiles[n1].borders[n2] = t if 'borders' not in tiles[n2]: tiles[n2].borders = tdict() tiles[n2].borders[n1] = t G.tiles = tdict({name: idict(tile) for name, tile in tiles.items()}) for name, tile in G.tiles.items(): tile.__dict__['_id'] = name # tile.name = name tile.units = tset() if tile.type not in {'Sea', 'Ocean', 'Strait'}: for neighbor in tile.borders.keys(): if G.tiles[neighbor].type == 'Sea' or G.tiles[ neighbor].type == 'Ocean': tile.type = 'Coast' break # add tile to game objects tile.obj_type = 'tile' tile.visible = tset({'Axis', 'West', 'USSR'}) G.objects.table[name] = tile
def add_unit(G, unit): # tile, type, cv, nationality unit = idict(unit.items()) unit.obj_type = 'unit' if 'cv' not in unit: # by default add a cadre unit.cv = 1 else: assert 1 <= unit.cv <= 4, '{} is an invalid cv value: {}'.format( unit.cv, unit) player = G.nations.designations[unit.nationality] #if player is 'Minor': #@@@ if player == 'Minor': unit.visible = tset(G.players.keys()) #G.nations.status[unit.nationality][unit._id] = unit #@@@ G.nations.status[unit.nationality].units[unit._id] = unit else: unit.visible = tset({G.nations.designations[unit.nationality]}) # check/update reserves reserves = G.units.reserves[unit.nationality] if unit.type not in reserves or reserves[unit.type] == 0: raise OutOfReservesError('{} has no more {}'.format( unit.nationality, unit.type)) reserves[unit.type] -= 1 G.players[player].units[unit._id] = unit tilename = unit.tile tile = G.tiles[tilename] # check for multiple fortresses if unit.type == 'Fortress': assert not ( tile.type == 'Sea' or tile.type == 'Ocean' ), 'Fortresses cannot be placed in the Sea/Ocean {}'.format(tilename) for unit_id in tile.units: assert G.objects.table[ unit_id].type != 'Fortress', 'There is already a Fortress in {}'.format( G.objects.table[unit_id].tile) # check convoy check_for_convoy(unit, tile) # add to sets tile.units.add(unit._id) G.objects.table[unit._id] = unit G.objects.created[unit._id] = unit G.objects.updated[tilename] = tile return unit
def load_map(G, tiles='config/tiles.yml', borders='config/borders.yml'): tiles = load(tiles) borders = load(borders) for b in borders: n1, n2 = b.tile1, b.tile2 t = b.type if 'borders' not in tiles[n1]: tiles[n1].borders = tdict() tiles[n1].borders[n2] = t if 'borders' not in tiles[n2]: tiles[n2].borders = tdict() tiles[n2].borders[n1] = t G.tiles = tiles for name, tile in G.tiles.items(): tile.name = name tile.units = tset() if tile.type != 'Sea' and tile.type != 'Ocean': for neighbor in tile.borders.keys(): if G.tiles[neighbor].type == 'Sea' or G.tiles[ neighbor].type == 'Ocean': tile.type = 'Coast' break # add tile to game objects tile.obj_type = 'tile' G.objects.table[name] = tile
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 convert_from_saveable(data): if data is None: return None if isinstance(data, (str, int, float)): try: return int(data) except: pass return data if isinstance(data, dict): if len(data) == 1: key, val = next(iter(data.items())) if 'set' == key: return tset(convert_from_saveable(el) for el in val) if 'xset' == key: return xset(convert_from_saveable(el) for el in val) if 'tuple' == key: return tuple(convert_from_saveable(el) for el in val) if '_object_' == key[:8]: typ = eval(key[8:]) obj = typ() obj.load_state(val) return obj if '_id' in data: return idict({convert_from_saveable(k): convert_from_saveable(v) for k, v in data.items()}) return tdict({convert_from_saveable(k): convert_from_saveable(v) for k, v in data.items()}) if isinstance(data, list): return tlist(convert_from_saveable(el) for el in data) try: return data.save_state() except AttributeError: raise Exception('Cannot save data of type: {}'.format(type(data)))
def production_pre_phase(G): if 'temp' in G: del G.temp G.temp = tdict() G.temp.active_idx = 0 G.temp.prod = tdict() # TODO: update blockades for player, faction in G.players.items(): 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)
def prepare_combat_structs(G, player): G.temp.combat = adict() c = G.temp.combat c.stages = [] #calc optional battles for player battles_to_select = tset() for tilename in G.temp.potential_battles: if tilename in G.temp.battles: continue is_relevant = player in powers_present(G, G.tiles[tilename]) if is_relevant: battles_to_select.add(tilename) c.battles_to_select = battles_to_select #calc battles that have to be fought and therefore are revealed battles_to_reveal = tdict() for tilename in G.temp.battles: if G.temp.battles[tilename] == player: battles_to_reveal[tilename] = player else: #print('RIESEN ERROR: new battle with another player!!!!',G.temp.battles[b]) pass c.battles_to_reveal = battles_to_reveal #add all bettles_to_reveal to c.battles c.battles = adict() c.battles_remaining = [] add_battles_to_reveal(G, player) assert len(c.battles_to_reveal.keys()) == 0, 'prepare_combat_structs: AFTER REVEALING STILL BATTLES_TO_REVEAL!'
def new_movement(G, player): G.temp.battles = tdict() # track new battles due to engaging G.temp.has_moved = tdict() # units can only move once per movement phase G.temp.threats = tset() G.temp.battle_groups = tdict() active = G.temp.order[G.temp.active_idx] G.logger.write('{} has {} command points for movement'.format( active, G.temp.commands[active].value))
def load_card_decks(G, action_path='config/cards/action_cards.yml', investment_path='config/cards/investment_cards.yml', info_path='config/cards/card_info.yml'): cinfo = load(info_path) caction = load(action_path) cinvest = load(investment_path) action_cards = tdict() action_cards.deck = tlist() for ID, card in caction.items(): card = idict(card) card.obj_type = 'action_card' card.visible = tset() card.__dict__['_id'] = 'action_{}'.format(ID) action_cards.deck.append(card._id) G.objects.table[card._id] = card investment_cards = tdict() investment_cards.deck = tlist() for ID, card in cinvest.items(): card = idict(card) card.obj_type = 'investment_card' card.visible = tset() card.__dict__['_id'] = 'invest_{}'.format(ID) investment_cards.deck.append(card._id) G.objects.table[card._id] = card G.cards = tdict() G.cards.action = action_cards G.cards.action.discard_pile = tlist() G.cards.investment = investment_cards G.cards.investment.discard_pile = tlist() G.cards.info = cinfo shuffle(G.random, G.cards.investment) shuffle(G.random, G.cards.action)
def government_pre_phase(G): # prep influence if 'temp' in G: del G.temp G.temp = tdict() G.temp.diplomacy = tdict() G.temp.diplomacy_cards = tset() G.temp.intel = tdict() G.temp.past_upgrades = tdict() for player in G.players: G.temp.past_upgrades[player] = 0 G.temp.passes = 0 G.temp.active_idx = 0 return encode_government_actions(G)
def load_players_and_minors(G): player_setup = load('config/faction_setup.yml') capitals = load('config/capitals.yml') G.nations = tdict() territories = tdict() designations = tdict() minor_designation = 'Minor' for tile in G.tiles.values(): if 'alligence' in tile: designations[tile.alligence] = minor_designation if tile.alligence not in territories: territories[tile.alligence] = tset() territories[tile.alligence].add(tile._id) designations['USA'] = 'Major' G.nations.designations = designations G.nations.territories = territories G.nations.capitals = capitals for nation, tilename in capitals.items(): G.tiles[tilename].capital = True G.nations.groups = tdict() # load factions/players players = tdict() groups = tset(player_setup.keys()) rivals = tdict() for g in groups: gps = groups.copy() gps.remove(g) rivals[g] = tset(gps) for name, config in player_setup.items(): faction = tdict() faction.stats = tdict() faction.stats.handlimit = config.Handlimit faction.stats.factory_all_costs = config.FactoryCost faction.stats.factory_idx = 0 faction.stats.factory_cost = faction.stats.factory_all_costs[ faction.stats.factory_idx] faction.stats.emergency_command = config.EmergencyCommand faction.stats.rivals = rivals[name] faction.stats.DoW = tdict({r: False for r in rivals[name]}) faction.stats.at_war_with = tdict({r: False for r in rivals[name]}) faction.stats.at_war = False faction.stats.aggressed = False faction.stats.peace_dividends = tlist() faction.stats.enable_USA = 'enable_USA' in config faction.stats.enable_Winter = 'enable_Winter' in config faction.cities = tdict() faction.cities.MainCapital = config.MainCapital faction.cities.SubCapitals = config.SubCapitals faction.members = tdict() for nation, info in config.members.items(): faction.members[nation] = tset([nation]) if info.type == 'Great_Power': faction.stats.great_power = nation if 'Colonies' in info: faction.members[nation].update(info.Colonies) full_cast = tset() for members in faction.members.values(): full_cast.update(members) for member in full_cast: G.nations.designations[member] = name faction.homeland = tdict( {member: tset() for member in faction.members.keys()}) faction.territory = tset() for tile_name, tile in G.tiles.items(): if 'alligence' not in tile: continue if tile.alligence in faction.members: # homeland faction.homeland[tile.alligence].add(tile_name) if tile.alligence in full_cast: faction.territory.add(tile_name) tile.owner = name faction.tracks = tdict() pop, res = compute_tracks(faction.territory, G.tiles) faction.tracks.POP = pop faction.tracks.RES = res faction.tracks.IND = config.initial_ind faction.units = tdict() faction.hand = tset() # for cards faction.technologies = tset() faction.secret_vault = tset() faction.influence = tset() faction.diplomacy = tdict() faction.diplomacy.associates = tset() faction.diplomacy.protectorates = tset() faction.diplomacy.satellites = tset() faction.diplomacy.violations = tset() players[name] = faction G.players = players # load minors/diplomacy minors = tdict() majors = tdict() status = tdict() for name, team in G.nations.designations.items(): if team not in G.nations.groups: G.nations.groups[team] = tset() G.nations.groups[team].add(name) if team in {minor_designation, 'Major'}: status[name] = tdict() status[name].is_armed = False status[name].units = tdict() if team == minor_designation: # only minors minor = tdict() minor.faction = None minor.value = 0 minors[name] = minor if team == 'Major': # only includes neutral majors major = tdict() major.faction = None major.value = 0 majors[name] = major G.diplomacy = tdict() G.diplomacy.minors = minors G.diplomacy.majors = majors G.diplomacy.neutrals = minors.copy() G.diplomacy.neutrals.update(majors) G.diplomacy.influence = tdict() G.nations.status = status
def movement_phase(G, player=None, action=None): if 'battles' not in G.temp: # pseudo prephase new_movement(G, player) if player is None: # when returning from some interrupting phase return encode_movement(G) faction = G.players[player] cmd = G.temp.commands[player] head, *tail = action if head in faction.secret_vault: reveal_tech(G, player, head) elif head in faction.stats.rivals: # TODO: use lazy threats - declarations only take effect when aggressing # declaration_of_war(G, player, head) G.temp.threats.add(head) G.logger.write('{} has declared war on {}'.format(player, head)) elif head in G.diplomacy.neutrals: # TODO: use lazy threats - declarations only take effect when aggressing # violation_of_neutrality(G, player, head) G.temp.threats.add(head) G.logger.write( '{} has threatened to violate the neutrality of {}'.format( player, head)) elif head in faction.units: destination, *border = tail if len(border): a = destination b = border[0] key = encode_tuple_key(a, b) if a < b else encode_tuple_key(b, a) if key not in G.temp.borders[player]: G.temp.borders[player][key] = 0 G.temp.borders[player][key] += 1 # if border[0] not in G.temp.borders[player]: # G.temp.borders[player][border[0]] = 0 # G.temp.borders[player][border[0]] += 1 unit = faction.units[head] G.temp.has_moved[head] = unit.tile source = G.tiles[unit.tile] source.units.remove(unit._id) dest = G.tiles[destination] if 'threats' in G.temp: if 'alligence' in dest: owner = '' if 'owner' in dest and dest.owner in G.temp.threats: # controlled by player owner = dest.owner assert owner in G.players, 'how can {} be in threats'.format( owner) declaration_of_war(G, player, owner) G.temp.threats.remove(owner) else: owner = dest.alligence if owner in G.temp.threats: # nation assert owner in G.nations.status, '{} mistaken as minor/major'.format( owner) violation_of_neutrality(G, player, owner) G.temp.threats.remove(owner) elif dest.type in ['Sea', 'Ocean']: pp = powers_present(G, dest) for p in pp: if p in G.temp.threats: declaration_of_war(G, player, p) G.temp.threats.remove(p) break new_battle, engaging, disengaging = eval_movement( G, source, unit, dest) if new_battle: G.temp.battles[destination] = player if engaging or disengaging: assert len(border) or G.units.rules[ unit. type].type != 'G', 'no border was tracked, but unit is {}'.format( 'engaging' if engaging else 'disengaging') move_unit(G, unit, destination) # decrement command points cmd.value -= 1 G.logger.write( '{} moves a unit from {} to {} ({} command points remaining)'. format(player, source._id, destination, cmd.value)) elif head == 'pass': cmd.value = 0 #-= 1 relinquish restl commands TODO: change back if fe G.logger.write('{} passes ({} command points remaining)'.format( player, cmd.value)) if cmd.value > 0: # continue movement return encode_movement(G) # movement complete del G.temp.commands[player] G.logger.write('{} movement is complete'.format(player)) conflicts = tset() for uid, unit in faction.units.items(): tile = G.tiles[unit.tile] if 'disputed' in tile: conflicts.add(unit.tile) elif tile.type in {'Sea', 'Ocean'}: #check if faction and enemy on same tile! #in that case, add this tile to battles powers = powers_present(G, tile) for p in powers: if p in G.temp.threats: G.temp.battles[tile._id] = player G.temp.active_idx += 1 if len(G.temp.battles) or len(conflicts): # add combat phase G.temp.potential_battles = conflicts G.temp.attacker = player # either interrupt or add next if len(G.temp.commands): # theres another movement phase after this raise PhaseInterrupt('Combat') else: add_next_phase(G, 'Combat') raise PhaseComplete else: del G.temp.battles if not len(G.temp.commands): # this season is complete add_next_phase(G, 'Supply') raise PhaseComplete new_movement(G, player) return encode_movement(G)
def planning_phase(G, player, action): if action is None: if 'temp' in G: del G.temp G.temp = tdict() G.temp.season = G.game.sequence[G.game.index] G.temp.active_idx = 0 G.temp.active_players = G.game.turn_order.copy() if G.temp.season == 'Winter': G.temp.active_players = tlist(p for p in G.game.turn_order if G.players[p].stats.enable_Winter) G.temp.decision = tdict() G.temp.passes = 0 G.temp.borders = tdict({p: tdict() for p in G.players}) return encode_command_card_phase(G) faction = G.players[player] head, *tail = action if head == 'pass': G.temp.passes += 1 G.temp.active_idx += 1 G.temp.active_idx %= len(G.temp.active_players) G.logger.write('{} passes'.format(player)) elif head in faction.hand: G.temp.passes = 0 card = G.objects.table[head] del card.owner G.objects.updated[head] = card G.temp.decision[player] = card faction.hand.remove(head) G.logger.write('{} plays a card'.format(player)) G.temp.active_players.remove(player) if len(G.temp.active_players): G.temp.active_idx %= len(G.temp.active_players) if len(G.temp.active_players) > G.temp.passes: return encode_command_card_phase(G) # evaluate card choices G.temp.commands = tdict() for p, card in G.temp.decision.items( ): # RULE OVERRULED: emergency priority tie breaks are automatic if 'season' in card: cmd = tdict() cmd.priority = card.priority cmd.moved = tset() if card.season == G.temp.season: val = card.value msg = ' {} command: {} {}'.format(card.season, card.priority, val) else: cmd.emergency = True val = G.players[p].stats.emergency_command msg = 'n emergency command: {} {}'.format(card.priority, val) cmd.value = val G.temp.commands[p] = cmd else: msg = ' bluff (investment card)' G.logger.write('{} has played a{}'.format(p, msg)) discard_cards(G, card._id) if len(G.temp.commands): ##someone played cmd card ##players put in order of cards: G.temp.order contains players G.temp.order = tlist( k for k, v in sorted([(k, v.priority + ('e' if 'emergency' in v else '')) for k, v in G.temp.commands.items()], key=lambda x: x[1])) G.logger.write('Play order is: {}'.format(', '.join(G.temp.order))) G.temp.active_idx = 0 add_next_phase(G, 'Movement') else: G.logger.write('No player played a command card during {}'.format( G.temp.season)) raise PhaseComplete
def governmnet_phase(G, player, action): # play cards if action is None: # prep influence G.logger.write('Beginning Government Phase') if 'temp' in G: del G.temp G.temp = tdict() G.temp.diplomacy = tdict() G.temp.diplomacy_cards = tset() G.temp.intel = tdict() G.temp.past_upgrades = tdict() for player in G.players: G.temp.past_upgrades[player] = 0 G.temp.passes = 0 G.temp.active_idx = 0 return encode_government_actions(G) if 'move_to_post' in G.temp: # after phase has ended and only clean up is necessary return government_post_phase(G, player, action) # TODO: make sure cards that should now be visible stay visible if player in G.temp.intel: # hide any temporarily visible objects from intel cards for ID, obj in G.temp.intel[player].items(): obj.visible.discard(player) G.objects.updated[ID] = obj del G.temp.intel[player] if 'hack' in G.temp: if player == G.temp.hack.source: raise NotImplementedError assert action == ( 'cancel', ), 'Misunderstood action: {}'.format(action) G.players[player].hand.add( G.temp.hack.card._id ) # make sure card is back in sources's ownership del G.temp.hack return encode_government_actions(G) else: actions = resolve_intel(G, player, action) if actions is not None: return actions elif 'mole' in G.temp: if action != ('accept', ): _, tech, _ = action G.logger.write('{} uses their mole to achieve {}'.format( player, tech), player=G.temp.mole) achieve_tech(G, player, *action) del G.temp.mole elif 'factory_upgrade' in G.temp: if action == ('cancel', ): G.logger.write('Cancelled factory upgrade', player=player) del G.temp.factory_upgrade return encode_government_actions(G) ID, = action val = G.objects.table[ID].value if ID in G.temp.factory_upgrade.selects: val = -val G.temp.factory_upgrade.selects.discard(ID) G.logger.write('Unselected {}'.format(ID), end='', player=player) else: G.temp.factory_upgrade.selects.add(ID) G.logger.write('Selected {}'.format(ID), end='', player=player) G.temp.factory_upgrade.value += val G.logger.write(' (value so far: {}/{})'.format( G.temp.factory_upgrade.value, G.players[player].stats.factory_cost), player=player) # print(G.temp.factory_upgrade.value) if G.temp.factory_upgrade.value < G.players[player].stats.factory_cost: return encode_factory_upgrade_actions(G) # factory upgrade complete G.players[player].tracks.IND += 1 G.temp.past_upgrades[player] += 1 G.players[player].hand -= G.temp.factory_upgrade.selects G.logger.write( '{} upgrades their IND to {} with factory card values of: {}'. format( player, G.players[player].tracks.IND, ', '.join( str(G.objects.table[ID].value) for ID in G.temp.factory_upgrade.selects))) discard_cards(G, *G.temp.factory_upgrade.selects) del G.temp.factory_upgrade G.temp.passes = 0 elif action == ('pass', ): G.logger.write('{} passes'.format(player)) G.temp.passes += 1 if G.temp.passes == len(G.players): G.logger.write( 'All players have passed consecutively - moving on to Government resolution' ) G.temp.move_to_post = tdict() # for handsize limit options for name, faction in G.players.items(): handsize = len(faction.hand) diff = handsize - faction.stats.handlimit if diff > 0: G.logger.write('{} must discard {} cards'.format( name, diff)) G.temp.move_to_post[name] = True return government_post_phase(G) else: # execute action head, *tail = action if head == 'factory_upgrade': G.temp.factory_upgrade = tdict() G.temp.factory_upgrade.value = 0 G.temp.factory_upgrade.selects = tset() G.logger.write('Select the cards to use for the factory upgrade', player=player) return encode_factory_upgrade_actions(G) elif head in G.players[ player].secret_vault: # reveal tech from secret vault reveal_tech(G, player, head) return encode_government_actions(G) elif head == 'remove': nation, = tail decrement_influence(G, nation) G.logger.write('{} removes one of their influence from {}'.format( player, nation)) return encode_government_actions(G) elif head in {'open', 'secret'}: G.temp.passes = 0 achieve_tech(G, player, head, *tail) else: G.temp.passes = 0 card = G.objects.table[head] if 'wildcard' in card: nation, = tail increment_influence(G, player, nation) extra = '' if card.wildcard == 'Foreign_Aid': # pay IND G.players[player].tracks.IND -= 1 extra = ' (decreasing IND to {})'.format( G.players[player].tracks.IND) G.logger.write( '{} plays {} adding/removing influence in {}{}'.format( player, card.wildcard, nation, extra)) discard_cards(G, head) elif 'intelligence' in card: discard_cards(G, head) return play_intel(G, player, card, *tail) else: nation, = tail play_diplomacy(G, player, nation) G.temp.diplomacy_cards.add(head) card.visible = xset(G.players.keys()) # visible to everyone G.players[card.owner].hand.discard(card._id) del card.owner G.objects.updated[head] = card # discard_cards(G, head) G.temp.active_idx += 1 G.temp.active_idx %= len(G.players) return encode_government_actions(G)
def planning_phase(G, player, action): faction = G.players[player] head, *tail = action if head == 'pass': G.temp.passes += 1 G.temp.active_idx += 1 G.temp.active_idx %= len(G.temp.active_players) G.logger.write('{} passes'.format(player)) elif head in faction.hand: G.temp.passes = 0 card = G.objects.table[head] # if 'owner' del card.owner G.objects.updated[head] = card G.temp.decision[player] = card faction.hand.remove(head) G.logger.write('{} plays a card'.format(player)) G.temp.active_players.remove(player) if len(G.temp.active_players): G.temp.active_idx %= len(G.temp.active_players) if len(G.temp.active_players) > G.temp.passes: return encode_command_card_phase(G) # evaluate card choices if len(G.temp.decision) == 0: return #raise PhaseComplete G.temp.commands = tdict() for p, card in G.temp.decision.items( ): # RULE OVERRULED: emergency priority tie breaks are automatic if 'season' in card: cmd = tdict() cmd.priority = card.priority cmd.moved = tset() cmd.declarations = tset() if card.season == G.temp.season: val = card.value msg = ' {} command: {} {}'.format(card.season, card.priority, val) else: cmd.emergency = True val = G.players[p].stats.emergency_command msg = 'n emergency command: {} {}'.format(card.priority, val) cmd.value = val G.temp.commands[p] = cmd else: msg = ' bluff (investment card)' G.logger.write('{} has played a{}'.format(p, msg)) discard_cards(G, card._id) if len(G.temp.commands): G.temp.order = tlist( k for k, v in sorted([(k, v.priority + ('e' if 'emergency' in v else '')) for k, v in G.temp.commands.items()], key=lambda x: x[1])) G.logger.write('Play order is: {}'.format(', '.join(G.temp.order))) G.temp.active_idx = 0 else: G.logger.write('No player played a command card during {}'.format( G.temp.season))
def load_players_and_minors(G): player_setup = load('config/faction_setup.yml') nations = tdict() minor_designation = 'Minor' for tile in G.tiles.values(): if 'alligence' in tile: nations[tile.alligence] = minor_designation G.nations = nations # map nationality to faction/minor # load factions/players players = tdict() groups = tset(player_setup.keys()) rivals = tdict() for g in groups: gps = groups.copy() gps.remove(g) rivals[g] = list(gps) for name, config in player_setup.items(): faction = tdict() faction.stats = tdict() faction.stats.handlimit = config.Handlimit faction.stats.factory_all_costs = config.FactoryCost faction.stats.factory_idx = 0 faction.stats.factory_cost = faction.stats.factory_all_costs[ faction.stats.factory_idx] faction.stats.emergency_command = config.EmergencyCommand faction.stats.DoW = tdict() faction.stats.DoW[rivals[name][0]] = False faction.stats.DoW[rivals[name][1]] = False faction.stats.enable_USA = 'enable_USA' in config faction.stats.enable_Winter = 'enable_Winter' in config faction.cities = tdict() faction.cities.MainCapital = config.MainCapital faction.cities.SubCapitals = config.SubCapitals faction.members = tdict() for nation, info in config.members.items(): nations[nation] = name faction.members[nation] = tset([nation]) if 'Colonies' in info: faction.members[nation].update(info.Colonies) faction.homeland = tset() faction.territory = tset() full_cast = tset() for members in faction.members.values(): full_cast.update(members) for tile_name, tile in G.tiles.items(): if 'alligence' not in tile: continue if tile.alligence in faction.members: # homeland faction.homeland.add(tile_name) if tile.alligence in full_cast: faction.territory.add(tile_name) faction.tracks = tdict() pop, res = compute_tracks(faction.territory, G.tiles) faction.tracks.pop = pop faction.tracks.res = res faction.tracks.ind = config.initial_ind faction.units = tdict() faction.hand = tset() # for cards faction.influence = tdict() players[name] = faction G.players = players # load minors/diplomacy minors = tdict() for name, team in nations.items(): if team == minor_designation: minor = tdict() minor.units = tset() minor.is_armed = False minor.influence_faction = None minor.influence_value = 0 minors[name] = minor G.minors = minors
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)