elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Haciendo juego muy sencillo de cartas, dudas.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Haciendo juego muy sencillo de cartas, dudas.  (Leído 308 veces)
Tachikomaia


Conectado Conectado

Mensajes: 1.551


Hackentifiko!


Ver Perfil
Haciendo juego muy sencillo de cartas, dudas.
« en: Ayer a las 00:30 »

Por ahora es que un jugador y la máquina...

Tienen puntos de vida (HP).

Obtienen 1 carta al azar cada uno. No hay mazo con cartas ordenadas de X modo, simplemente cartas posibles.

Es el turno del humano, debe usar su carta. La carta puede tener opciones.

La carta hace su efecto según cómo se especificó.

Si la IA aún tiene HP, el humano toma otra carta y es el turno de la IA, que deberá seguir el mismo proceso que el humano.
Sino, se muestra un mensaje de victoria.

Código
  1. Cartas = ["MarioDK", "DK"];
  2. // Lo anterior se usa para hacer sus efectos, esto es cómo se muestran sus nombres:
  3. ShowerDeCartas = ["Mario de Donkey Kong", "Donkey Kong"];
  4. HumanoHP = 10;
  5. IAHP = 10;
  6. // Frame 1: Se dan cartas, el mensaje no tiene saltos de línea.
  7. // F2: Un objeto repite TurnoDeHumano hasta que se presione A.
  8. NroDeCartaDeHumano = random(Cartas.length);
  9. Mensaje = "Tu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  10. NroDeCartaDeIA = random(Cartas.length);
  11. function TurnoDeHumano () {
  12. // Si se presiona A:
  13. if (Key.isDown(65)) {
  14. // Usa la carta (dando su estadística AT a la función):
  15. eval(Cartas[NroDeCartaDeHumano])(eval(Cartas[NroDeCartaDeHumano]+"AT"));
  16. }
  17. }
  18. function HumanoObtieneCarta () {
  19. NroDeCartaDeHumano = random(Cartas.length);
  20. Mensaje = Mensaje+"\n\nTu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  21. }
  22. function FinDelTurnoDeHumano () {
  23. HumanoObtieneCarta();
  24. // Turno de la IA:
  25. }
  26. function Victoria () {
  27. Mensaje = Mensaje+"\n\n¡Ganaste!";
  28. gotoAndStop (4);
  29. }
  30. // Estadísticas:
  31. MarioDKAT = 1;
  32. DKAT = 2;
  33. // Efectos:
  34. function MarioDK (ataque) {
  35. Mensaje = "¡Tu rival ha sido enjaulado!";
  36. IAHP = IAHP-ataque;
  37. if (IAHP > 0) {
  38. FinDelTurnoDeHumano();
  39. } else {
  40. Victoria();
  41. }
  42. }
  43. function DK (ataque) {
  44. Mensaje = "¡Rival dañado!";
  45. IAHP = IAHP-ataque;
  46. if (IAHP > 0) {
  47. FinDelTurnoDeHumano();
  48. } else {
  49. Victoria();
  50. }
  51. }

Quisiera que me digan cómo lo mejorarían (no en cuanto a gráficos, sonido, etc, sino el código, eficiencia y claridad) y cómo puedo hacer que los efectos de las cartas se apliquen al humano o a la IA según quién las juegue. Así como están siempre afectan a la IA.

La forma que se me ocurre es pasar un parámetro extra a las funciones, por ejemplo target, y luego meter un if para que afecten a uno u otro, pero pregunto si hay algo mejor.

Esto se repite:
Código
  1. IAHP = IAHP-ataque;
  2. if (IAHP > 0) {
  3. FinDelTurnoDeHumano();
  4. } else {
  5. Victoria();
  6. }
  7.  
Es que antes ponía 1ero el daño, luego el mensaje (que varía según la carta) y luego esos ifs, pero tengo pensado que algunas cartas hagan daño a quien las usa o den una carta extra y deba descartarse una, así que ese código dudo que pueda servir repetirlo. Bueno, en general supongo que sí.


Respuesta de Deepseek:
Citar
# Análisis y Mejoras para el Juego de Cartas

## Mejoras de Código y Estructura

1. **Eliminar duplicación de código**: El patrón de reducir HP y verificar victoria se repite. Podrías crear una función común:
```actionscript
function aplicarAtaque(target, ataque, mensajeEfecto) {
    target.HP -= ataque;
    Mensaje = mensajeEfecto;
    if (target.HP > 0) {
        FinDelTurnoDeHumano();
    } else {
        Victoria();
    }
}
```

2. **Sistema de objetivos más flexible**: En lugar de hardcodear el objetivo, puedes pasar el objetivo como parámetro:

```actionscript
function MarioDK(ataque, objetivo) {
    aplicarAtaque(objetivo, ataque, "¡Tu rival ha sido enjaulado!");
}

// Llamada:
eval(Cartas[NroDeCartaDeHumano])(eval(Cartas[NroDeCartaDeHumano]+"AT"), IA);
```

3. **Estructura de datos más organizada**: En lugar de tener arrays separados para nombres y estadísticas, podrías usar objetos:

```actionscript
Cartas = [
    {nombre: "Mario de Donkey Kong", ataque: 1, efecto: MarioDK},
    {nombre: "Donkey Kong", ataque: 2, efecto: DK}
];
```

4. **Sistema de turnos más robusto**: Implementar un sistema de gestión de turnos que alterna entre jugadores.

## Implementación Mejorada

Aquí tienes una versión mejorada que aborda estos puntos:

```actionscript
// Configuración inicial
Cartas = [
    {nombre: "Mario de Donkey Kong", ataque: 1, efecto: function(objetivo) {
        aplicarAtaque(objetivo, this.ataque, "¡Tu rival ha sido enjaulado!");
    }},
    {nombre: "Donkey Kong", ataque: 2, efecto: function(objetivo) {
        aplicarAtaque(objetivo, this.ataque, "¡Rival dañado!");
    }}
];

Jugador = {HP: 10, nombre: "Humano"};
IA = {HP: 10, nombre: "IA"};
turnoActual = Jugador;
Mensaje = "";

// Frame 1: Repartir cartas iniciales
repartirCartas();

// Frame 2: Lógica del juego
function repartirCartas() {
    NroDeCartaDeHumano = random(Cartas.length);
    NroDeCartaDeIA = random(Cartas.length);
    Mensaje = "Tu carta ahora es " + Cartas[NroDeCartaDeHumano].nombre;
}

function TurnoDeHumano() {
    if (Key.isDown(65)) { // Si se presiona A
        var carta = Cartas[NroDeCartaDeHumano];
        carta.efecto(IA); // Siempre ataca a la IA en este caso
    }
}

function aplicarAtaque(objetivo, ataque, mensajeEfecto) {
    objetivo.HP -= ataque;
    Mensaje = mensajeEfecto;
   
    if (objetivo.HP <= 0) {
        Victoria();
    } else if (turnoActual == Jugador) {
        FinDelTurnoDeHumano();
    } else {
        // Turno de la IA
        turnoIA();
    }
}

function FinDelTurnoDeHumano() {
    turnoActual = IA;
    repartirCartas();
    // La IA juega inmediatamente después
    turnoIA();
}

function turnoIA() {
    var carta = Cartas[NroDeCartaDeIA];
    carta.efecto(Jugador); // La IA siempre ataca al jugador
   
    // Volver al turno del jugador
    turnoActual = Jugador;
    repartirCartas();
}

function Victoria() {
    var ganador = (IA.HP <= 0) ? Jugador : IA;
    Mensaje = "¡" + ganador.nombre + " ha ganado!";
    gotoAndStop(4);
}
```

## Ventajas de esta implementación:

1. **Flexibilidad en objetivos**: Las funciones de efecto ahora reciben explícitamente su objetivo.
2. **Estructura más clara**: Los datos de las cartas están encapsulados en objetos.
3. **Sistema de turnos**: Más fácil de extender para más jugadores o mecánicas complejas.
4. **Menos duplicación**: La lógica común está centralizada en `aplicarAtaque`.

## Para futuras expansiones:

1. **Efectos complejos**: Puedes añadir propiedades adicionales a las cartas (como "dañoAutomatico", "curar", etc.)
2. **Selección de objetivo**: Modificar la UI para permitir elegir objetivo cuando sea relevante.
3. **Múltiples jugadores**: El sistema de turnos ya está preparado para escalar.

Esta estructura hace que sea más fácil añadir nuevos tipos de cartas con efectos variados sin tener que modificar mucho la lógica principal del juego.

Mucha cosa, lo pensaré.


En línea

Tachikomaia


Conectado Conectado

Mensajes: 1.551


Hackentifiko!


Ver Perfil
Re: Haciendo juego muy sencillo de cartas, dudas.
« Respuesta #1 en: Ayer a las 09:19 »

Apliqué la recomendación 1 más o menos:
Código
  1. Cartas = ["MarioDK", "DK"];
  2. // Lo anterior se usa para hacer sus efectos,
  3. // esto es cómo se muestran sus nombres:
  4. ShowerDeCartas = ["Mario de Donkey Kong", "Donkey Kong"];
  5. HumanoHP = 10;
  6. IAHP = 10;
  7. // Frame 1: Se dan cartas, el mensaje no tiene saltos de línea.
  8. // F2: Un objeto repite TurnoDeHumano hasta que se presione A.
  9. NroDeCartaDeHumano = random(Cartas.length);
  10. Mensaje = "Tu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  11. NroDeCartaDeIA = random(Cartas.length);
  12. function TurnoDeHumano () {
  13. // Si se presiona A:
  14. if (Key.isDown(65)) {
  15. // Usa la carta (dando su estadística AT a la función):
  16. eval(Cartas[NroDeCartaDeHumano])(eval(Cartas[NroDeCartaDeHumano]+"AT"));
  17. }
  18. }
  19. function HumanoObtieneCarta () {
  20. NroDeCartaDeHumano = random(Cartas.length);
  21. Mensaje = Mensaje+"\n\nTu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  22. }
  23. function FinDelTurnoDeHumano () {
  24. HumanoObtieneCarta();
  25. play();
  26. // Turno de la IA:
  27. }
  28. function Victoria () {
  29. Mensaje = Mensaje+"\n\n¡Ganaste!";
  30. gotoAndStop (4);
  31. }
  32. // Estadísticas:
  33. MarioDKAT = 1;
  34. DKAT = 2;
  35. // Efectos:
  36. function AplicarAtaque (ataque) {
  37. IAHP = IAHP-ataque;
  38. if (IAHP > 0) {
  39. FinDelTurnoDeHumano();
  40. } else {
  41. Victoria();
  42. }
  43. }
  44. function MarioDK (ataque) {
  45. Mensaje = "¡Tu rival ha sido enjaulado!";
  46. AplicarAtaque(ataque);
  47. }
  48. function DK (ataque) {
  49. Mensaje = "¡Rival dañado!";
  50. AplicarAtaque(ataque);
  51. }

Citar
   target.HP -= ataque;
Eso creo que no funcionaría, target debería ser una película.

El mensaje depende de la carta así que no tiene sentido meterlo en una función para todos, o no veo bien cómo lo tendría.

También debería variarse qué turno termina y de quién es la victoria.

Aunque me cuesta mucho creo que puedo hacer estas cosas, lo que no puedo es hacerlo de un modo que me parezca bien, o no veo bien cómo.

2: Pasar un objetivo es lo que había comentado, pero no imagino cómo eso quedaría bien.

3: Nunca vi algo así y por lo que anduve preguntando, no funciona en Macromedia Flash 5. No le había comentado al bot que era para eso.

4: Lo de los turnos ni siquiera lo tengo completo así que paso de eso por ahora.

Le muestro el nuevo código a GPT diciéndole que es de MF5 a ver qué me dice.

En resumen:
Citar
```actionscript
function AplicarAtaque(ataque, objetivo) {
   if (objetivo == "IA") {
      IAHP = IAHP - ataque;
      if (IAHP > 0) {
         FinDelTurnoDeHumano();
      } else {
         Victoria();
      }
   } else if (objetivo == "Humano") {
      HumanoHP = HumanoHP - ataque;
      if (HumanoHP > 0) {
         // Aquí iría el siguiente paso del juego (turno IA, etc.)
      } else {
         Derrota(); // Deberías crear esta función
      }
   }
}
```

Entonces, tus funciones de carta se pueden actualizar así:

```actionscript
function MarioDK(ataque) {
   Mensaje = "¡Tu rival ha sido enjaulado!";
   AplicarAtaque(ataque, "IA");
}
```

Y si luego la IA usa la carta contra el jugador, cambiarías:

```actionscript
function MarioDK_IA(ataque) {
   Mensaje = "¡Has sido enjaulado!";
   AplicarAtaque(ataque, "Humano");
}
```

O incluso puedes hacer que **ambas versiones usen una misma función** con el objetivo como parámetro:

```actionscript
function MarioDK(ataque, objetivo) {
   if (objetivo == "IA") {
      Mensaje = "¡Tu rival ha sido enjaulado!";
   } else {
      Mensaje = "¡Has sido enjaulado!";
   }
   AplicarAtaque(ataque, objetivo);
}
```

Y la llamarías así:

```actionscript
MarioDK(MarioDKAT, "IA"); // Si el humano ataca
MarioDK(MarioDKAT, "Humano"); // Si la IA ataca
```

---

### ✅ Ventajas de este enfoque:

- **Sin `eval`**: Usar `eval` puede hacer el código más difícil de mantener.
- **Más escalable**: Puedes agregar más jugadores, enemigos o efectos fácilmente.
- **Control total**: Puedes decidir qué pasa según el objetivo y mostrar mensajes distintos.

---

### 🧠 Consejo adicional

Si haces muchos efectos de cartas, podrías pensar en tener un sistema de cartas con objetos o arrays de objetos, por ejemplo:

```actionscript
Cartas = [
    { nombre: "MarioDK", mostrar: "Mario de Donkey Kong", ataque: 1, efecto: MarioDK },
    { nombre: "DK", mostrar: "Donkey Kong", ataque: 2, efecto: DK }
];
```

Pero eso es más avanzado y Flash 5 no tiene soporte completo para objetos complejos como en JS moderno. Aun así, puedes simularlo con arrays paralelos como ya estás haciendo.

haces esto
if (objetivo == "IA") {
al aplicar el efecto de una carta y lo vuelves a hacer al aplicar el ataque de la carta, quisiera que sólo se haga 1 vez

Citar
¡Perfecto! Si quieres **evitar repetir el `if (objetivo == "IA")`** tanto en la función del efecto como dentro de `AplicarAtaque`, la mejor forma es que `AplicarAtaque` simplemente **modifique el HP del objetivo directamente**, sin preocuparse por quién es.

### 💡 Solución: Pasar una *referencia* al HP del objetivo

En Flash 5 (ActionScript 1.0), **no puedes pasar variables por referencia** como en lenguajes modernos, pero puedes simularlo con objetos o propiedades dentro de objetos.

Así que, en lugar de pasar `"IA"` o `"Humano"`, puedes pasar un objeto que contenga el HP. Por ejemplo:

---

### 🧱 Paso 1: Crear objetos para los jugadores

```actionscript
Humano = { nombre: "Jugador", hp: 10 };
IA = { nombre: "IA", hp: 10 };
```

---

### 🧱 Paso 2: AplicarAtaque sin `ifs`

```actionscript
function AplicarAtaque(ataque, objetivo) {
   objetivo.hp = objetivo.hp - ataque;
   if (objetivo.hp > 0) {
      if (objetivo == IA) {
         FinDelTurnoDeHumano();
      } else {
         // Fin del turno de la IA (a implementar si no existe)
      }
   } else {
      if (objetivo == IA) {
         Victoria();
      } else {
         Derrota(); // Deberías definir esta función
      }
   }
}
```

---

### 🧱 Paso 3: Efectos de cartas usan sólo una línea

```actionscript
function MarioDK(ataque, objetivo) {
   Mensaje = (objetivo == IA) ? "¡Tu rival ha sido enjaulado!" : "¡Has sido enjaulado!";
   AplicarAtaque(ataque, objetivo);
}
```

---

### 🧱 Paso 4: Llamada desde el turno humano

```actionscript
if (Key.isDown(65)) {
   eval(Cartas[NroDeCartaDeHumano])(eval(Cartas[NroDeCartaDeHumano]+"AT"), IA);
}
```

Y si la IA juega:

```actionscript
eval(Cartas[NroDeCartaDeIA])(eval(Cartas[NroDeCartaDeIA]+"AT"), Humano);
```

---

### ✅ Ventajas:

- El **objetivo se evalúa una sola vez**, y se pasa como objeto.
- Puedes **acceder directamente a `hp`** sin `eval` o `if`s innecesarios.
- Muy fácil de extender si luego agregas más jugadores, enemigos, curación, etc.

---

¿Quieres que te ayude a reescribir todo tu código con esta estructura completa?
Me mareó. Lo intento a mi manera.

Tengo esto:
Código
  1. HumanoHP = 10;
  2. IAHP = 10;
  3. Cartas = ["MarioDK", "DK"];
  4. // Lo anterior se usa para hacer sus efectos,
  5. // esto es cómo se muestran sus nombres:
  6. ShowerDeCartas = ["Mario de Donkey Kong", "Donkey Kong"];
  7. // Frame 1: Se dan cartas, el mensaje no tiene saltos de línea.
  8. // F2: Un objeto repite TurnoDeHumano hasta que se presione A.
  9. // F3: Pequeña pausa.
  10. // F4: Turno de la IA.
  11. // F5: Nada, sólo para mostrar victoria o derrota.
  12. NroDeCartaDeHumano = random(Cartas.length);
  13. Mensaje = "Tu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  14. NroDeCartaDeIA = random(Cartas.length);
  15. function TurnoDeHumano () {
  16. // Si se presiona A:
  17. if (Key.isDown(65)) {
  18. trace("A presionada");
  19. // Usa la carta (dando su estadística AT a la función):
  20. eval(Cartas[NroDeCartaDeHumano])(eval(Cartas[NroDeCartaDeHumano]+"AT"), "IA");
  21. }
  22. }
  23. function HumanoObtieneCarta () {
  24. NroDeCartaDeHumano = random(Cartas.length);
  25. Mensaje = Mensaje+"\nTu carta ahora es "+ShowerDeCartas[NroDeCartaDeHumano];
  26. }
  27. function FinDelTurnoDeHumano () {
  28. HumanoObtieneCarta();
  29. // Turno de IA:
  30. play();
  31. }
  32. function FinDelTurnoDeIA () {
  33. NroDeCartaDeIA = random(Cartas.length);
  34. // Turno de Humano:
  35. Mensaje = Mensaje+"\nEs tu turno";
  36. gotoAndStop (2);
  37. }
  38. // Estadísticas:
  39. MarioDKAT = 1;
  40. DKAT = 2;
  41. // Efectos:
  42. function TipicoFinDelTurnoDeHumano (ataque) {
  43. IAHP = IAHP-ataque;
  44. if (IAHP > 0) {
  45. FinDelTurnoDeHumano();
  46. } else {
  47. Mensaje = Mensaje+"\n¡Ganaste!";
  48. gotoAndStop (5);
  49. }
  50. }
  51. function TipicoFinDelTurnoDeIA (ataque) {
  52. HumanoHP = HumanoHP-ataque;
  53. if (HumanoHP > 0) {
  54. FinDelTurnoDeIA();
  55. } else {
  56. Mensaje = Mensaje+"\n¡Perdiste!";
  57. gotoAndStop (5);
  58. }
  59. }
  60. function MarioDK (ataque, objetivo) {
  61. if (objetivo == "IA") {
  62. Mensaje = "¡Tu rival ha sido enjaulado!";
  63. TipicoFinDelTurnoDeHumano(ataque);
  64. } else {
  65. Mensaje = Mensaje+"\n\n¡Has sido enjaulado!";
  66. TipicoFinDelTurnoDeIA(ataque);
  67. }
  68. }
  69. function DK (ataque, objetivo) {
  70. if (objetivo == "IA") {
  71. Mensaje = "¡Rival dañado!";
  72. TipicoFinDelTurnoDeHumano(ataque);
  73. } else {
  74. Mensaje = Mensaje+"\n\n¡Te dañaron!";
  75. TipicoFinDelTurnoDeIA(ataque);
  76. }
  77. }

Frame 4:
Código
  1. // Turno de IA:
  2. eval(Cartas[NroDeCartaDeIA])(eval(Cartas[NroDeCartaDeIA]+"AT"), "Humano");

Perdí la capacidad de analizarlo, me concentré en que funcionen los turnos, y funcionan. Pero ya está, no se hacen 2 ifs para ver si aplicar el daño al humano/IA y luego qué mensaje mostrar, se hace con un if.

Lo que me parece un poco mal es que se pasen parámetros si al fin y al cabo todas esas funciones (cartas, pondré más) lo van a necesitar, mejor creo un par de variables.

El patrón:
Código
  1. if (objetivo == "IA") {
  2. Mensaje1
  3. TipicoFinDelTurnoDeHumano(ataque);
  4. } else {
  5. Mensaje2
  6. TipicoFinDelTurnoDeIA(ataque);
  7. }
Parece que va a repetirse mucho, pero si los mensajes son distintos... ¿qué puedo hacer? O sea, una misma carta dará mensajes distintos según quien la use, y cómo la use (por ahora no les puse opciones pero algunas las tienen).
Si quisiera evitar esos ifs o esa repetición tendría que... ¿? Lo pensaré.

En vez de dar el parámetro ataque por tantos lados voy a crear una variable.

Una muestra del juego:
Nota: El efecto de ser enjaulado no lo programé aún.
https://youtu.be/bmLwILSr5mo


« Última modificación: Ayer a las 10:33 por Tachikomaia » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
juego de cartas
Programación C/C++
Elpior 3 4,308 Último mensaje 8 Octubre 2013, 02:39 am
por erest0r
Juego de cartas llamado truco
Java
marcelogalarza 0 2,917 Último mensaje 25 Septiembre 2011, 02:47 am
por marcelogalarza
Juego de memoria con Cartas DEV-C++
Programación C/C++
miroku123 3 7,006 Último mensaje 30 Noviembre 2012, 19:16 pm
por 4moulins
Juego de cartas
Java
calun 6 5,152 Último mensaje 5 Mayo 2015, 18:57 pm
por DarK_FirefoX
Juego del tonto(cartas)
.NET (C#, VB.NET, ASP)
nathalia1234 4 3,902 Último mensaje 18 Noviembre 2021, 15:00 pm
por Eleкtro
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines