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
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!')
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')
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!')
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!')
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!')
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!')
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!')
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
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