Esempio n. 1
0
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)
Esempio n. 2
0
def encode_post_gov_actions(G):

    code = adict()

    for player, is_active in G.temp.move_to_post.items():
        faction = G.players[player]

        handsize = len(faction.hand)
        if not is_active and handsize <= faction.stats.handlimit:
            continue

        options = xset()

        if handsize > faction.stats.handlimit:

            for cid in faction.hand:
                options.add((cid, ))

            # options.update(faction.hand.copy())
            #
            # options = xset((options,))

        if is_active:
            options.add(('accept', ))

            # reveal techs from secret vault
            options.update(check_revealable(G, player))

            # removable nations
            options.add((removable_nations(G, player), ))

        code[player] = options

    for player in G.players:
        if player not in code and player in G.temp.move_to_post:
            del G.temp.move_to_post[player]

    return code
Esempio n. 3
0
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))
Esempio n. 4
0
def encode_setup_actions(G):

    code = adict()

    for faction, nationality, tilenames in seq_iterate(G.temp.setup,
                                                       [None, 'cadres', None],
                                                       end=True):
        # if player is not None and faction != player:
        # 	continue

        options = placeable_units(G, faction, nationality, tilenames)

        if len(options) == 0:
            continue

        if faction not in code:
            code[faction] = xset()

        code[faction].add((nationality, options))

    if len(code) == 0:
        raise PhaseComplete

    return code
Esempio n. 5
0
def count_victory_points(G):
    points = adict({p: 0 for p in G.players})

    for name, faction in G.players.items():

        # current production level
        prod_level = compute_production_level(faction)
        points[name] += prod_level

        # control of enemy capitals
        enemy_cities = 0
        for rival, rival_faction in G.players.items():
            if rival != name:
                if rival_faction.cities.MainCapital in faction.territory:
                    enemy_cities += 1
                for subcapital in rival_faction.cities.SubCapitals:
                    if subcapital in faction.territory:
                        enemy_cities += 1

        points[name] += 2 * enemy_cities

        # count atomic research
        atomics = 0
        for tech in faction.technologies:
            if 'Atomic' in tech:
                atomics += 1
        points[name] += 1 * atomics

        # peace dividends
        points[name] += sum(faction.stats.peace_dividends)

        # subtract DoW
        DoWs = sum(faction.stats.DoW.values())
        points[name] -= DoWs

    return points
Esempio n. 6
0
def get_game_info(player):
	
	info = adict()
	
	info.game = adict()
	info.game.year = G.game.year
	info.game.phase = G.game.sequence[G.game.index]
	if 'turn_order' in G.game:
		info.game.turn_order = G.game.turn_order
	if 'winner' in G.game:
		info.game.winner = G.game.won.player
		info.game.winning_reason = G.game.won.reason
	
	info.players = adict()
	
	vps = count_victory_points(G)
	
	for p, faction in G.players.items():
		
		play = adict()
		
		play.tracks = adict()
		for track, val in faction.tracks.items():
			play.tracks[track] = val
		
		play.at_war_with = faction.stats.at_war_with
		play.DoW = faction.stats.DoW
		
		if p == player:
			play.victory_points = vps[p]
			
			reserves = adict()
			for member in faction.members.keys():
				reserves[member] = G.units.reserves[member]
			play.reserves = reserves
	
		info.players[p] = play
	
	return info
Esempio n. 7
0
 def run():
     for id in ids:
         path = os.path.join(self._path, wztype, '%d.xml' % id)
         if os.path.isfile(path):
             yield id, adict(cb(read_soup(path).find(wztype)))
