Fundamentos de Programación

1

Bienvenida a Platzi: ¿qué necesitas para tomar el curso?

2

Programación en Navegadores: Primeros Pasos

3

Crea tu primer sitio web

4

Sitios web con HTML

5

Estructura de árbol en HTML

6

Instalando tu primer editor de código

7

Cómo declarar variables y usar prompt

8

Algoritmo de piedra, papel o tijera

9

Algoritmo avanzado de piedra, papel o tijera

10

Aleatoriedad

11

Refactor del código usando funciones

12

Ciclos

13

Gana 3 veces

14

Archivos de HTML y JavaScript

15

¿Qué es el DOM?

Quiz: Fundamentos de Programación

Desarrollando un juego con HTML y JavaScript

16

Maquetación con HTML

17

Sección de elegir mascota

18

¿Dónde ubicar la etiqueta script? Conectando HTML con JavaScript

19

Escuchando eventos con JavaScript

20

addEventListener

21

Manipulación del DOM

22

Enemigos aleatorios

23

Ataques en JavaScript

24

Ataques aleatorios del enemigo

25

Imprimiendo ataques del enemigo

26

¿Ganaste, perdiste o empataste?

27

Tablas de verdad

28

Creando el contador de vidas

29

¿Quién ganó el juego?

30

Reiniciando el juego

31

Ocultando elementos HTML con JS para mejorar la UX del juego

Quiz: Desarrollando un juego con HTML y JavaScript

Estilos con CSS

32

Anatomía de CSS

33

Tipos de display

34

Flexbox

35

Modelo de caja

36

Imágenes para los Mokepones

37

Estilos del botón

38

Adaptando HTML al diseño del juego

39

Layout: título y ataques

40

Adaptando JavaScript al diseño del juego

41

CSS Grid

42

Responsive Design

43

Detalles finales

Quiz: Estilos con CSS

Optimización de código

44

Revisión de código

45

Don't repeat yourself (DRY)

46

Clases y objetos

47

Clases y objetos de Mokepon

48

Arrays o arreglos

49

Objetos vs. arreglos

50

Ciclos: manipulando el DOM con iteradores

51

Declaración lenta de variables

52

Una sola fuente de la verdad

53

Mascotas aleatorias con arreglos

54

Ataques dinámicos por cada mascota: extraer

55

Renderizado dinámico en HTML

56

Eventos de click dinámicos

57

Secuencia de ataques del enemigo

58

Iniciando el combate

59

Resolviendo el reto de condicionales

60

Optimizando el frontend del juego

Quiz: Optimización de código

Mapa con canvas

61

Introducción a canvas: dibujando con JavaScript

62

Moviendo a Capipepo hacia la derecha

63

Movimiento hacia todas las direcciones

64

Movimientos con el teclado

65

Imágenes y personajes de fondo

66

Métodos en las clases

67

Obstáculos y colisiones

68

Combate entre mokepones colisionados

69

Mapa responsive

70

Botones bonitos y viewport

Quiz: Mapa con canvas

Backend: videojuego multijugador

71

¿Qué es backend?

72

Instalación de Node.js y NPM

73

Terminal de comandos y Node.js

74

Servidor web con Express.js

75

HTTP, localhost, servidores y puertos

76

Express.js y fetch: API REST con JavaScript

77

JSON y POST: mokepon online

78

Transmisión de coordenadas

79

Mokepones dinámicos en el mapa

80

Optimizando el mapa del juego

81

Batalla entre jugadores

82

Consumiendo la API de ataques del enemigo

Quiz: Backend: videojuego multijugador

Próximos pasos

83

Probando el juego en varios dispositivos

84

¿Y ahora qué curso tomar?

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Secuencia de ataques del enemigo

57/84
Recursos

Ya tienes la lógica del mokepon que selecciona el usuario para el combate. Ahora, debes preparar al mokepon enemigo para que esté listo para combatir y determinar al ganador de la pelea.

Preparando los ataques del enemigo

Declara dos variables, ataquesMokeponEnemigo para almacenar un arreglo con los ataques del enemigo seleccionado y otra variable ataqueEnemigo donde se guardarán los ataques aleatorios para el combate.

let ataquesMokeponEnemigo;
let ataqueEnemigo = [];

Luego de que el jugador seleccione su mokepon a través de la función seleccionarMascotaJugador(), lanza la función seleccionarMascotaEnemigo() para ejecutar la misma lógica aleatoria para seleccionar un mokepon aleatorio y determinar sus ataques también de forma aleatoria.

function seleccionarMascotaJugador() {
    // ...
    seleccionarMascotaEnemigo()
}
function seleccionarMascotaEnemigo() {
    let mascotaAleatoria = aleatorio(0, mokepones.length - 1);
    spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatoria].nombre;
    ataquesMokeponEnemigo = mokepones[mascotaAleatoria].ataques;
    secuenciaAtaque();
}

Una vez esté lista la lógica de los ataques del mokepon seleccionado por el usuario, lanzaremos la función ataqueAleatorioEnemigo() para preparar los ataques del enemigo.

function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            // ...
            ataqueAleatorioEnemigo();
       })
   })
}

Con esta función, se selecciona un ataque aleatorio del mokepon enemigo para combatir contra los ataques del mokepon del jugador, cada vez que el mismo se selecciona un ataque.

function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length - 1);
    if (ataqueAleatorio == 0 || ataqueAleatorio == 1) {
        ataqueEnemigo.push('FUEGO');
    } else if (ataqueAleatorio == 3 || ataqueAleatorio == 4) {
        ataqueEnemigo.push('AGUA');
    } else {
        ataqueEnemigo.push('TIERRA');
    }
    console.log(ataqueEnemigo);
    combate();
}

La lógica para el combate está casi lista, tanto la lógica del mokepon y del usuario como el mokepon aleatorio. Solo resta un paso para finalizar la lógica de todo el combate de tu videojuego.


Contribución creada por: Kevin Fiorentino (Platzi Contributor)

Aportes 115

Preguntas 41

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

El profe: “Super bien, cómo vas viendo el juego”

Yo:

Hola!! yo cambié un poquito el código porque entiendo que si dejamos solo en random la elección del enemigo de la secuencia de ataques no se está considerando el personaje elegido por el mismo, es decir, si el enemigo elige por ejemplo Hipodoge, el random de la secuancia de ataques del enemigo solo debería formarse por 3 aguas, 1fuego y 1 tierra (cualquier combinación de estos 5 elementos). No se si estoy interpretando mal la solución que se propone, pero en todo caso dejo mi aporte de como lo implementé en mi código.

La variable** ataquePC** contiene los ataques del personaje elegido por el enemigo, luego lo que hice fue ordenar estos ataques en forma random con el método sort()

ataquePC.sort(()=>Math.random()-0.5**)**;

