<script> // ---------- CONFIGURACIÓN ---------- const GRID_SIZE = 10; let grid = []; let currentTurn = "attacker"; // attacker or defender let selectedUnit = null; // x, y
def change_turn(self): self.current_turn = "defender" if self.current_turn == "attacker" else "attacker" print(f"\n🔄 Turno cambiado a self.current_turn.upper()")
def attack(self, ax, ay, dx, dy): attacker = self.grid[ax][ay] defender = self.grid[dx][dy] if not attacker or not defender: return False, "No hay unidad" if attacker.side == defender.side: return False, "No puedes atacar aliados" if attacker.side != self.current_turn: return False, "No es tu turno" if not self.in_range(ax, ay, dx, dy, attacker.range): return False, "Fuera de rango" damage = self.calculate_damage(attacker, defender, self.terrain[ax][ay], self.terrain[dx][dy]) defender.hp -= damage msg = f"attacker.icon ataca a defender.icon y causa damage de daño!" if defender.hp <= 0: msg += f" defender.icon ha muerto!" self.grid[dx][dy] = None return True, msg
function resetGame() initGrid(); placeArmies(); currentTurn = "attacker"; selectedUnit = null; updateUI(); addLog("⚔️ La batalla por Tierra comienza de nuevo. ¡Lucha!"); batalla por terra
def random_terrain(self): r = random.random() if r < 0.5: return Terrain.PLAIN elif r < 0.75: return Terrain.FOREST else: return Terrain.HILL
def play(self): while True: self.display() if self.check_victory(): break print("\nOpciones: ") print("1. Atacar (coordenadas atacante x y | defensor x y)") print("2. Terminar turno") print("3. Rendirse") opt = input("Elige: ") if opt == "3": print(f"self.current_turn se rinde. Batalla terminada.") break elif opt == "2": self.change_turn() continue elif opt == "1": try: ax, ay, dx, dy = map(int, input("Atacante (x y) y Defensor (x y): ").split()) if 0<=ax<self.size and 0<=ay<self.size and 0<=dx<self.size and 0<=dy<self.size: success, msg = self.attack(ax, ay, dx, dy) print(msg) if success: if self.check_victory(): break self.change_turn() else: print("Coordenadas inválidas") except: print("Formato incorrecto. Ejemplo: 1 0 6 7") input("\nPresiona Enter para continuar...") if == " main ": game = LandBattle(8) game.play() Características del Feature "Batalla por Tierra" ✅ Campo de batalla con terreno variable ✅ Dos facciones (Atacante/Defensor) ✅ Unidades con atributos distintos (daño, defensa, rango, HP) ✅ El terreno modifica el daño y defensa ✅ Sistema por turnos ✅ Interfaz visual para web o consola
def __str__(self): return f"self.iconself.type[0]" class LandBattle: def (self, size=8): self.size = size self.grid = [[None for _ in range(size)] for _ in range(size)] self.terrain = [[self.random_terrain() for _ in range(size)] for _ in range(size)] self.current_turn = "attacker" self.setup_armies() Terminar turno") print("3
def calculate_damage(self, attacker, defender, att_terrain, def_terrain): base = attacker.atk - defender.defense if base < 2: base = 2 damage = int(base * att_terrain["dmg_atk"] * def_terrain["dmg_def"]) + random.randint(-1, 3) return max(1, damage)
Puedes copiar el código HTML en un archivo .html y abrirlo en cualquier navegador para jugar. El script de Python se ejecuta en terminal.
// Verificar si está en rango (distancia Manhattan) function isInRange(ax, ay, dx, dy, range) return (Math.abs(ax - dx) + Math.abs(ay - dy)) <= range; Ejemplo: 1 0 6 7") input("\nPresiona Enter para continuar
// Terrenos const TERRAIN = PLAIN: name: "🌾", dmgModAttacker: 1.0, dmgModDefender: 1.0, defBonus: 0 , FOREST: name: "🌲", dmgModAttacker: 0.9, dmgModDefender: 1.1, defBonus: 2 , HILL: name: "⛰️", dmgModAttacker: 1.15, dmgModDefender: 0.95, defBonus: 1 ;
// Cambiar turno function endTurn() if (checkVictory()) addLog("⚜️ La batalla ha terminado. Reinicia para seguir jugando."); return; currentTurn = (currentTurn === "attacker") ? "defender" : "attacker"; selectedUnit = null; updateUI(); addLog(`🔄 Turno cambiado: $currentTurn === "attacker" ? "ATACANTE 🔥" : "DEFENSOR 🛡️"`);
// Calcular daño con terreno function calculateDamage(attacker, defender, attackerTerrain, defenderTerrain) let baseDmg = attacker.baseAtk - defender.baseDef; if (baseDmg < 2) baseDmg = 2; let terrainAtkMod = attackerTerrain.dmgModAttacker; let terrainDefMod = defenderTerrain.dmgModDefender; let finalDamage = Math.floor(baseDmg * terrainAtkMod * terrainDefMod); finalDamage += Math.floor(Math.random() * 4); // azar pequeño if (finalDamage < 1) finalDamage = 1; return finalDamage;
// Atacar function attack(attackerX, attackerY, defenderX, defenderY) const attackerCell = grid[attackerX][attackerY]; const defenderCell = grid[defenderX][defenderY]; if (!attackerCell.unit
// Contar unidades restantes function countUnits(side) let count = 0; for (let i = 0; i < GRID_SIZE; i++) for (let j = 0; j < GRID_SIZE; j++) if (grid[i][j].side === side && grid[i][j].unit !== null) count++; return count;
Atrodo, jūs dar nieko nepasirinkote :)