Esempio n. 8
0
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
Esempio n. 9
0
def resolve_intel(G, player, response):

    card = G.temp.hack.card

    assert player == G.temp.hack.target, 'Target should be responding'

    # G.logger.write('{} plays {} targeting {}'.format(G.temp.hack.source, G.temp.hack.card.intelligence, G.temp.hack.target))

    if response != ('accept', ):  # target plays Double Agent

        ID, *args = response

        # switch target and source, update args
        G.temp.hack.target = G.temp.hack.source
        G.temp.hack.source = player
        if len(args) > 1:
            args = (args[-1], )
        G.temp.hack.args = args

        # discard double agent card
        discard_cards(G, ID)

        G.logger.write(
            'However, {} uses their double agent to reverse the effects'.
            format(player))

    target = G.temp.hack.target
    player = G.temp.hack.source
    args = G.temp.hack.args

    code = None

    if card.intelligence == 'Coup':
        nation, = args

        inf = G.diplomacy.influence[nation]

        assert inf.faction == target, 'Influence is owned by {} not the target ({})'.format(
            inf.faction, target)

        G.players[target].influence.remove(inf._id)
        del G.diplomacy.influence[nation]
        del G.objects.table[inf._id]
        G.objects.removed[inf._id] = inf

        G.logger.write('{} {} influence is removed from {}'.format(
            inf.value, target, nation))
    elif card.intelligence == 'Agent':
        tilename, = args
        tile = G.tiles[tilename]

        G.temp.intel[player] = tdict()

        for uid in tile.units:
            unit = G.objects.table[uid]
            if unit.nationality in G.players[target].members:
                unit.visible.add(player)
                G.objects.updated[uid] = unit
                G.temp.intel[player][uid] = unit

        G.logger.write('{} may view all {}\'s units in {} for one turn'.format(
            player, target, tilename))
    elif card.intelligence == 'Spy_Ring':

        cid = G.random.choice(list(G.players[target].hand))

        G.players[target].hand.remove(cid)
        G.players[player].hand.add(cid)

        pick = G.objects.table[cid]
        pick.visible.clear()
        pick.visible.add(player)
        pick.owner = player
        G.objects.updated[cid] = pick

        G.logger.write('{} steals one card from {}\'s hand'.format(
            player, target))
    elif card.intelligence == 'Sabotage':
        G.players[target].tracks.IND -= 1
        G.logger.write('{} IND is decreased to {}'.format(
            target, G.players[target].tracks.IND))
    elif card.intelligence == 'Code_Break':

        G.temp.intel[player] = tdict()

        for cid in G.players[target].hand:
            card = G.objects.table[cid]

            card.visible.add(player)

            G.temp.intel[player][cid] = card
            G.objects.updated[cid] = card

        G.logger.write('{} may view {}\'s hand for one turn'.format(
            player, target))
    elif card.intelligence == 'Mole':

        G.logger.write(
            '{} may view {}\'s secret vault, and possibly achieve a tech therein'
        )

        vault = G.players[target].secret_vault
        G.logger.write('{}\'s secret vault contains: {}'.format(
            target, ', '.join(vault)),
                       player=player)

        options = xset()

        for cid in G.players[player].hand:

            card = G.objects.table[cid]

            if card.obj_type == 'investment_card' and 'top' in card:
                if card.top in vault and is_achievable_tech(
                        G, player, card.top):
                    options.add((card.top, cid))
                if card.bottom in vault and is_achievable_tech(
                        G, player, card.bottom):
                    options.add((card.bottom, cid))

        if len(options):  # any tech can be achieved openly or in secret
            options = xset((xset(['open', 'secret']), options))

        options.add(('accept', ))

        G.temp.mole = target

        code = adict()
        code[player] = options

    else:
        raise Exception('Unknown intelligence card type: {}'.format(
            card.intelligence))

    del G.temp.hack

    return code  # is None unless mole was played
Esempio n. 10
0
def check_techs(G, player, cards):

    global_techs = xset()
    for name, faction in G.players.items():
        if name != player:
            global_techs.update(faction.technologies)

    # print(len(cards))

    science = adict({
        cid: card
        for cid, card in cards.items()
        if 'science' in card and card.year <= G.game.year
    })

    simple = adict({cid: card for cid, card in cards.items() if 'top' in card})

    # print(len(science), len(simple))
    # print(simple)

    available = adict()

    for cid, card in simple.items():
        if card.top not in available:
            available[card.top] = xset()
        available[card.top].add(cid)

        if card.bottom not in available:
            available[card.bottom] = xset()
        available[card.bottom].add(cid)

    espionage = None
    if 'Industrial_Espionage' in available:
        espionage = available['Industrial_Espionage']
        del available['Industrial_Espionage']

    # remove already discovered techs
    for tech in G.players[player].technologies:
        if tech in available:
            del available[tech]

    # remove unachievable techs (higher atomic techs)
    # print(available.keys())

    available = adict({
        t: c
        for t, c in available.items() if is_achievable_tech(G, player, t)
    })

    # print(available)

    options = xset()

    for tech, sIDs in available.items():

        topts = xset()

        if len(sIDs) > 1:
            topts.update(choose_2_from(sIDs))

        for sciID in science:
            if tech in cards[sciID].science:
                topts.add((sIDs, sciID))

        if espionage is not None and tech in global_techs:
            for eID in espionage:
                combs = sIDs.copy()
                combs.discard(eID)
                if len(combs) > 0:
                    topts.add((sIDs, eID))

        if len(topts):
            options.add((tech, topts))

    if len(options):  # any tech can be achieved openly or in secret
        options = xset([(xset(['open', 'secret']), options)])

    return options
