示例#1
0
def knock_out(agent_a, agent_b):
    """Handle KO of first agent in line."""
    Printer.print_ui('  {} is knocked out!'.format(agent_a.name))
    Printer.delay_ui(2)
    Printer.print_ui('  {} jumps into battle.'.format(agent_b.name))
    agent_b.strategy.set_order_info(True)
    return agent_b
示例#2
0
def perform(user, other):
    """Perform Mimic."""
    move = other.stats['Previous move']
    if move is not None:
        Printer.print_ui('  {} mimics {} using {}.'.format(user.name, other.name, move.NAME))
        Printer.delay_ui(1)
        user.stats['Previous move'] = move
        move.perform(user, other)
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#3
0
def perform(user, other):
    """Perform Sing."""
    try:
        Printer.print_ui('  ♪ The sound of {} singing fills the area. ♫'.format(user.name))
    except UnicodeEncodeError:
        Printer.print_ui('  (la la) The sound of {} singing fills the area. (la)'.format(user.name))
    Printer.delay_ui(1)
    if random.randint(0, 99 - user.stats['Special']) > SUCCESS_RATE or \
            'Sleep' in other.stats['Effects']:
        Printer.print_ui('  It\'s ineffective!')
    else:
        Printer.print_ui('  {} is now asleep!'.format(other.name))
        other.stats['Effects'].append('Sleep')
示例#4
0
def perform(user, other):
    """Perform Glare."""
    if random.randint(0, 99) < SUCCESS_RATE:
        if random.randint(0, 99) < CRIT_RATE:
            Printer.print_ui('  It\'s super effective!')
            Printer.delay_ui(1)
            base_damage = 0.5 * user.stats['Special']
        else:
            base_damage = 0.3 * user.stats['Special']
        damage = max(1, random.randint(int(0.8 * base_damage), int(1.2 * base_damage) + 1))
        damage = min(damage, other.stats['PP'])
        Printer.print_ui('  {} loses {} PP'.format(other.name, damage))
        other.stats['PP'] -= damage
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#5
0
def perform(user, other):
    """Perform Blast."""
    if random.randint(0, 99) < SUCCESS_RATE:
        if random.randint(0, 99) < CRIT_RATE:
            Printer.print_ui('  It\'s super effective!')
            Printer.delay_ui(1)
            base_damage = max(0, 1.8 * user.stats['Special'])
        else:
            base_damage = max(0, 1.2 * user.stats['Special'] - 0.2 * other.stats['Defense'])
        damage = max(1, random.randint(int(0.8 * base_damage), int(1.2 * base_damage) + 1))
        if damage == 1:
            Printer.print_ui('  It deals {} point of damage.'.format(damage))
        else:
            Printer.print_ui('  It deals {} points of damage.'.format(damage))
        other.stats['HP'] -= damage
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#6
0
def perform(user, other):
    """Perform Drain."""
    if random.randint(0, 99) < SUCCESS_RATE:
        if random.randint(0, 99) < CRIT_RATE:
            Printer.print_ui('  It\'s super effective!')
            Printer.delay_ui(1)
            base_damage = max(0, 1.2 * user.stats['Special'])
        else:
            base_damage = max(
                0, user.stats['Special'] - 0.2 * other.stats['Defense'])
        damage = min(
            max(
                1,
                random.randint(int(0.8 * base_damage),
                               int(1.2 * base_damage) + 1)), other.stats['HP'])
        Printer.print_ui('  {} drains {} HP from {}.'.format(
            user.name, damage, other.name))
        other.stats['HP'] -= damage
        user.stats['HP'] = min(user.stats['Max HP'], user.stats['HP'] + damage)
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#7
0
def finally_perform(user, other):
    """Finally do the Focus hit."""
    user.stats['Effects'].remove('Focus')
    Printer.print_ui('  {} attacks with all its might!'.format(user.name))
    Printer.delay_ui(1)
    if random.randint(0, 99) < SUCCESS_RATE:
        if random.randint(0, 99) < CRIT_RATE:
            Printer.print_ui('  It\'s super effective!')
            Printer.delay_ui(1)
            base_damage = max(0, 1.8 * user.stats['Strength'] - 0.8 * other.stats['Defense'])
        else:
            base_damage = max(0, 1.8 * user.stats['Strength'] - 1.2 * other.stats['Defense'])
        damage = max(1, random.randint(int(0.8 * base_damage), int(1.2 * base_damage + 1)))
        if damage == 1:
            Printer.print_ui('  It deals {} point of damage.'.format(damage))
        else:
            Printer.print_ui('  It deals {} points of damage.'.format(damage))
        other.stats['Recent damage'] = damage
        other.stats['HP'] -= damage
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#8
0
def perform(user, other):
    """Perform Counter."""
    if random.randint(0, 99) < SUCCESS_RATE:
        if random.randint(0, 99) < CRIT_RATE:
            Printer.print_ui('  It\'s super effective!')
            Printer.delay_ui(1)
            base_damage = max(0, user.stats['Recent damage'] + \
                    user.stats['Strength'] - 0.5 * other.stats['Defense'])
        else:
            base_damage = max(0, 0.5 * user.stats['Recent damage'] + \
                    user.stats['Strength'] - other.stats['Defense'])
        damage = max(
            1,
            random.randint(int(0.8 * base_damage), int(1.2 * base_damage + 1)))
        if damage == 1:
            Printer.print_ui('  It deals {} point of damage.'.format(damage))
        else:
            Printer.print_ui('  It deals {} points of damage.'.format(damage))
        other.stats['Recent damage'] = damage
        other.stats['HP'] -= damage
    else:
        Printer.print_ui('  It\'s ineffective!')
