예제 #1
0
def achieve_tech(G, player, pub, tech, *cIDs):
	
	if pub == 'open':
		G.players[player].technologies.add(tech)
		G.logger.write('{} has achieved {}'.format(player, tech))
	elif pub == 'secret':
		G.players[player].secret_vault.add(tech)
		G.players[player].stats.handlimit -= 1
		G.logger.write('{} has placed a technology in their secret vault ({} handlimit is now {})'.format(
			player, player, G.players[player].stats.handlimit))
		G.logger.write('- You can reveal {} from your vault anytime during your turn'.format(tech), player=player)
	
	discard_cards(G, *cIDs)
	
	
	pass
예제 #2
0
파일: command.py 프로젝트: felixludos/tnt
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
예제 #3
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:
            # G.temp.move_to_post[player] = False
            #deactivate removing influence!!!
            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
    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:

                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) #@@@@
                    G.players[inf.faction].diplomacy[diplvl[
                        dipl.value]].remove(nation)

            faction = G.players[inf.faction]
            faction.diplomacy[diplvl[val]].add(nation)

            dipl.faction = inf.faction
            dipl.value = val

            if val >= 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)

            if nation == 'USA' and not faction.stats.enable_USA:
                G.logger.write('{} has {} influence in the USA'.format(
                    inf.faction, inf.value))
            else:
                dname = dipname[val]
                G.logger.write('{} becomes {} of {}{}'.format(
                    nation, dname, inf.faction, tmsg))

    G.temp.new_sats = new_sats

    if len(new_sats):  # plan a satellite phase to place garrison troops
        add_next_phase(G, 'Satellite')

    raise PhaseComplete
예제 #4
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)
예제 #5
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
예제 #6
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))
예제 #7
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