Esempio n. 11
0
def factory_upgrade_combos(cards, cost):
    options = adict({c._id: c.value for c in cards})
    IDs, vals = zip(
        *sorted(options.items(), key=operator.itemgetter(1), reverse=True))

    return map(tuple, opposite_knapsack(IDs, options, cost))
Esempio n. 12
0
            # if 'log' in out and len(out.log):
            # 	print('<{} log>'.format(player))
            # 	print(out.log, end='')
            # 	print('</{}>'.format(player))


from flask_app import *

print(ping())

if False:

    out = format_msg_to_python(init_game(debug=True, player='Axis'))

    G = get_G()
    fixed = adict()

    # Setup + New Year
    try:
        for player in G.game.turn_order:
            fixed[player] = [('investment_card', )] * 6  # + [('action_card',)]
        players = G.game.turn_order
    except KeyError:
        players = ['Axis', 'USSR', 'West']
    print(players)

    complete_phase(players)

    path = save('setup_complete.json')
    print('Saved Setup phase at {}'.format(path))
Esempio n. 13
0
def load_gen_card_decks(
    G,
    card_config_path='config/card_stats.yml',
):

    cc = load(card_config_path)

    config = cc.action_cards
    G.action_cards = adict()

    card_list = []

    dim = 2
    num = sum(config.diplomacy.values()) // dim

    for _ in range(10):
        try:
            picks = split_choices(G, list(config.diplomacy.items()), num, dim)
        except ValueError:
            pass
        else:
            break

    wildcards = []
    for name, info in config.wildcards.items():
        for _ in range(info.count):
            card = idict(info.items())
            del card.count
            card.name = name

            wildcards.append(card)
    G.random.shuffle(wildcards)

    for season, info in config.seasons.items():

        commands = sum([[k] * v for k, v in info.commands.items()], [])
        G.random.shuffle(commands)

        if len(info.priorities) > info.count:
            priorities = G.random.choice(info.priorities,
                                         info.count,
                                         replace=False).tolist()
        else:
            priorities = info.priorities
        assert len(priorities) == info.count

        for _ in range(info.num_wildcards):
            command, priority = commands.pop(), priorities.pop()
            wildcard = wildcards.pop()

            card = idict()
            card.wildcard = wildcard
            card.command_value = command
            card.command_priority = priority
            card.season = season

            card_list.append(card)

        for command, priority in zip(commands, priorities):
            dpl1, dpl2 = picks.pop()

            card = idict()
            card.command_value = command
            card.command_priority = priority
            card.season = season

            card.top_diplomacy = dpl1
            card.bottom_diplomacy = dpl2

            card_list.append(card)

    G.action_cards.deck = card_list

    config = cc.investment_cards
    G.investment_cards = adict()

    card_list = []

    dim = 2
    num = 0

    techs = []
    for name, info in config.technologies.items():
        tech = adict(info.items())
        count = info.count
        del tech.count
        num += count
        tech.name = name
        techs.append((tech, count))

    for name, info in config.intelligence.items():
        tech = adict(info.items())
        count = info.count
        del tech.count
        num += count
        tech.name = name
        techs.append((tech, count))

    num = num // dim

    for _ in range(10):
        try:
            picks = split_choices(G, techs, num, dim)
        except ValueError:
            pass
        else:
            break

    factories = sum([[k] * v for k, v in config.factory_levels.items()], [])
    G.random.shuffle(factories)

    for pick in picks:
        tech1, tech2 = pick
        card = idict()
        card.top_technology = tech1
        card.bottom_technology = tech2
        card.factory_value = factories.pop()

        card_list.append(card)

    G.investment_cards.deck = card_list

    G.action_cards.discard_pile = []
    G.investment_cards.discard_pile = []

    G.random.shuffle(G.investment_cards.deck)
    G.random.shuffle(G.action_cards.deck)