示例#9
0
def process_effects(agent_cur):
    """Process all status effects that may affect the current player.

    :param agent_cur: agent (AI instance) that needs to have effects inflicted
    :return: returns a pair of boolean values (will_die, will_continue), stating whether to KO the
    the agent or skip turn, respectively"""
    will_die, will_skip = False, False
    agent_cur.stats['Defense'] = agent_cur.stats['Base Defense']
    if 'Sleep' in agent_cur.stats['Effects']:
        if 'Focus' in agent_cur.stats['Effects']:
            agent_cur.stats['Effects'].remove('Focus')
        if sing.wakeup():
            Printer.print_ui('  {} wakes up!'.format(agent_cur.name))
            agent_cur.stats['Effects'].remove('Sleep')
            Printer.delay_ui(1)
        else:
            try:
                Printer.print_ui('  {} is still asleep. 💤'.format(
                    agent_cur.name))
            except UnicodeEncodeError:
                Printer.print_ui('  {} is still asleep. *Zzz*'.format(
                    agent_cur.name))
            will_skip = True
    if 'Poison' in agent_cur.stats['Effects']:
        damage = poison.latent(agent_cur)
        try:
            Printer.print_ui('  {} loses {} HP due to Poison! ☠'.format(
                agent_cur.name, damage))
        except UnicodeEncodeError:
            Printer.print_ui('  {} loses {} HP due to Poison!'.format(
                agent_cur.name, damage))
        agent_cur.stats['HP'] -= damage
        Printer.delay_ui(1)
        if agent_cur.stats['HP'] <= 0:
            will_die = True
    if 'Disable' in agent_cur.stats['Effects']:
        Printer.print_ui('  {} is Disabled.'.format(agent_cur.name))
        Printer.delay_ui(1)
    # Focus not processed here
    return will_die, will_skip
