From d97b5b9fb7efb10744a83356ac9f54576dd8e3b6 Mon Sep 17 00:00:00 2001 From: markojozsef Date: Wed, 16 Sep 2026 18:52:00 +0200 Subject: [PATCH] =?UTF-8?q?bugfixek=20=C3=A9s=20chatgpt=20teszt=20csatamen?= =?UTF-8?q?et?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bullshit.py | 199 ++++++++++++++++++++++++++++++++++++++++++---------- src/menu.py | 11 ++- 2 files changed, 167 insertions(+), 43 deletions(-) diff --git a/bullshit.py b/bullshit.py index c4edf77..069d5d5 100644 --- a/bullshit.py +++ b/bullshit.py @@ -62,7 +62,7 @@ class Action: self.who.atb = self.who.max_atb - if target.ko: + if target.ko and self.status.ko != 2: print(f" -> {target.name} is KO'd, move cancelled!") return @@ -114,65 +114,192 @@ class Action: target.def_up = False print(f" -> {target.name} got hurt and collapsed!") +# !!! CHATGPT !!! CSAK TESZT !!! enemies = [ - Combatant("Six-Seven kid", 100, 100, 100, 100, 100, 100, False, False) + # name hp atk spd dphys dfire dice absF absI + Combatant("Six-Seven kid", 120, 30, 80, 20, 0, 50, False, False), + Combatant("Ice Sprite", 60, 15, 150, 10, 0, 200, False, True ), # ice-immune, fast, fragile + Combatant("Magma Brute", 200, 40, 40, 60, 999, -50, True, False), # absorbs fire, weak to ice, slow tank ] - + party_members = [ - Combatant("Terra", 100, 100, 100, 100, 100, 100, False, False), - Combatant("Locke", 100, 100, 100, 100, 100, 100, False, False), - Combatant("Celes", 100, 100, 100, 100, 100, 100, False, False), - Combatant("Cyan", 100, 100, 100, 100, 100, 100, False, False) + # name hp atk spd dphys dfire dice absF absI + Combatant("Terra", 100, 35, 100, 30, 30, 30, False, False), + Combatant("Locke", 80, 45, 130, 15, 10, 10, False, False), # glass cannon, fast, low def + Combatant("Celes", 110, 25, 90, 50, 40, 40, False, False), # tanky + Combatant("Cyan", 130, 38, 70, 40, 20, 20, False, False), ] - + tick_counter = 0 action_queue = [] - + +# --------------------------------------------------------------------------- +# Move library — a spread of physical/elemental/status/healing effects +# --------------------------------------------------------------------------- + +def move_attack(user, target): + return Action("Attack", user, target, Damage(user.attack, 0, 0, 0), StatusChange(0, 0, 0)) + +def move_fire(user, target): + return Action("Fira", user, target, Damage(0, 45, 0, 0), StatusChange(0, 0, 0)) + +def move_ice(user, target): + return Action("Blizzara", user, target, Damage(0, 0, 45, 0), StatusChange(0, 0, 0)) + +def move_cure(user, target): + return Action("Cure", user, target, Damage(0, 0, 0, 42), StatusChange(0, 0, 0)) + +def move_defend(user, target): + return Action("Defend", user, target, Damage(0, 0, 0, 0), StatusChange(0, 0, 1)) + +def move_break(user, target): + return Action("Break", user, target, Damage(0, 0, 0, 0), StatusChange(0, 1, 0)) + +def move_death(user, target): + return Action("Death", user, target, Damage(0, 0, 0, 0), StatusChange(1, 0, 0)) + +def move_phoenix(user, target): + # revive w/ modest healing; execute() floors it at +1 HP if this isn't enough + return Action("Phoenix Down", user, target, Damage(0, 0, 0, 30), StatusChange(2, 0, 0)) + +def move_softenup(user, target): + return Action("Esuna (remove stoneskin)", user, target, Damage(0, 0, 0, 0), StatusChange(2, 0, 0)) + +MOVES = { + "attack": ("Physical attack", move_attack, True), + "fire": ("Fira (fire magic)", move_fire, True), + "ice": ("Blizzara (ice magic)", move_ice, True), + "cure": ("Cure (heal ally)", move_cure, False), + "defend": ("Defend (self def_up)", move_defend, None), # self-only, forced + "break": ("Break (inflict stone)", move_break, True), + "death": ("Death (instant KO)", move_death, True), + "phoenix": ("Phoenix Down (revive ally)",move_phoenix, False), + "unstone": ("Esuna (cure stone)", move_softenup,False), +} + +HELP_TEXT = ( + "\nAvailable moves:\n" + + "\n".join(f" {k:8s} - {v[0]}" for k, v in MOVES.items()) + + "\n help - show this list\n" +) + + +def choose_target(user, candidates, prompt): + alive = [c for c in candidates] + print(prompt) + for i, c in enumerate(alive): + tags = [] + if c.ko: tags.append("KO") + if c.stone: tags.append("STONE") + if c.def_up: tags.append("DEF_UP") + tagstr = f" [{', '.join(tags)}]" if tags else "" + print(f" {i}: {c.name} ({c.hp}/{c.maxhp} HP){tagstr}") + while True: + raw = input("Target #: ").strip() + if raw.isdigit() and 0 <= int(raw) < len(alive): + return alive[int(raw)] + print("Invalid target index.") + + +def player_turn(p): + print(f"\n{p.name} is ready to act! ({p.hp}/{p.maxhp} HP, def_up={p.def_up}, stone={p.stone})") + while True: + act = input("Action (or 'help'): ").strip().lower() + if act == "help": + print(HELP_TEXT) + continue + if act not in MOVES: + print("Unknown move. Type 'help' for the list.") + continue + + label, builder, needs_enemy_target = MOVES[act] + + if act == "defend": + return builder(p, p) + + if needs_enemy_target is True: + target = choose_target(p, enemies, "Choose an enemy target:") + elif needs_enemy_target is False: + target = choose_target(p, party_members, "Choose a party target:") + else: + target = p + + return builder(p, target) + + +import random + +def enemy_turn(e): + living = [p for p in party_members if not p.ko] + if not living: + return None + + # weighted move pool -- enemies get the same toolkit as the party + offensive = ["attack", "fire", "ice", "death"] + support = ["break"] + self_only = ["defend"] + + # if an ally is KO'd, occasionally try to revive/cure instead of attacking + ko_allies = [a for a in enemies if a.ko and a is not e] + hurt_allies = [a for a in enemies if not a.ko and a.hp < a.maxhp] + + roll = random.random() + + if ko_allies and roll < 0.15: + act = "phoenix" + target = random.choice(ko_allies) + elif hurt_allies and roll < 0.30: + act = "cure" + target = random.choice(hurt_allies) + elif not e.def_up and roll < 0.40: + act = "defend" + target = e + elif roll < 0.55: + act = "break" + target = random.choice(living) + elif roll < 0.65: + act = "death" + target = random.choice(living) + else: + act = random.choice(["attack", "fire", "ice"]) + target = random.choice(living) + + _, builder, _ = MOVES[act] + print(f" ({e.name} chooses {act} -> {target.name})") + return builder(e, target) + + while True: - print(f"Tick #{tick_counter}!") - + print(f"\n=== Tick #{tick_counter} ===") + for e in enemies: if e.ko or e.stone: continue - e.atb -= 1 - if e.atb == 0: - action_queue.append(Action("Physical Attack", e, party_members[0], Damage(25,0,0,0), StatusChange(0, 0, 0))) - + if e.atb <= 0: + act = enemy_turn(e) + if act: + action_queue.append(act) + for p in party_members: if p.ko or p.stone: continue - p.atb -= 1 - if p.atb == 0: - print(f"{p.name} is ready to attack with {p.hp} health!") - should_loop = True - while should_loop: - print(f"Action(attack / heal / defend): ", end="") - act = input() - if act == "attack": - action_queue.append(Action("Physical Attack", p, enemies[0], Damage(25,0,0,0), StatusChange(0, 0, 0))) - should_loop = False - elif act == "heal": - action_queue.append(Action("Cure", p, p, Damage(0,0,0,42), StatusChange(0, 0, 0))) - should_loop = False - elif act == "defend": - action_queue.append(Action("Defend", p, p, Damage(0,0,0,0), StatusChange(0, 0, 1))) - should_loop = False - else: - print("Idk what you mean I told you attack and heal and defend are the only valid options bruh") - + if p.atb <= 0: + action_queue.append(player_turn(p)) + if len(action_queue) != 0: action = action_queue.pop(0) print(f"Executing: {action}") action.execute() - + if all(e.ko for e in enemies): print("\nVICTORY! all enemies were defeated.") break - + if all(p.ko for p in party_members): print("\nGAME OVER! the party was defeated.") break tick_counter += 1 + diff --git a/src/menu.py b/src/menu.py index 5614846..e31222a 100644 --- a/src/menu.py +++ b/src/menu.py @@ -33,16 +33,13 @@ class MenuItem: if controls.is_control_pressed(0) and self.up: # Fel self.selected = False self.up.select() - - if controls.is_control_pressed(1) and self.down: # Le + elif controls.is_control_pressed(1) and self.down: # Le self.selected = False self.down.select() - - if controls.is_control_pressed(2) and self.left: # Bal + elif controls.is_control_pressed(2) and self.left: # Bal self.selected = False self.left.select() - - if controls.is_control_pressed(3) and self.right: # Jobb + elif controls.is_control_pressed(3) and self.right: # Jobb self.selected = False self.right.select() @@ -55,4 +52,4 @@ class MenuItem: assets.sprites["cursor"], arcade.LBWH(self.x - 16, self.y - 6, 16, 16), pixelated=True - ) \ No newline at end of file + )