Esempio n. 14
0
def ANS_rebase_options(G, unit):
    pts = G.units.rules[unit.type].move
    options = xset()

    if pts == 0:
        return options

    player = G.nations.designations[unit.nationality]
    tile = G.tiles[unit.tile]
    destinations = xset()
    crossings = adict()
    borders = G.temp.borders[player]  # past border crossings
    ugroup = G.units.rules[unit.type].type
    hidden_movement = ugroup == 'S' or ugroup == 'A'
    disengaging = ()  #if 'disputed' in tile else None
    fuel = pts  #brauche nur non-strategic movement!
    is_disengaging = True
    defensive = True  #das ist fuer non-strategic movement

    #actually, ugroup cannot be 'G' since this is rebasing!
    #if using it for retreat also, keep this!
    xing = crossings if ugroup == 'G' else None  #borders tracked?!?
    current = xset()

    #sea movement
    if ugroup in 'NS' or (ugroup == 'G' and tile.type
                          in movement_restrictions['sea']):  # sea movement
        fill_movement(G,
                      player,
                      tile,
                      current,
                      crossings=xing,
                      borders=borders,
                      move_type='sea',
                      fuel=fuel,
                      disengaging=disengaging,
                      friendly_only=defensive,
                      hidden_movement=hidden_movement)

        destinations.update(current)
        current = xset()

    # land movement
    if ugroup == 'G':

        fill_movement(G,
                      player,
                      tile,
                      destinations,
                      crossings=xing,
                      borders=borders,
                      move_type='land',
                      fuel=fuel,
                      disengaging=disengaging,
                      friendly_only=defensive,
                      hidden_movement=hidden_movement)

        destinations.update(current)
        current = xset()

    if ugroup == 'A':

        fill_movement(G,
                      player,
                      tile,
                      destinations,
                      crossings=xing,
                      borders=borders,
                      move_type='air',
                      fuel=fuel,
                      disengaging=disengaging,
                      friendly_only=defensive,
                      hidden_movement=hidden_movement)

        destinations.update(current)
        #air cannot rebase to sea areas!
        #eliminate those from dest

    destinations.discard(unit.tile)

    #air rebase only to land area
    if ugroup == 'A':
        destinations = [d for d in destinations if is_land_area(G, d)]

    for dest in destinations:
        if dest in crossings:
            options.add((dest, crossings[dest]))
        else:
            options.add((dest, ))

    return options
Esempio n. 15
0
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)
Esempio n. 16
0
def encode_production_actions(G):

    code = adict()

    active_player = G.game.turn_order[G.temp.active_idx]
    faction = G.players[active_player]

    options = xset()

    # pass
    options.add(('pass', ))

    # cards
    options.add(('action_card', ))
    options.add(('investment_card', ))

    ex_territory = faction.territory.copy()

    # new cadres
    for nationality, tiles in faction.homeland.items():
        groups = placeable_units(G, active_player, nationality, tiles)
        if len(groups):
            options.add((nationality, groups))

        ex_territory -= tiles

    # new fortresses
    fort_opts = adict()
    for tilename in ex_territory:
        tile = G.tiles[tilename]
        if not contains_fortress(G, tile):
            nationality = faction.stats.great_power
            for nat, lands in faction.members.items():
                if tile.alligence in lands:
                    nationality = nat
                    break
            if G.units.reserves[nationality].Fortress > 0:
                if nationality not in fort_opts:
                    fort_opts[nationality] = xset()
                fort_opts[nationality].add(tilename)
    if len(fort_opts):
        for nationality, tiles in fort_opts.items():
            options.add((nationality, tiles, 'Fortress'))

    # improve units
    improvable = xset()

    for uid, unit in faction.units.items():

        # can't upgrade a cv of 4
        if unit.cv == 4:
            continue

        tile = G.tiles[unit.tile]

        # unit must be supplied and not engaged
        if 'disputed' in tile or 'unsupplied' in tile:
            continue

        # tile must be land or coast
        if tile.type in {'Sea', 'Ocean'}:
            continue

        improvable.add(unit._id)
    improvable -= G.temp.prod[active_player].upgraded_units
    if len(improvable):
        options.add((improvable, ))

    code[active_player] = options

    return code