De esta forma, el enemigo solo podrá atacar con una secuencia que corresponda al personaje elegido por la pc.

Los errores te hacen mas fuerte, yo despues de terminar las clases del profe diego:

posdata: buen trabajo¡¡

Aqui mi solucion para que se tome en cuenta la mascota del enemigo y para que sus ataques no puedan repetirse:

let  newArray = []

function selectEnemyPet () {
  let randomPet = randomNumber(0, mokepones.length - 1);
  enemysPet.innerHTML = mokepones[randomPet].name;
  enemysAttack = mokepones[randomPet].attack;
  for (let ind in enemysAttack) {
    newArray.push(ind);
  }
 console.log(enemysAttack);
};

function setEnemyAttack () {
  console.log(newArray);
  let randomInd = randomNumber(0, newArray.length - 1);
  let randomAttack;
  if (newArray.length <= 1) {
    randomAttack = newArray[0];
  } else {
    randomAttack = newArray[randomInd];
  }

  console.log(randomAttack);

  if (enemysAttack[randomAttack].name === "🔥") {
    enemyAttackCounter.push("FUEGO");
  } else if (enemysAttack[randomAttack].name === "🌊") {
    enemyAttackCounter.push("AGUA");
  } else if (enemysAttack[randomAttack].name === "🌱") {
    enemyAttackCounter.push("TIERRA");
  }

  newArray.splice(randomAttack, 1);
  console.log(enemyAttackCounter);
};

NOTA: me tomo un laaarrrgo rato(horas) dar con la solucion, y estoy seguro que hay muchas soluciones posibles, asi que no te rindas y nunca pares de aprender!

alamaye en este punto ya siento más dificil seguirle el paso al profe. Me detengo mucho a analizar y comprender pero ME ENCANTA :3

Espero poder tener la capacidad de aprender y aplicar las lógicas que ha venido haciendo el prof en estas últimas clases en otros proyectos sin ayuda

Veo a muchas personas con experiencia en los comentarios, dando soluciones que a veces nosotros los nuevos ni comprendemos jajajaja… Estoy haciendo el curso tal cual y como lo hace el profesor con el fin de entender lo máximo posible y luego de culminarlo pasar a una de sus rutas desde 0 :´).

Un ligero cambio:


Sugiero que en vez de añadir un cambio de calor al botón después de ser seleccionado mejor sele agregue la propiedad disable, esto para evitar que vuelva a usar.

Muestro ejemplo:

Qué se hace en esta clase

Se asignan los ataques del enemigo, de manera aleatoria, guardándolo en un arreglo


Considerando los ataques que tiene el mokepón del enemigo

En la función ataqueAleatorioEnemigo() creo el siguiente código

// Variable que guarde un número (índice)
let i = aleatorio(0, ataquesMokeponEnemigo.length - 1)

/* Se valida ataque asignado según índice y se guarda el nombre en el array ataqueEnemigo */
if (ataquesMokeponEnemigo[i].nombre === '🔥') {
	ataqueEnemigo.push('FUEGO')
} else if (ataquesMokeponEnemigo[i].nombre === '🌊') {
  ataqueEnemigo.push('AGUA')
} else {
  ataqueEnemigo.push('TIERRA')
}

/// Se elimina ataque asignado a enemigo del arreglo ataquesMokeponEnemigo
ataquesMokeponEnemigo.splice(i, 1)

Creo que algo que pude confundir un poco, es que se están creando las funciones de manera implícita pero el hecho de que se defina allí, no significa que ocurra ahora mismo.

