Example #1
0
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
Example #2
0
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
Example #3
0
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
Example #4
0
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())
Example #5
0
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)))
Example #6
0
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)
Example #7
0
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!'
Example #8
0
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))
Example #9
0
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)
Example #10
0
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)
Example #11
0
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
Example #12
0
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)
Example #13
0
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
Example #14
0
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)
Example #15
0
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))
Example #16
0
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
Example #17
0
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)