Esempio n. 17
0
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)
Esempio n. 18
0
def travel_options(G, unit):
    pts = G.units.rules[unit.type].move

    options = xset()

    if pts == 0:
        return options

    player = G.nations.designations[unit.nationality]

    tile = G.tiles[unit.tile]

    destinations = xset()
    crossings = adict()
    cmd = G.temp.commands[player]
    borders = G.temp.borders[player]  # past border crossings

    cls = G.units.rules[unit.type].type

    hidden_movement = cls == 'S' or cls == 'A'
    disengaging = () if 'disputed' in tile else None

    for defensive in range(
            2):  # gen all steps once with strategic movement and once without

        if defensive and ('emergency' in cmd or disengaging is not None):
            continue

        fuel = pts * (1 + defensive)

        if 'emergency' in cmd or disengaging is not None:
            defensive = True

        xing = crossings if cls == 'G' and (
            not defensive or disengaging is not None) else None

        # if defensive:
        # 	1+1

        current = xset()

        if cls in 'NS' or (cls == 'G' and tile.type
                           in movement_restrictions['sea']):  # sea movement

            fill_movement(G,
                          player,
                          tile,
                          current,
                          crossings=xing,
                          borders=borders,
                          move_type='sea',
                          fuel=fuel,
                          disengaging=disengaging,
                          friendly_only=defensive,
                          hidden_movement=hidden_movement)
            if len(crossings):
                print('CROSSINGS', crossings)
            else:
                print('*********no crossings!')
            if len(borders):
                print('BORDERS', borders)
            else:
                print('*********no borders!')
            # print(destinations)

        destinations.update(current)
        current = xset()

        if cls == 'G':  # land movement

            fill_movement(G,
                          player,
                          tile,
                          destinations,
                          crossings=xing,
                          borders=borders,
                          move_type='land',
                          fuel=fuel,
                          disengaging=disengaging,
                          friendly_only=defensive,
                          hidden_movement=hidden_movement)

        destinations.update(current)
        current = xset()

        if cls == 'A':

            if tile.type in {'Sea', 'Ocean'}:
                fuel = pts  # no strategic movement
                defensive = 1  # no engaging

            fill_movement(G,
                          player,
                          tile,
                          destinations,
                          crossings=xing,
                          borders=borders,
                          move_type='air',
                          fuel=fuel,
                          disengaging=disengaging,
                          friendly_only=defensive,
                          hidden_movement=hidden_movement)

            if tile.type in {'Sea', 'Ocean'}:
                break

        destinations.update(current)

    destinations.discard(unit.tile)

    for dest in destinations:
        if dest in crossings:
            options.add((dest, crossings[dest]))
        else:
            options.add((dest, ))

    return options
Esempio n. 19
0
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
Esempio n. 20
0
from collections import namedtuple
import traceback

from new_year import new_year_phase
from production import production_phase, production_pre_phase
from government import governmnet_phase, government_pre_phase
from command import command_phase, pre_command_phase

import json