boton.addEventListener(‘click’, (e) => { }

Esto significa que estoy creando una funcion sin nombre, por lo que solo se ven los parentesis, y estoy pasandole como parámetro “e”, el cual es un objeto estandar del sistema y que estaba disponible en ese momento DENTRO de addEventListener… Entonces:

funcionSinNombre(e) se ejecutará correctamente, pero, no se puede llamar desde otro punto porque no tiene un nombre explícito… También puede resultar más dificil de depurar.

Me parece excelente como va el curso, pero hay conceptos que requieren práctica para que los más nuevos lo entiendan, y explicarlos un poquito podría potenciar su uso en la creatividad de todos. Yo soy nuevo en JavaScript, espero no equivocarme mucho y que les sea util.

Cada vez que veo que comete un error y no le puedo decir, automaticamente entro en MOD ANSIEDAD

Jajaja

Mis secuencias solo son TIERRA, TIERRA, TIERRA, TIERRA sin importar que seleccione, Tengo el código tal cual, A este punto es bien difcil y no entiendo casi nada, solo quiero acabar el curso por ansiedad geez T_T

Igual que algunos compañeros, me di cuenta que en la solución planteada por el profe no se tienen en cuenta los ataques del mokepon enemigo y si estos se repiten o no. Estuve intentando seguir la lógica de que una vez que elijamos un ataque, el enemigo elija un ataque también y así fue como me quedó.

Lo primero que hice fue crear un array global (enemyAttacks) para almacenar los números aleatorios que se convertirán en los ataques enemigos. Luego creé otro array global (enemySequence) en el que se almacena la secuencia de ataques enemigos ya transformados en emojis(los cuales he estado utilizando como ataques)
Luego, igual que el profe, declaré una variable y le agregué el número aleatorio entre 0 y 4 en este caso

function chooseEnemyAttack() {
    let randomAttack = randomNumber(0, (enemyMokeponAttack.length - 1))

Posteriormente utilicé el método includes para verificar si el número aleatorio randomAttack que se acaba de generar se encuentra en el array enemyAttacks.

    if (enemyAttacks.includes(randomAttack) === false)

Si la condición no se cumple (false)(el ataque no se repite)
entonces se agrega el numero aleatorio randomAttack al array enemyAttacks y se genera un nuevo condicional en el cual comparamos al array que contiene los ataques del mokepon enemigo enemyMokeponAttacks en la posicion randomAttack(que tiene como valor un numero de ataque que no se ha repetido, por ejemplo el 2) en su .name (que tiene por nombre el emoji correspondiente) con los distintos ataques 🔥, 💧 o 🍃 y si coincide, el ataque será agregado al array que contiene la secuencia de ataques enemigos enemySequence. Luego llama a la funcion que compara los ataques para dar una victoria (la cual se encuentra rota ahora mismo)

if (enemyAttacks.includes(randomAttack) === false) {
        enemyAttacks.push(randomAttack)
        if (enemyMokeponAttacks[randomAttack].name == "🔥") {
            enemySequence.push("🔥")
        }
        else if (enemyMokeponAttacks[randomAttack].name == "💧") {
            enemySequence.push("💧")
        }
        else {
            enemySequence.push("🍃")
        }

        battleResult()
    }

Y por último, si la condición en la que comparamos si el número aleatorio que se generó al inicio de la función randomAttack nos da como resultado true quiere decir que el número aleatorio se repite dentro del array de ataques enemyAttacks y se repetiría el ataque, asi que no se realiza el .push sino que se llama nuevamente a la funcion para que empiece de nuevo y logre encontrar un número que no se repita

    else {
        chooseEnemyAttack()
    }
}

Intenté explicar lo mejor que pude, espero que les sirva de ayuda!

y se supone que esto es programación básica, pero es muy interesante, por que hace que uno piense en las soluciones, aparte de que si uno pone atención hay otras cosas que se le puede agregar al codigo para que valla quedando mas pulido

Sinceramente a este punto requiere bastante detenimiento entender que esta pasando, pero me emociona ver que el código funciona y todas las cosas que son posibles realizar.

Super F!
Se rompio mi codigo JS
Selecciono los ataques pero ninguno se registra y solo se queda alli el juego
Profe Diego ayudeeee

Así hice para que me seleccione los ataques del enemigo, le pase la variable ‘mascotaAleatorio’, la cual ya tenía el valor del mokepon seleccionado por el enemigo, y luego creo la función para que le agregue los ataques al arreglo ataqueEnemigo.

function ataqueAleatorioEnemigo(mascotaAleatorio) {
    let ataques=mokepones[mascotaAleatorio].ataques
    ataqueAleatorio = ataques[aleatorio(ataques.length-1)].nombre.toUpperCase()
    ataqueEnemigo.push(ataqueAleatorio)
    console.log(ataqueEnemigo)
}

ni a mi novia le presto tanta atención como a estas clases de la clase 50 hasta aquí 🤣🤣🤣🤣

Siento que en este punto ya la lógica perdió, se hizo un poco denso y complicado, Creo que me perdí. Pd. A medio video me perdí porque se brinco el 3.

Buenas a todos! Duré 2 días, pero finalmente logre hacer que el ataque del enemigo sea fiel a las normas del juego! lo pensé de muchas maneras, pero un poco de lógica y la función .includes() me terminaron bastando!

Declaré un array en global (arrayVerificacion) para cargar los números aleatorios ahí, para luego preguntar con el if y la funcion includes si el numero aleatorio se encuentra repetido en el arrayVerificacion, si no se encontraba, entonces que cargue el numero en el array del ataque del enemigo.

El segundo if es para que a medida de que el array del jugador guarde sus ataques, el array del enemigo vaya acorde a elegir y guardar sus ataques a la par, hasta llegar a 5.length los 2. Espero haberlos ayudado!!

function ataqAlEnemigo(){
    let ataqueAleatorioEn = aleatorio(0, ataqMokeponEnemigo.length -1) 

        if(!arrayVerificacion.includes(ataqueAleatorioEn)){
            
            ataqEnemigo.push(ataqMokeponEnemigo[ataqueAleatorioEn].nombre)
        }
    
    arrayVerificacion.push(ataqueAleatorioEn)
        
    // console.log(ataqEnemigo) 
    // console.log(ataqueAleatorioEn) 

        if (ataqEnemigo.length === ataqJugador.length) {
            iniciarPelea()
        } else {
            ataqAlEnemigo()
        }

}

Me demoré un chingo de tiempo para darme cuenta de que habia tipeado mal, y era con mayùscula. Les dejo esta herramienta donde pueden comparar el código suyo con el del profe.
https://pinetools.com/es/diff-comparar-archivos

Siento que hay un error en la interpretación del juego, ya que dependiendo del personaje, este puede tener más ataques de fuego o más de agua o más de tierra. Con la solución propuesta por Diego, el arrays que se crea con los ataques del enemigo no se tiene en cuenta que personaje es. Les comparto mi solución:

  1. En la función en la que se selecciona el personaje enemigo, al igual que Diego, yo creé un variable en la que se almacene el array de los ataques que arrojó esta función.
    Dentro de esta misma función hago llamado a otra función llamada “ramdomEnemyAttack” y como parámetro le envio el array de los ataques propios del personaje del enemigo:
function selectWarriorEnemy(){
    let ramdonEnemy = random(0, warriors.length - 1)
    spanWarriorEnemyName.innerHTML = warriors[ramdonEnemy].name
    enemyAttacks = warriors[ramdonEnemy].attacks
    ramdomEnemyAttack(enemyAttacks)
}
  1. La función “ramdomEnemyAttack” recibe el array de los ataques del enemigo y lo que hace es retornar el mismo array pero con los elemento ordenados de forma aleatoria
function ramdomEnemyAttack(enemyAttacks) {
    for (var i = enemyAttacks.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = enemyAttacks[i];
        enemyAttacks[i] = enemyAttacks[j];
        enemyAttacks[j] = temp;
    }
    console.log(enemyAttacks)
}

Me cuentan sus opiniones de esta sugerencia de mejora. Un abrazo !!!

En cuanto el profesor dijo que íbamos a cambiar la lógica del juego pensé que eso era un error 👎🏻⛔️y una mala práctica🙅🏼‍♀️🚫, que en un buen proyecto lo adecuado sería que la ruta estuviera bien planteada desde el principio y que no fuera necesario cambiarla a mitad. Una cosa es cambiar la forma de los botones y otra cambiar la lógica.

También me venía fatal porque yo tengo variaciones y adaptarme a los cambios me supone un quebradero fuerte de cabeza.

PERO entonces me vino la iluminación y me di cuenta de que yo no estoy en ningún proyecto real, que estoy aprendiendo y que perderle el miedo a tener que cambiar la lógica a mitad es literalmente uno de los aprendizajes más valiosos. Molesto en un proyecto real, valiososo en nuestro parque de juegos.

Así que les comparto mi momento de iluminación por si les sirve porque también se habían desubicado y pensaban “dios mío a este paso la startup se nos va al guano en dos semanas”

Buenas! desde la clase anterior me esta costando entender. Desde la clase 47 hasta la 55 me hice un resumen y fui escribiendo los codigos con notas y distintos colores para poder identificar cada variable y/o funcion. importante para mi visualmente escribi todo en cada hoja solo en una carilla. Ustedes tienen otro metodo?

Pero en la función ataqueAleatorioEnemigo, no toma en cuenta los ataques del mokepon seleccionado del enemigo, queda *hard coded* 🔥🔥💧💧🌵, bueno, me adelanto y propongo un código para que se tomen en cuenta los ataques del mokepon enemigo seleccionado y que si se agregan mas ataques el código no se rompa, saludos. ```js function seleccionarAtaqueEnemigo(){ let numeAleatorio = aleatorio(0, mascotaEnemigo.ataques.length-1) let ataqueAleatorio = mascotaEnemigo.ataques[numeAleatorio].nombre if (ataqueAleatorio == "🥵"){ ataqueEnemigo.push("FUEGO") } else if (ataqueAleatorio == "💦"){ ataqueEnemigo.push("AGUA") } else { ataqueEnemigo.push["TIERRA"] } print(ataqueEnemigo) combate() } ```function seleccionarAtaqueEnemigo(){    let numeAleatorio = aleatorio(0, mascotaEnemigo.ataques.length-1)    let ataqueAleatorio = mascotaEnemigo.ataques\[numeAleatorio].nombre     if (ataqueAleatorio == "🥵"){        ataqueEnemigo.push("FUEGO")    }    else if (ataqueAleatorio == "💦"){        ataqueEnemigo.push("AGUA")    }    else {        ataqueEnemigo.push\["TIERRA"]    }     print(ataqueEnemigo)}
Por que no se encuentran los recursos.?

Hasta el momento, con cada clase voy observando como existen muchas maneras de hacer las cosas. Cada vez se pone más interesante.!

note que el programa que hizo el profe era muy genérico así que la solución que hice para hacerlo de pendiendo de la mascota del enemigo fu esta

function ataqueAleatoriEnemigo()
{
    let ataqueAleatorio = aleatorio(0,ataqueEnemigo.length - 1)
    
 	
    ataqueEnemigo.push(mokepones[enemigo].ataques[ataque 
    Aleatorio].nombre)
    console.log(ataqueEnemigo)
    combate()
}    

donde enemigo es el numero aleatorio que genera en la función que selecciona la mascota del enemigo y la volví variable global para usarla en esta función

3 horas me demore en completar el reto, y añadí los ataque en los resultados para poder corroborar que si son las comparaciones correctas

Optimize un poco el código en la función de ataqueAleatorioEnemigo, en vez de usar una secuencia if guarde el mokepon del enemigo en una varibale y cambie todo ese codigo por el siguiente

  • ataqueEnemigo.push(mascotaEnemigo.ataques[ataqueAleatorio].ataque)*

Pero entonces lo del ataque aleatorio cuando dijo que si llegan mas ataques los guarda, pero aquí estamos con 5
entonces no veo la optimización del if porque manualmente digito los números 0 a 5. Pero bueno esperar las otras clases para ver en que termina 😅

function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length - 1);
    if (ataqueAleatorio == 0 || ataqueAleatorio == 1) {
        ataqueEnemigo.push('FUEGO');
    } else if (ataqueAleatorio == 3 || ataqueAleatorio == 4) {
        ataqueEnemigo.push('AGUA');
    } else {
        ataqueEnemigo.push('TIERRA');
    }
    console.log(ataqueEnemigo);
    combate();
}

