From b6501f101b3efaab7f0e5beac9d6392a273d10e2 Mon Sep 17 00:00:00 2001 From: Mal Date: Sat, 17 Sep 2022 16:05:00 +0200 Subject: [PATCH] Init --- cheaprpg.py | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100755 cheaprpg.py diff --git a/cheaprpg.py b/cheaprpg.py new file mode 100755 index 0000000..75af97e --- /dev/null +++ b/cheaprpg.py @@ -0,0 +1,248 @@ +#!/usr/bin/env python3 + +import time + + +class Unit: + def __init__(self): + self.title = 'Default Unit' + self.hp = 100 + self.hp_max = 100 + self.effects = [] + self.abilities = [] + + def add_effect(self, effect): + if self._can_effect_be_added(effect): + self.effects.append( + {'effect': effect, 'lifetime': 0} + ) + + def remove_effect_set(self, effect): + self.effects.remove(effect) + + def _can_effect_be_added(self, effect): + count = 0 + + for e in self.effects: + if e['effect'].id == effect.id: + count += 1 + + if count > effect.stags_max: + return False + + return True + + +class Mage(Unit): + def __init__(self): + Unit.__init__(self) + self.mana = 100 + self.mana_max = 100 + + +class Player(Mage): + def __init__(self): + self.target = None + self.mana = 400 + self.mana_max = 400 + + +class Ability: + def __init__(self, caster): + self.caster = caster + self.title = 'Default Ability' + self.mana_cost = 0 + self.error_message = '' + + def cast(self) -> bool: + raise Error('Cast method must be implemented!') + + +class DaggerImpact(Ability): + def __init__(self, caster): + Ability.__init__(self, caster) + self.title = 'Klingenstoß' + self.mana_cost = 150 + self.damage = 60 + + def cast(self) -> bool: + if self.caster.target is None: + self.error_message = 'Kein Ziel ausgewählt!' + return False + + self.caster.target.hp -= self.damage + self.caster.target.add_effect(EffectBleedOut()) + + return True + + +class Ui: + def show_enemies(self, enemies): + raise Error('Method must be implemented!') + + +class Cli(Ui): + def __init__(self): + Ui.__init__(self) + + def show_enemies(self, player, enemies): + enemy_names = [] + + for e in enemies: + name = e.title + + if e == player.target: + name = '[' + name + ']' + + enemy_names.append(name) + + print() + print('Vor dir stehen %s.' % (', '.join(enemy_names))) + + def make_choice(self, choices = [], callbacks = []): + if len(choices) != len(callbacks): + raise Error('Number of callbacks must equal the number of choices!') + + for i,c in enumerate(choices): + print('[%d] %s' % (i + 1, c)) + + choice = 0 + + while choice == 0: + choice = int(input('Triff deine Wahl: ')) + + if choice < 1 or choice > len(choices): + choice = 0 + else: + callbacks[choice - 1]() + + return + + +class Effect: + def __init__(self): + self.id = 0 + self.title = 'Effect' + self.stags_max = 1 + self.lifetime = 0 + + def apply_to_unit(self, unit) -> str: + raise Error('This abstract method must be implemented!') + + return 'This abstract method must be implemented!' + + +class EffectBleedOut(Effect): + def __init__(self): + Effect.__init__(self) + self.id = 1 + self.title = 'Blutung' + self.amount = 3 + self.lifetime = 5 + self.stags_max = 5 + + def apply_to_unit(self, unit): + unit.hp -= self.amount + + +class Fight: + def __init__(self, ui, player): + self.ui = ui + self.player = player + self.enemies = [] + + def add_enemy(self, enemy): + self.enemies.append(enemy) + + def start(self): + while len(self.enemies) > 0: + self.ui.show_enemies(self.player, self.enemies) + + ui.make_choice( + ['Gegner wählen', 'Fähigkeit wirken'], + [self.choose_enemy, self.choose_ability] + ) + + print('Du warst siegreich.') + + def choose_enemy(self): + choices = [] + callbacks = [] + + for e in self.enemies: + choices.append(e.title) + callbacks.append(lambda e=e: self.set_player_target(e)) + + ui.make_choice(choices, callbacks) + + def set_player_target(self, target): + self.player.target = target + print('%s ist jetzt dein Ziel.' % (target.title)) + + def choose_ability(self): + names = [] + callbacks = [] + + for a in self.player.abilities: + names.append(a.title) + callbacks.append(lambda a=a: self.cast_ability(a)) + + self.ui.make_choice(names, callbacks) + + def cast_ability(self, ability): + print('Wirke %s.' % (ability.title)) + ability.cast() + + +if __name__ == '__main__': + ui = Cli() + + player = Player() + player.abilities = [ + DaggerImpact(player) + ] + + u = Unit() + u.add_effect(EffectBleedOut()) + + dog = Unit() + dog.title = 'Räudiger Hund' + dog.hp = 20 + dog.hp_max = 20 + + dragon = Unit() + dragon.title = 'Feuerdrache' + dragon.hp = 800 + dragon.hp_max = 800 + + orc = Unit() + orc.title = 'Dämlicher Ork' + orc.hp = 350 + orc.hp_max = 350 + + fight = Fight(ui, player) + fight.add_enemy(dog) + fight.add_enemy(dragon) + fight.add_enemy(orc) + fight.start() + + while u.hp > 0: + to_be_removed = [] + + for e in u.effects: + e['effect'].apply_to_unit(u) + e['lifetime'] += 1 + + if e['lifetime'] == e['effect'].lifetime: + to_be_removed.append(e) + + for r in to_be_removed: + print(r['effect'].title, 'klingt ab.') + u.remove_effect_set(r) + + if u.hp < 0: + u.hp = 0 + + print(u.hp, end='') + + time.sleep(1)