PRE_PHASES = adict({  # all action phases
    'Setup': setup_pre_phase,
    'Production': production_pre_phase,
    'Government': government_pre_phase,
    'Spring': pre_command_phase,
    'Summer': pre_command_phase,
    'Fall': pre_command_phase,
    'Winter': pre_command_phase,

    # 'Land_Combat': None,
    # 'Naval_Combat': None,
})
PHASES = adict({
    'Setup': setup_phase,
    'New_Year': new_year_phase,
    'Production': production_phase,
    'Government': governmnet_phase,
    'Spring': command_phase,
    'Summer': command_phase,
    'Blockade': None,
    'Fall': command_phase,
    'Winter': command_phase,
Esempio n. 21
0
import json

PHASES = adict({
	'Setup': setup_phase,

    'New_Year': new_year_phase,
    'Production': production_phase,
    'Government': governmnet_phase,
    'Spring': planning_phase,
    'Summer': planning_phase,
    'Blockade': blockade_phase,
    'Fall': planning_phase,
    'Winter': planning_phase,
	
	'Satellite': satellite_phase,

	'Movement': movement_phase,

	'Combat': combat_phase,
	'Land Battle': land_battle_phase, 
	'Sea Battle': sea_battle_phase,
	'Supply': supply_phase,
	'Retreat': retreat_phase,

	'Land_Battle': land_battle_phase,
	'Naval_Battle': sea_battle_phase,
	
	'Scoring': scoring_phase,
})

# ALL game information is in the gamestate "G"
Esempio n. 22
0
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))
Esempio n. 23
0
def add_battles_to_reveal(G, player):
	#turn all units to be visible on each tile in G.temp.battles_to_reveal
	#moves revealed battles from battles_to_reveal to battles_to_fight
	#print('battles are revealed...')
	c = G.temp.combat
	for tile in c.battles_to_reveal:
		# atk = c.battles_to_reveal[tile]
		#print('...', tile, type(tile))
		units = G.tiles[tile].units
		c.battles[tile] = adict()
		c.battles_remaining.append(tile)
		b = c.battles[tile]
		b.tilename = tile
		b.tile = G.tiles[tile]
		b.isSeaBattle = b.tile.type in ['Sea', 'Ocean']
		#find owners of units on that tile
		#TODO: replace by powers_present!!!
		owners = [k for k in powers_present(G, b.tile)]

		if len(owners) != 2:
			#TODO implement 3 way battles
			#if this is the defender, needs to choose who to attack
			#for now assume that there must be exactly 2 parties in a combat
			c.ERROR = 'NOT SUPPORTED: COMBAT WITH POWERS != 2 ' + b.tilename
			pass
		
		b.owner = b.tile.owner if 'owner' in tile else None
		uidsList = [k for k in units]
		if not b.owner:
			uid = uidsList[0]
			b.owner = find_unit_owner(G, G.objects.table[uid])

		b.intruder = owners[1] if b.owner == owners[0] else owners[0]
		
		assert G.temp.attacker == player, 'ATTACKER != PLAYER!!!!!!'
		b.attacker = G.temp.attacker  #GANZ SICHER RICHTIG
		b.defender = owners[1] if b.attacker == owners[0] else owners[0]
		b.units = []

		for id in units:
			unit = G.objects.table[id]
			unit.visible = xset(G.players.keys())
			G.objects.updated[id] = unit
			attacker = b.attacker
			defender = b.defender
			uowner = find_unit_owner(G, unit)
			uopponent = defender if uowner == attacker else attacker
			utype = unit.type
			ugroup = G.units.rules[utype].type
			upriority = G.units.rules[utype].priority
			udamage = G.units.rules[utype]
			uid = id

			u_battle_group = None
			if b.isSeaBattle and b.tilename in G.temp.battle_groups and uid in G.temp.battle_groups[b.tilename]:
				u_battle_group = G.temp.battle_groups[b.tilename][uid]
			
			uff = False
			prec_bomb = False
			air_def_radar = False
			sonar = False

			u = adict()
			u.unit = unit
			u.owner = uowner
			u.group = ugroup
			u.priority = upriority
			u.rules = udamage
			u.id = uid
			u.battle_group = u_battle_group
			#modifying cards
			uff = hasFirstFire(G, uowner, utype)

			if uowner in G.players:
				tech = G.players[player].technologies

				#determine IND damage of AirForce:
				if utype == 'AirForce' and 'Jets' in tech:
					prec_bomb = True

				#	air defense radar:
				#Air Forces in Friendly Territory (1.14) Fire doubledice (two dice/CV) at Enemy Air
				if uowner == b.owner and utype == 'AirForce' and 'Air_Defense_Radar' in tech:
					air_def_radar = True

				#sonar
				if utype == 'Fleet' and 'Sonar' in tech:
					sonar = True

			u.ff = uff
			u.sonar = sonar
			u.air_def_radar = air_def_radar
			u.prec_bomb = prec_bomb
			u.type = unit.type

			#if owner of this unit is defender he goes first by default
			#u.turn 0: this unit goes before same type of opponent, otherwise 1
			u.turn = 0
			opp_has_ff = hasFirstFire(G, uopponent, utype)

			uHasFF = False
			if uowner == 'Minor':
				if not opp_has_ff:
					uHasFF = True
			elif uopponent == 'Minor':
				if u.ff:
					uHasFF = True
			elif uowner == attacker and G.players[uowner].stats.DoW[uopponent] and not opp_has_ff:
				uHasFF = True
			elif uowner == attacker and u.ff and not opp_has_ff:
				uHasFF = True
			elif uowner == defender and (u.ff or (not opp_has_ff and not G.players[uopponent].stats.DoW[uowner])):
				uHasFF = True
			u.turn = 0 if uHasFF else 1

			b.units.append(u)

		unitsSorted = sorted(b.units, key=lambda u: u.battle_group if u.battle_group else 'zzz') if b.isSeaBattle else b.units
		b.fire_order = sorted(unitsSorted, key=lambda u: u.priority * 10 + u.turn)
	c.battles_to_reveal.clear()
Esempio n. 24
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)