Pensé que yo era el único perdido acá, pero bueno veo que varios somos primiparos adelantando conocimientos para luego de a poco comprender.

de Profe a Profe , decir "ya habiamos hecho esto" "ya habías visto eso" , inconscientemente hace sentir tontos a los estudiantes , inconscientemente repito.

Casi se me rompe el código de tantos cambio, casi no la cuento xd🤯

Hola a todos. Si al momento de ejecutar el código les sale en la consola que su elección fue solo [TIERRA, TIERRA, TIERRA], les recomiendo poner un console.log(e) debajo del boton.addEventListener(“click”, (e) => { para así ver en la consola cómo está almacenado el emoji del botón que seleccionaron y lo copien tal y como está en el navegador con todo y espacios en su código para que la condición pueda ser True y pueda variar dependiendo del botón elegido.

las probabilidades de ataque enemigo son las siguientes:
fuego: 40%
agua: 40%
tierra: 20%

Hola, como muchos han comentado esta solución no considera cual es la mascota del enemigo. Comparto mi solución que creo más sencilla y es usando una función que se llama splice(), la cual va recortando los ataques del mokepon, por lo tanto, no repetiremos el ataque seleccionado. Saludos y espero que les ayude a los que no han entendido.

<code> 
function ataqueAleatorioEnemigo(){
    let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length-1)
    		ataqueEnemigo.push(ataquesMokeponEnemigo[ataqueAleatorio].nombre)
    ataquesMokeponEnemigo.splice(ataqueAleatorio,1)    
    console.log(ataqueEnemigo)
    combate()
}
function secuenciaAtaqueEnemigo() {
    let ataqueAleatorio = aleatorio(0, ataquesPersonajeEnemigo.length - 1)

    if (ataquesPersonajeEnemigo[ataqueAleatorio].nombre === "🪨") {
        ataqueEnemigo.push("Rock")
    } else if(ataquesPersonajeEnemigo[ataqueAleatorio].nombre === "✂️") {
        ataqueEnemigo.push("Scissors")
    } else {
        ataqueEnemigo.push("Paper")
    }
    console.log(ataqueEnemigo)
    ataquesPersonajeEnemigo.splice(ataqueAleatorio, 1)
}

Dejo por aqui mi avance en el curso de programacion basica, tome un camino muy diferente al que hicieron.
Mis mokepones tienen 120 puntos de vida y cada ataque tiene un daño base, segun el tipo de mokepon y el tipo de ataque, del enemigo y del jugador, hace un calculo de aumento o decrecimiento del daño, tambien agregue una funcion de curacion limitada a 3 usos. Me gustaria que le echaran un ojo y me dieran su opinion.

Este es el github

y por aca les dejo el juego en githubpages

Yo lo que hice para que tomara en cuenta la mascota del enemigo es:
1 crear un objeto mascotaEnemigo
donde se guarda la mascota aleatoria del enemigo.

2 con la función

numeroAleatorio(0, mascotaEnemigo.ataques.length)

generar un número aleatorio para elegir un ataque aleatorio de los que tiene la mascota y guardalo en una variable auxiliar “ataque”.

3 guardar el ataque del enemigo en la variable “ataqueEnemigo” de la siguiente forma

ataqueEnemigo = mascotaEnemigo.ataques[ataque]

4 borrar del array “mascotaEnemigo.ataques” el ataque ya usado

mascotaEnemigo.ataques.splice(ataque, 1)

Les dejo la documentación que encontré sobre arrays en JS donde encontré este método, hay otros métodos para borrar elementos de un array pero este es el que mas se ajusto a lo que necesitaba Docuemtacion Arrays

Y aquí sobre el método splice()

Y listo, de esa forma el enemigo selecciona ataques según su personaje y a medida que ataca no puede volver a usar esos mismos ataques.

Al igual que muchos aquí, también me parece que no usar los ataques que ya están establecidos en el arreglo de la clase (class) de los mokepones en mi caso son armas, pues no es lo lógico, así que mi solución fue crear un nuevo arreglo y a este arreglo enviar la copia de lo ya creado luego desordenar el arreglo para que los ataques no sean siempre los mismos, la línea de código que use fue la siguiente tuArreglo.sort(function(){return Math.random() - 0.5 });, el resto fue comparar las posiciones de los arreglos, modificar los mensajes y listo.

He realizado algunas variantes al código, para que use las opciones de ataque del mokepon que escoge la computador.
También le agregé una nueva llave al arreglo de los ataques del mokepon, para que contenga la descripción del ataque

let     opponentMokepon
function sequenceAttacks(){
    let buttonsAttacks=document.querySelectorAll('.button-attack')
    buttonsAttacks.forEach((buttonAttack) => {
        buttonAttack.addEventListener('click', (e) => {
            attacksplayer.push(buttonAttack.value)
            buttonAttack.style.background='#001D6E'
            console.log(attacksplayer)
            opponentRandomAttack()
        })
    })
}
function chooseOpponentMokepon(){
    let mokeponRandomnumber = randomnumber(0,mokepons.length-1)
    opponentMokepon=mokepons[mokeponRandomnumber]
    spanMokeponOpponent.innerHTML = opponentMokepon.name
    imgMokeponOpponent.alt=opponentMokepon.name
    imgMokeponOpponent.src=opponentMokepon.image
    sequenceAttacks()        
}
function opponentRandomAttack(){
    let attackindex=randomnumber(1,opponentMokepon.attacks.length-1)
    attacksopponent.push(opponentMokepon.attacks[attackindex].desc)
    battle()
}

La solución que encontré (después de horas xd) al problema mencionado en los comentarios fue en la función donde se selecciona los ataques aleatorios, ordenar aleatoriamente los ataques del personaje del enemigo y luego ir agregándolos al array de ataques seleccionados y al mismo tiempo eliminándolos del array de los ataques del personaje, para que no se repitan, por eso se selecciona el primer ataque del array e inmediatamente se elimina para que a la próxima vez que se seleccione un ataque se tenga que elegir otro y nunca se elija el mismo de antes :

function seleccionarAtaqueEnemigo(){

ataquesMokeponEnemigo.sort(()=>Math.random()-0.5)

 ataqueSeleccionadoEnemigo.push(ataquesMokeponEnemigo[0].nombre)

    ataquesMokeponEnemigo.shift()


    console.log(ataqueSeleccionadoEnemigo)


    combate()
![](https://static.platzi.com/media/user_upload/image-74b9eddd-2116-4f7e-b108-4e3c1b71d169.jpg) Le Faltan unos detalles css pero ahi la llevo
Hola! Creo que con este profe se debio trabajar con un nuevo ejercicio porque esto de reutilizar o " optimizar el codigo " terminamos confundidos y un poquito mas dificil de aprender estas nuevas clases.
Aunque no creo que ya lo vea nadie, pero por si algún rezagado como yo está realizando el curso, les dejo mi solución para el tema de la secuencia de ataques de la máquina. La solución que da el profesor, genera una secuencia indiferente del mokepon usado, con lo cuál no está siguiendo las reglas del juego donde cada mascota tiene sus tipos de ataque para poder generar una estrategia. Posiblemente se arregle más adelante, pero como no lo sé, os dejo la solución que he encontrado después de varias horas. Por lo demás bien el curso, aunque ya terminé varios de javascript y DOM. ```js function seleccionarMascotaEnemigo() { //Generamos la mascota del Enemigo de forma aleatoria con nuestro array de dragonPones let mascotaAleatoria = aleatorio(0, dragonPones.length - 1); let elementoAleatorio; let ataqueEnemigoAux = []; //Mostramos el nombre en el HTML spanMascotaEnemigo.innerHTML = dragonPones[mascotaAleatoria].nombre; //Guardamos los ataques correspondientes a la mascota elegida. Esta queda guardada en un Array de objetos ataquesDragonPonEnemigo = dragonPones[mascotaAleatoria].ataque //console.log(ataquesDragonPonEnemigo); //Recorremos el array de ataques para tomar solamente el nombre y generar la secuencia de ataque del Enemigo ataquesDragonPonEnemigo.forEach((ataqueNombre) => { //console.log(ataqueNombre.nombre); ataqueEnemigo.push(ataqueNombre.nombre);//Ya tenemos la secuencia ordenada //console.log(ataqueEnemigo); }); //Creamos la secuencia aleatoria let sizeAtaqueEnemigo = ataqueEnemigo.length; for (let i = 0; i < sizeAtaqueEnemigo; i++) { elementoAleatorio = aleatorio(0, ataqueEnemigo.length - 1); ataqueEnemigoAux.push(ataqueEnemigo[elementoAleatorio]); //console.log(ataqueEnemigoAux); ataqueEnemigo.splice(elementoAleatorio, 1); } ataqueEnemigo = Array.from(ataqueEnemigoAux); //console.log(ataqueEnemigo); secuenciaAtaque(); } ```Espero les sirva, hay que tener en cuenta que la nomenclatura de las variables he seguido yo la mía propia, pero creo que se entiende.
El codigo como lo dejo Juan Dc, estaba bien en vez de optimizarlo lo que está haciendo el profe Diego es retrasar un poco y dar dolores de cabezas...
Retomando este curso luego de un año que lo deje, no sería mejor poner los condicionales del ataque sin los números y más bien directamente hacer las condiciones con el nombre, algo más o menos así: function ataqueEnemigo() { let aAleatorio = aleatorio(0, AtaqueEnemigo.length - 1); let ataqueSeleccionado = AtaqueEnemigo\[aAleatorio].nombre; if (ataqueSeleccionado === 'Wather') { ataqueContrincante.push('Wather'); } else if (ataqueSeleccionado === 'Fire') { ataqueContrincante.push('Fire'); } else if (ataqueSeleccionado === 'Earth') { ataqueContrincante.push('Earth'); } else if (ataqueSeleccionado === 'Air') { ataqueContrincante.push('Air'); } console.log(ataqueContrincante); combate(); }
No te rindas, falta poco 🤏
que laberinto es programar
Recuerden escribir bien el "textContent", tenia errores distintos y era por lo habia escrito todo en minúsculas ![](https://static.platzi.com/media/user_upload/1-c89ea101-056b-46df-8ef5-7a69392d3046.jpg)
bueno a mi no me gusta como el profe quieres que sea el juego yo quiero que sea uno que tengas los mismo ataques por cada mascota pero dependiendo de que mascota elegiste sus ataque aran mas o menos daño y que puedas utilizar las beses necesarias un ataque y que no solo se rinda a 4 o 3 y tambien quiero que hayga no solo ataques sino tambien defensas pa mejorar la experiencia y recuerden no copien el codigo es decir no miren y hagan como el profe quiere sino haganlo como usted quiera
Una hora buscando por qué mi código se rompía, para que al final haya sido por escribir "lenght" en vez de "length"
¡Hola! 🎉 Te recomiendo la extensión Blackbox para Visual Studio Code. ¡Espero que les sea útil! 😊 ¡Saludos! 🚀
Hola, a mí muestra este error al seleccionar el ataque, no hay cambio en las vidas y solo me muestra el primer evento ya sea "GANASTE, PERDISTE O EMPATE" ![](https://static.platzi.com/media/user_upload/image-b2198f89-f378-4281-a30e-f1a51ac22eab.jpg)
Me esforcé mucho así que me veo en la obligación de dejar este aporte. Primero también hice una función usando "for" para seleccionar la mascota enemiga y creé otra función identificando los ataques y sus índices para que cada vez que use uno random, lo vaya eliminando (Con una nuevo método). Así quedó de la siguiente manera la segunda función. Donde .Splice es para eliminar el index que se acaba de usar ```js function mostrarAtaqueEnemigo(){ let ataqueAleatorio = aleatorio(0, ataquesPuchamonEnemigo.length - 1) let fire = ataquesPuchamonEnemigo.findIndex(index => index.id == "boton-fuego") let water = ataquesPuchamonEnemigo.findIndex(index => index.id == "boton-agua") if (ataqueAleatorio == fire){ ataqueEnemigo.push("Fuego") ataquesPuchamonEnemigo.splice(ataqueAleatorio, 1) }else if (ataqueAleatorio == water){ ataqueEnemigo.push("Agua") ataquesPuchamonEnemigo.splice(ataqueAleatorio, 1) }else { ataqueEnemigo.push("Tierra") ataquesPuchamonEnemigo.splice(ataqueAleatorio, 1) } ```
yo mas
el diablo
no soy alejandro
lo que yo hare sera hacer lo que hace el profe al pie de la letra con todo identigo pero al final yo le pondre todo lo que quiero mas personajes mas mecanicas mas ataques mas detalles
CLASE 1 (= CLASE 57 != ULTIMA CLASE (=
Perdí de vista en las últimas clases para qué era el -1 en la declaración de la variable del ataque aleatorio...
bueno todo me salió bien igual que el profe y entiendo lo que dice ósea su lógica, lo que si se es que sola por mi cuenta no lo haría hahahaha pero bueno imagino que eso lo da el tiempo la practica y experiencia, por ahora me conformo con que el código no se me ha roto con todo y que he metido mas elementos de los que tiene el juego original, pero esto de la lógica esta fuerte
Me parece que para que tenga más sentido, es mejor hacer que la mascota enemiga también tenga exactamente los ataques correspondientes al mokepon que sale aleatoriamente, por eso yo lo hice de esta manera, `function seleccionarMascotaEnemigo(){` ` let ataqueAleatorio = aleatorio(mokepones.length -1,0)` ` spanMascotaEnemigo.innerHTML = mokepones[ataqueAleatorio]._nombre` ` document.getElementById("mascota-seleccionada-enemigo").src=mokepones[ataqueAleatorio]._fotos` ` ataquesMascotaEnemigo = mokepones[ataqueAleatorio]._ataques` ` ` ` // Aplicar el algoritmo de Fisher-Yates para reordenar ataquesMascotaEnemigo` ` for (let i = ataquesMascotaEnemigo.length - 1; i > 0; i--) {` ` let j = Math.floor(Math.random() * (i + 1));` ` [ataquesMascotaEnemigo[i], ataquesMascotaEnemigo[j]] = [ataquesMascotaEnemigo[j], ataquesMascotaEnemigo[i]];` ` }` `}` Estuve investigando y encontré que ese algoritmo llamado de Fisher-Yates es muy usado para este fin, ya que devuelve un arreglo aleatorio real de cada elemento del mismo arreglo. La verdad es que no le entendí muy bien el funcionamiento, ya que es complicado, pero al final lo hice funcionar gracias a la IA de Bing... y realmente devuelve siempre el arreglo del mokepon "revuelto"
Por fin lo logré, me negué a usar `if` porque mis 5 ataques son diferentes y no quería hacer un bloque largo cuando sabía que debía de haber algún modo de buscar el tipo de ataque comparando el `button.target.id` y el `mokepones.attacks[index].id` y por fin di con la respuesta para mantener en apariencia 5 ataques pero que la lógica del juego que nos están enseñando se mantuviera en pie y este es mi resultado: **Ataques de mokepones** ```js hipodoge.attacks.push( {name: '💥', id: 'hit', img: 'assets/hit.svg', class: 'normal', type: 'fuego 🔥'}, {name: '🛡️', id: 'shield', img: 'assets/shield.svg', class: 'normal', type: 'tierra 🌱'}, {name: '💧', id: 'water', img: 'assets/water.svg', class: 'water', type: 'agua 💧'}, {name: '🌊', id: 'tsunami', img: 'assets/tsunami.svg', class: 'water', type: 'agua 💧'}, {name: '❄️', id: 'snow', img: 'assets/snow.svg', class: 'water', type: 'agua 💧'} ); capipepo.attacks.push( {name: '💥', id: 'hit', img: 'assets/hit.svg', class: 'normal', type: 'agua 💧'}, {name: '🛡️', id: 'shield', img: 'assets/shield.svg', class: 'normal', type: 'fuego 🔥'}, {name: '🌱', id: 'earth', img: 'assets/earth.svg', class: 'earth', type: 'tierra 🌱'}, {name: '🍃', id: 'blades', img: 'assets/blades.svg', class: 'earth', type: 'tierra 🌱'}, {name: '☘️', id: 'fortune', img: 'assets/fortune.svg', class: 'earth', type: 'tierra 🌱'} ); ratigueya.attacks.push( {name: '💥', id: 'hit', img: 'assets/hit.svg', class: 'normal', type: 'tierra 🌱'}, {name: '🛡️', id: 'shield', img: 'assets/shield.svg', class: 'normal', type: 'agua 💧'}, {name: '🔥', id: 'fire', img: 'assets/fire_dracula.svg', class: 'fire', type: 'fuego 🔥'}, {name: '🌋', id: 'volcano', img: 'assets/volcano.svg', class: 'fire', type: 'fuego 🔥'}, {name: '❤️‍🔥', id: 'self-esteem', img: 'assets/self_estreem.svg', class: 'fire', type: 'fuego 🔥'} ); ``` **Secuencia de ataque** ```js function attackSequence() { attackButtons.forEach((button) => { button.addEventListener('click', (event) => { let target = event.target.id; console.log(target) playerAttacks.push(attacks.find(keyValue => keyValue['id'] === target)['type']) button.disabled = true; button.classList.add('disable'); console.log(playerAttacks) }) }); } ``` **Diseño** ![](file:///C:/Users/mumbu/Desktop/mokepon.gif)![](https://static.platzi.com/media/user_upload/image-11e8c339-1cf0-4c55-9de9-7227bb43d686.jpg)
Hola, teniendo en cuenta lo que muchos compañeros están comentando, me gustaría compartir la manera que encontré para que no se repita el ataque aleatorio enemigo dependiendo de sus ataques. Guardé los números aleatorios en un Array, luego, con el atributo .includes verifica si ya está el núm dentro del array, si lo incluye, retorna hasta tener un numero único. Después de no haber más números entrará en un bucle infinito xdd. ```js function ataqueAleatorioEnemigo() { let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length -1) let numerosAtaqueEnemigo = [] if (numerosAtaqueEnemigo.includes(ataqueAleatorio)) { return ataqueAleatorioEnemigo() } poderEscogido = mokepones[mascotaAleatoria].ataques[ataqueAleatorio].poder if (ataqueAleatorio == 0 || ataqueAleatorio == 1 || ataqueAleatorio == 2) { ataqueEnemigo.push(poderEscogido) } else if (ataqueAleatorio == 3) { ataqueEnemigo.push(poderEscogido) } else { ataqueEnemigo.push(poderEscogido) } numerosAtaqueEnemigo.push(ataqueAleatorio) console.log(ataqueEnemigo) combate() } ```function ataqueAleatorioEnemigo() {    sectionMessages.style.display = "flex"    let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length -1)     if (numerosAtaqueEnemigo.includes(ataqueAleatorio)) {        return ataqueAleatorioEnemigo()    }
A mi, salen los ataques en el console, los botones cambian de color, pero no cambia los mensajes de ganaste/perdiste, ni se imprime los ataques abajo
![](https://static.platzi.com/media/user_upload/sp2-d79af1ff-640f-4bcb-9e6d-936b2df74378.jpg)El código que resalté se me dificultó entenderlo, ya que en mi mente daba 3 porque es la longitud del arreglo o vector mokepones, por ende el ataqueMokeponesEnemigo era para mí justo eso, un valor entre el índice 0 y 2, pero con la propiedad .ataques cambia la longitud del arreglo por la propia sintaxis del lenguaje, entonces se accede directamente a la longitud de los ataques que son 5, o sea, 0-4 que es la longitud del vector ataques, no sé si me hice entender, pero espero les ayude para avanzar en la clase, es tediosa, si yo no hubiera visto en la universidad antes lógica o fundamentos, estaría con derrame cerebral ya que hay cositas que se pasan por alto y JavaScript no lo había manejado hasta ahora

Se me hace un poco complicado seguir a este profesor. Quiero terminar los videos pero esta ha sido la seccion que menos he aprendido. Quizas conecto mejor con otro metodo de explicacion porque en esta seccion ando en el limbo

TENGO buen nivel en javascript pero estas clases se vuelven cada vez muy difícil de entender por la falta de explicación.!!!

Hola, les comparto mi solución que creo que es algo más fácil. Les explico: El enemigo tiene cinco ataques únicos, y cuando selecciona uno ya no debería poder seleccionarlo nuevamente. Entonces, para hacer eso, lo que yo hice fue crear un número aleatorio (rng) entre cero (el índice del primer ataque) y el número total de ataques menos uno (índice del último ataque). Y después, para asegurarme de que no se pudiera volver a seleccionar ese ataque, lo eliminé del arreglo que contiene los ataques del mokepón del enemigo (mascotaEnemigo.ataques) `rng = aleatorio(0, [mascotaEnemigo.ataques.length -1])    ataqueEnemigo = mascotaEnemigo.ataques[rng].nombre    ataquesEnemigo.push(ataqueEnemigo)    mascotaEnemigo.ataques.splice(rng, 1)` Por último creé dos variables, una llamada ataqueEnemigo que es la que utilizo para validar quién gana en la ronda actual, y otra llamada AtaquesEnemigo (que es un arreglo) en la que guardo el historial de ataques del enemigo.

Gracias al aporte de Paula Inés Cudicio me inspiré a realizar esta solución al problema. Para que el enemigo elija los ataques de acuerdo a su mascota

Blablabla, tengo problemas para seguir comentando 😦 la verdad es que no se si sea un bug pero estoy intentando hacer aportes pero me sale un mensaje de error abajo de la caja de texto de platzi y no me deja postear…

3 horas me demore en completar el reto, y añadí los ataque en los resultados para poder corroborar que si son las comparaciones correctas

ayen por favor mi codigo no funciona y ya ise todo lo que se tenia que hacer

para hacer la barra vertical | , presionen la tecla que está ANTES de la tecla 1 , en su portatil.

Veo que se aun se repite mucho código, además cualquier mascota enemiga tendrá las mismas probabilidades de ataque sin tener en cuenta que unas puede ser mas probable que usen fuego, agua o tierra dependiendo de su tipo.

mi solución a esto es:

function ataqueEnemigoAleatorio(){
    let ataqueEnemigo = mascotaEnemigo.ataques
    return ataquesEnemigo[aleatorio(1,ataquesEnemigo.length)-1].id
}
  1. defino una variable ataqueEnemigo que tiene todos los ataques de la mascota que haya salido del aleatorio y con esta función retorno la propiedad id de un ataque aleatorio que va desde 1 hasta la cantidad de ataques que tenga la mascota enemiga (.length)
            ataquesEnemigo.push(ataqueEnemigoAleatorio())

y luego simplemente le agrego este resultado con el método push a la variable global ataquesEnemigo

clase 57. functionataqueAleatrioEnemigo (), se tiene (0 ó 1) fuego; (3 ó 4 ) agua; else (2)para tierra; considero no acertado por probabilidad de ocurrencia de ataques aleatorios son diferentes.

Gracias por la espectacularmente complicada clase.

Yo no le entiendo nada 😦

Alguien que pueda ayudarme por favor este ha sido el video que menos he podido entender nisiquiera bajando el mismo codigo del profesor le encuentro la logica

Les comparto mi código:

//Ataque Aleatorio del Enemigo

ataque_enemigo = personaje_enemigo.attacks[numeroRandom(0, personaje_enemigo.attacks.length -1)].nombre;

De esta manera hacemos que la elección de ataque del CPU enemigo sea dinámico.

A veces el codigo no me funciona pero si agarro y copio el codigo que esta en los recursos de la clase , magicamente si funciona , muy raro

Yo con POO cree Attacks y le doy un array de debilidades

class Attacks {
    constructor(public attacks: Attack[]) {}
    create(attack: Attack) {
        this.attacks.push(attack);
    }
    getbyName(name: TypeAtacks): Attack {
        return this.attacks.find((attack) => attack.type === name) as Attack;
    }

    public get all(): Attack[] {
        return this.attacks;
    }
}

y cree una funcion llamada result en la que busco la debilidad del usaurio y busco si alguna debilidad es igual al ataque del enemigo

const result = () => {
    const weakUser = attacks.getbyName(ataqueJugador).weak;
    const winPC = weakUser.some((attack) => {
        return attack === ataqueEnemigo;
    });
    ++turno;
    if (!winPC && ataqueJugador !== ataqueEnemigo) {
        changeLife('pcPetLife');
        return 'ganaste';
    } else if (ataqueJugador === ataqueEnemigo) {
        return 'empate';
    } else {
        changeLife('yourPetLife');
        return 'perdiste';
    }
};

Símbolo de O: ||

me rompió el desactivar los botones de ataques pero lo resolvi de esta forma

<code> 
function desactivarAtaques() {
    botonReiniciar.style.display = "block"
    
    botones.forEach((boton) => {
        boton.disabled = true
    })
}

anteriormente lo tenia asi :

<code> 
function desactivarAtaques() {
    botonReiniciar.style.display = "block"
    botonFuego.disabled = true
    botonAgua.disabled = true
    botonPlanta.disabled = true
}

A estas alturas el nivel del curso se ha puesto en mi opinión cuesta arriba 😦, estaba entendiendo paso a paso bien y como que en las últimas 5 o 6 clases mi mente desconecta o no comprendo la “lógica” entiendo que todo se hace de forma dinámica porque luego pueden existir mil personajes y mil ataques y no vas a ir uno por uno indicando cada vez pero como después del día trabajando y luego cenar y ponerme a estudiar a este nivel me cuesta mucho.

Espero poder ir comprendiendo más no quiero rendirme

!!HOLA estudiantes de platzi !!! aqui les dejo un consejo de forEach es un poco largo pero util lean detenidamente y hasta el final incluso las lineas de codigo ya que son la clave para
entener forEach.

recuerdan en clases pasadas y en esta clase hemos usado forEach pueda que algunos sigan con dudas, así que lo explicare de la mejor manera :

pueden interpretar

ataques.forEach((ataque) =>{     <button id="${ataque.id}"  class="ataques BAtaque">${ataque.nombre} </button>
        `     })  

como una funcion :

ataques.forEach(function (ataque){
<button id="${ataque.id}"  class="ataques BAtaque">${ataque.nombre} </button>
        `
})

y lo que dice es : que forEach pasara por cada una de las variable que estan dentro del array ataques y por cada iteracion se ejecutara la “funcion ataque”, los elementos que estan dentro del array ataques son encerrados en la funcion ataque y a la vez que tambien se ejecuta el codigo que pusimos adentro de la funcion que seria el siguiente :

ataquesMokepon = `
        <button id="${ataque.id}"  class="ataques BAtaque">${ataque.nombre} </button>
        `

entonces dentro de la variable ataquesMokepon estariamos guardando la estructura del boton que necesitamos y pueda que aqui es donde se confundieron y la analogia de la funcion nos ayudara a entender esto dijimos que ataque seria una funcion que guardaria cada linea de codigo independiente dentro de el si recordamos ataques tiene :

{nombre: '🔥', id: 'boton-fuego'}

entonces eso se guardaria dentro de la funcion ataque y ya podemos acceder desde la funcion y buscar el id que tiene guardado y tambien a su nombre como hicimos en :

<button id="${ataque.id}"  class="ataques BAtaque">${ataque.nombre} </button>
        `

ya que tenemos guardado el nombre y el id en la funcion podemos usarlas accediendo desde el, ya que estan guardadas dentro de la funcion que se ejecutara por cada iteracion.

Es increible como una simple letra mal puesta te complica la vida , esto es como jugar a ser detective

Solo como pregunta general, no es mejor dividir las variables en otro archivo, y las funciones en otro para que sea mas facil de acceder a ellos?

Aquí veo varios comentarios de l@s compañer@s que son principiantes y que en este punto ya están un poco perdidos, sin embargo me salen con terminologías expertas y ejemplos super avanzados y soluciones extraordinarias. A mi a las justas se me a quedado el nombre del juego 😭

  • ¿Cómo ves el juego?
  • Paso a pasito, el nivel está muy bueno

Yo los ataques de la maquina los nombres del ataque no lo que me lo tome directamte del arreglo de los ataques de la mascota del pc
let ataquecontrincante=[]
function ata_contrincante(){let eleccionataquecontrincante=aleatorio(0,ataquescontrincante.length-1)
console.log(eleccionataquecontrincante)
ataquecontrincante.push(ataquescontrincante[eleccionataquecontrincante].nombre)
console.log(ataquecontrincante)

Hola el curso me ha parecido super bueno, pero a mi opinion personal no me parece que se cambie mucho la logica del juego, porque teniamos desde el inicio una logica y entonces han cambiado muchas cosas y se que quizas sea asi en la realidad de un proyecto real como tal pero eso hace que se pierdan muchas cosas como tiempo, y quizas hasta algunos estilos y demas cosas, pero para eso estamos nosotros para modificar y llevar nuestro propio proyecto a donde nosotros mismo queramos.

Me parece muy valioso que durante el curso aparezca errores y se solucionen, siento que es un poco el día a día en programación y es fundamental entender estos errores.

Recuerden que en la partde de recursos aparece el GitHub donde encuntran las líneas de código. A veces si algo no te funciona es bueno revisar y comprar línea por línea 😃

La forma en que yo hice que mi código creara 5 ataques diferentes según los ataques que tiene el mokepon enemigo fue crear una matriz de números, la cual guardara números aleatorios y comparara los existentes con el que se va a ingresar para saber si alguno es repetido, en caso de que se repita el numero creara otro y así hasta tener los 5 aleatorios

let numeros = []
    var j = 0;
    while(j < 5)
    {
        numero = aleatorio(0, ataquesMokeponEnemigo.length - 1)
        var existe = false 
        for(var i = 0; i < numeros.length; i++)
        {            
            if(numeros[i] == numero)
            {
                existe = true;
                break;
            }
        }       
        if(existe == false)
        {
            numeros.push(numero)
            j++
        }        
    }

luego de esto recorro la matriz de numeros para hacer el push del respectivo ataque de la mascota que encaja con el numero aleatorio en su posicion

for(var i = 0; i<numeros.length; i++){
    
        tipoAtaqueEnemigo.push(mokepones[mascotaAleatoria].ataques[numeros[i]].nombre2)
    
    }

no se si me hice entender, pero si tienen alguna pregunta con gusto les respondo

Es interesante como se usa el metodo de los ataques de los mokepones similar al del enemigo. Aunque un falta complementar lo que dejo el profe. Se nota que esta parte es un poco tediosa, pero entretenida. A seguir aprendiendo.

Si tenemos una función que no esta mandada a llamar en ninguna otra función la función que no esta llamada no hará nada (como si no hubiera nada)