示例#10
0
def run_battle(agent_fst_a, agent_snd_a, agent_fst_b, agent_snd_b):
    """Have two players fight each other."""
    Printer.delay_ui(1)
    Printer.print_ui(
        '============================================================')
    Printer.print_ui('  {} is walking...'.format(agent_fst_a.name))
    Printer.delay_ui(1)
    Printer.print_ui('        ...a wild {} appears!'.format(agent_snd_a.name))
    turn_number = 0
    max_turns = 80
    current_player = 2
    agent_fst, agent_snd = agent_fst_a, agent_snd_a
    # player turns
    while turn_number < max_turns:
        turn_number += 1
        # determine who plays now
        current_player = 3 - current_player
        if current_player == 1:
            agent_cur, agent_oth = agent_fst, agent_snd
        else:
            agent_cur, agent_oth = agent_snd, agent_fst
        # UI
        Printer.delay_ui(1)
        write_stats(turn_number, agent_fst, agent_snd)
        Printer.delay_ui(1)
        # status effects logic
        will_die, will_continue = process_effects(agent_cur)
        if will_die:
            current_player = 3 - current_player
            if agent_cur == agent_fst_a:
                agent_fst = knock_out(agent_fst_a, agent_fst_b)
                continue
            elif agent_cur == agent_snd_a:
                agent_snd = knock_out(agent_snd_a, agent_snd_b)
                continue
            else:
                # agent_cur = agent_oth
                break
        if will_continue:
            continue
        # pass status information to current player
        agent_cur.give_stats_info(agent_oth.stats)
        # player makes decision, unless delayed move
        if 'Focus' in agent_cur.stats['Effects']:
            focus.finally_perform(agent_cur, agent_oth)
            if agent_oth.stats['HP'] <= 0:
                if agent_oth == agent_fst_a:
                    current_player = 3 - current_player
                    agent_fst = knock_out(agent_fst_a, agent_fst_b)
                    continue
                elif agent_oth == agent_snd_a:
                    current_player = 3 - current_player
                    agent_snd = knock_out(agent_snd_a, agent_snd_b)
                    continue
            else:
                continue
        action, detail = agent_cur.choose_action()
        # process the player's decision
        if action == Action.PERFORM_MOVE:  # use move
            if detail < 0 or detail >= MOVE_COUNT:
                Printer.print_ui(
                    '  {} tries to perform a move, but stumbles!'.format(
                        agent_cur.name))
            else:
                move = MOVES[agent_cur.stats['Moves'][detail]]
                Printer.print_ui('  {} uses {}.'.format(
                    agent_cur.name, move.NAME))
                Printer.delay_ui(1)
                if agent_cur.stats['PP'] < move.PP_COST:
                    Printer.print_ui(
                        '  But {} does not have enough PP!'.format(
                            agent_cur.name))
                elif 'Disable' in agent_cur.stats[
                        'Effects'] and move.CAN_DISABLE:
                    Printer.print_ui('  But {} is Disabled!'.format(
                        agent_cur.name))
                else:
                    agent_cur.stats['PP'] -= move.PP_COST
                    agent_cur.stats['Previous move'] = move
                    move.perform(agent_cur, agent_oth)
                    if agent_oth.stats['HP'] <= 0:
                        if agent_oth == agent_fst_a:
                            agent_fst = knock_out(agent_fst_a, agent_fst_b)
                            current_player = 3 - current_player
                            continue
                        elif agent_oth == agent_snd_a:
                            agent_snd = knock_out(agent_snd_a, agent_snd_b)
                            continue
                        else:
                            break
        elif action == Action.USE_ITEM:  # use item
            if detail < 0 or detail >= MAX_ITEMS:
                Printer.print_ui(
                    '  {} tries to use an item, but stumbles!'.format(
                        agent_cur.name))
            else:
                item_index = agent_cur.stats['Items'][detail]
                if item_index == -1:
                    Printer.print_ui('  {} tries to use an item, but it\'s not ' \
                             'there!'.format(agent_cur.name))
                else:
                    item = ITEMS[item_index]
                    if item.NAME[0] in ['A', 'E', 'I', 'O', 'U']:
                        Printer.print_ui('  {} uses an {}'.format(
                            agent_cur.name, item.NAME))
                    else:
                        Printer.print_ui('  {} uses a {}.'.format(
                            agent_cur.name, item.NAME))
                    item.use(agent_cur, agent_oth)
                    agent_cur.stats['Items'][detail] = -1
        elif action == Action.BLOCK:  # block
            Printer.print_ui('  {} blocks.'.format(agent_cur.name))
            # temporary increase in Defense
            agent_cur.stats['Defense'] += randint(8, 12)
            # restore 3 to 5 PP
            agent_cur.stats['PP'] = min(agent_cur.stats['Max PP'],
                                        agent_cur.stats['PP'] + randint(3, 5))
        else:
            Printer.print_ui('  {} stumbles!'.format(agent_cur.name))

    Printer.delay_ui(1)
    Printer.print_ui()
    Printer.print_ui()
    Printer.print_ui('  Match over!')
    if agent_fst.stats['HP'] > 0 and agent_snd.stats['HP'] > 0:
        current_player = 0
    Printer.print_ui(
        '============================================================')
    # Printer.print_ui()
    return current_player