Fundamentos de Programaci贸n

1

Bienvenida a Platzi: 驴qu茅 necesitas para tomar el curso?

2

驴C贸mo aprender programaci贸n?

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 92

Preguntas 41

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

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.

Se que no tiene que ver con el curso pero por aca lo dejo por si le es util a alguien mas, a estas alturas como esta un triz complicado para nosotros los primiparos en el tema, mi atencion se empezo a despersar, encontre esta herramienta para estar enfocada en el curso, en teoria contabiliza 25 min de trabajo y 5 min de descanso, suena una alarma para alertar, me es muy utiil

https://pomofocus.io/

El profe: 鈥淪uper bien, c贸mo vas viendo el juego鈥

Yo:

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

jajajajajaja ahora el juego qued贸 como la m谩quinas electorales que utilizan en Venezuela. Hagas lo que hagas, siempre vas a perder.

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 :麓).

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(鈥榗lick鈥, (e) => { }

Esto significa que estoy creando una funcion sin nombre, por lo que solo se ven los parentesis, y estoy pasandole como par谩metro 鈥渆鈥, 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.

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)

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:

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

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

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!

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

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.

As铆 hice para que me seleccione los ataques del enemigo, le pase la variable 鈥榤ascotaAleatorio鈥, 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 !!!

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?

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(鈥渃lick鈥, (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 鈥渁taque鈥.

3 guardar el ataque del enemigo en la variable 鈥渁taqueEnemigo鈥 de la siguiente forma

ataqueEnemigo = mascotaEnemigo.ataques[ataque]

4 borrar del array 鈥渕ascotaEnemigo.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/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.!!!

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, 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

ups,鈥 esto se puso muy bueno, y muy complejo,. es muy avanzado para un curso b谩sico? bueno, vamos al c贸digo.

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 鈥渓贸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 鈥渇uncion 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)

Me hab铆a atorado con un error de dedo pero ya voy tomando camino de nuevo.

excelente.

Buenas! yo lo hice de esta manera pensando en qu茅 pasar铆a si agregaramos m谩s ataques (osea m谩s botones) y evitando el hardcode:

Explicaci贸n paso a paso:

function selectPetEnemy() {
  randomPetEnemy = random(0, mokepons.length - 1);
  showSelectedPetEnemy.innerHTML = mokepons[randomPetEnemy].name;
}

En esta funci贸n primero creo una variable llamada randomPetEnemy que guarda el n煤mero aleatorio entre 0 y la cantidad de mokepones que hay. Recordemos que en los arreglos comenzamos a contar desde 0, por eso se pone el -1. Por ejemplo, si tenemos cinco mokepones entonces ser铆a de 0 a 4. Luego le digo que pinte contenido HTML a trav茅s de innerHTML, en este caso va a pintar el nombre del mokepon aleatorio.

function randomEnemyAttack() {
  let enemyPetAttacks = mokepons[randomPetEnemy].attacks;
  let randomAttack = random(0, enemyPetAttacks.length - 1);
  let attackName = enemyPetAttacks[randomAttack].name;

  enemyAttack.push(attackName);
  // Delete the selected attack to prevent it from being selected again
  enemyPetAttacks.splice(randomAttack, 1);

  console.log(`enemy attacks: ${enemyAttack}`);

  // Show match result (player attack, enemy attack and winner)
  // createMessage(combat());

  // Check lives to get the winner
  // checkLives(); 
}

En esta segunda funci贸n hacemos algo parecido a la anterior, pero esta vez para los ataques. enemyPetAttacks guarda los ataques de una mascota aleatoria, randomAttack guarda un n煤mero aleatorio entre 0 y la cantidad de ataques - 1. Y por 煤ltimo attackName guarda el nombre del ataque aleatorio. Luego empujamos ese nombre del ataque en el arreglo global de los ataques del enemigo. Despu茅s le aplicamos el m茅todo splice al arreglo que guarda los ataques de la mascota aleatoria, splice lo que hace es eliminar un elemento espec铆fico del arreglo, el primer valor que pide es el 铆ndice donde se encuentra el elemento que queremos eliminar, en este caso ponemos randomAttack para que autom谩ticamente apenas se escoga un ataque al azar, lo elimine y el enemigo no pueda volver a escogerlo. Y el segundo valor solamente es el n煤mero de elementos a eliminar que siempre ser谩 1.

Por 煤ltimo imprimimos el ataque en la consola.

Muchas gracias por leer馃. Espero haya quedado todo claro, se agradece feedback.
Saludos y feliz c贸digo馃憤馃徏

la secuencia de ataques en el if no son consecutivos

Hola, dejo mi c贸digo para que me den feedback de que les parece鈥 funciona perfectamente, al menos hasta el momento.

Explico el paso a paso


primero crear las variables



let ataqueEnemigo =[]
let seleccionEnemigo =[]

Despu茅s extraigo los ataques y mediante la funci贸n aleatorio ubicando el n煤mero en la posici贸n por si aumentan o disminuyen los ataques en el futuro.

function seleccionarMascotaEnemigo(){
    let mascotaEnemigo = aleatorio(0, (mokepones.length-1))

        spanMascotaEnemigo.innerHTML = mokepones[mascotaEnemigo].nombre
        ataqueEnemigo = mokepones[mascotaEnemigo].ataques

}

function ataqueAleatorioEnemigo(){
    let eleccionEnemigo = aleatorio(0,(ataqueEnemigo.length-1))
    seleccionEnemigo.push(ataqueEnemigo[eleccionEnemigo].nombre)

    resultadoCombate()
    crearMensaje()
}

Cambiamos la condici贸n para que cada vez que haya un comparativo sea en la ultima posici贸n del array

function resultadoCombate(){
    if (ataqueJugador[ataqueJugador.length-1] == '馃敟 FUEGO' && seleccionEnemigo[seleccionEnemigo.length-1] == '馃 TIERRA' || ataqueJugador[ataqueJugador.length-1] == '馃挧 AGUA' && seleccionEnemigo[seleccionEnemigo.length-1] =='馃敟 FUEGO' || ataqueJugador[ataqueJugador.length-1] == '馃 TIERRA' && seleccionEnemigo[seleccionEnemigo.length-1] =='馃挧 AGUA'){
        resultado= 'GANASTE!! 馃榿';
    }else if (ataqueJugador[ataqueJugador.length-1] == seleccionEnemigo[seleccionEnemigo.length-1]){
        resultado= 'empate';
    }else {
        resultado= 'perdiste 馃槩';
    }
}

Cambio en lo que se va a imprimir en pantalla en base a las jugadas

function crearMensaje(){
    let nuevoAtaqueJugador = document.createElement("p")
    let nuevoAtaqueEnemigo = document.createElement("p")
    
    sectionResultado.innerHTML = resultado
    nuevoAtaqueJugador.innerHTML = ataqueJugador[ataqueJugador.length-1]
    nuevoAtaqueEnemigo.innerHTML = seleccionEnemigo[seleccionEnemigo.length-1]

    sectionAtaqueJugador.appendChild(nuevoAtaqueJugador)
    sectionAtaqueEnemigo.appendChild(nuevoAtaqueEnemigo)
    
    contadorVidas()
}

Muchisimas gracias

BUENAS!!
Cambie el codigo un poco, arme un IF por cada pokemon para poder asignarles a c/u sus botones con sus poderes correspondientes. Seguro se puede optimizar ya que quedo con mucha linea de codigo. Despues de varios minutos me funciono y cada pokemon tiene sus botones con sus respectivos ataques鈥

function ataqueEnemigo(){
   let enemigoAtaque = aleatorio(0, ataquePokemonEnemigo.length -1)
    if(pokemones[mascotaAleatorio].nombre === 'Charizard'){ 
       if(enemigoAtaque === 0 || enemigoAtaque === 1 || enemigoAtaque === 2){
            poderEnemigo.push('FUEGO馃敟')
        }else if(enemigoAtaque === 3){
            poderEnemigo.push('AGUA馃挧')
        }else if(enemigoAtaque === 4){
            poderEnemigo.push('TIERRA馃尡')
        }else if(enemigoAtaque === 5){
            poderEnemigo.push('RAYO鈿')
        }else if(enemigoAtaque === 6){
            poderEnemigo.push('AIRE馃寣')
        }}
    if(pokemones[mascotaAleatorio].nombre === 'Bulbasaur'){ 
        if(enemigoAtaque === 0 || enemigoAtaque === 1 || enemigoAtaque === 2){
                poderEnemigo.push('TIERRA馃尡')
            }else if(enemigoAtaque === 3){
                poderEnemigo.push('AGUA馃挧')
            }else if(enemigoAtaque === 4){
            poderEnemigo.push('FUEGO馃敟')
            }else if(enemigoAtaque === 5){
                poderEnemigo.push('RAYO鈿')
            }else if(enemigoAtaque === 6){
                poderEnemigo.push('AIRE馃寣')
            }}
    if(pokemones[mascotaAleatorio].nombre === 'Pikachu'){ 
    if(enemigoAtaque === 0 || enemigoAtaque === 1 || enemigoAtaque === 2){
        poderEnemigo.push('RAYO鈿')
        }else if(enemigoAtaque === 3){
            poderEnemigo.push('AGUA馃挧')
        }else if(enemigoAtaque === 4){
        poderEnemigo.push('FUEGO馃敟')
        }else if(enemigoAtaque === 5){
        poderEnemigo.push('TIERRA馃尡')
        }else if(enemigoAtaque === 6){
            poderEnemigo.push('AIRE馃寣')
        }}
    if(pokemones[mascotaAleatorio].nombre === 'Blastoise'){ 
    if(enemigoAtaque === 0 || enemigoAtaque === 1 || enemigoAtaque === 2){
        poderEnemigo.push('AGUA馃挧')
        }else if(enemigoAtaque === 3){
        poderEnemigo.push('RAYO鈿') 
        }else if(enemigoAtaque === 4){
        poderEnemigo.push('FUEGO馃敟')
        }else if(enemigoAtaque === 5){
        poderEnemigo.push('TIERRA馃尡')
        }else if(enemigoAtaque === 6){
            poderEnemigo.push('AIRE馃寣')
        }}
   console.log(pokemones[mascotaAleatorio].nombre)
   console.log(enemigoAtaque)
   console.log(poderEnemigo)
   resultadoCombate()
   crearMensaje()
   resultadoFinal()

Ten铆a un error y era que coloque la llamada de la funci贸n mostrarAtaques(ataques) en la l铆nea antes de que terminase el for y por eso se repitieron, cuidado con eso.

Me cost贸 mucho poder seguir con la l贸gica del juego. Me pas贸 como a todos que no estamos de acuerdo con que la soluci贸n propuesta en la clase era una buena opci贸n, porque perd铆a lo l贸gica del juego, ya que el enemigo tambi茅n debe jugar con los 5 ataques disponibles de su jugador.
Para poder hacer que el Enemigo solo cuente con los mismos ataques del array, fui quitando ese ataque del array por medio de la funci贸n array.splice que consult茅 en la web.

Algo que no pude solucionar es que al agregarle un ataque por medio del Push no me funciona en el condicional pelea, lo solucion茅 creando otra variable y dandole el mismo resultado.

Dejo mi soluci贸n:

function ataqueAleatorioEnemigo(){
ataqueAleatorio1 = aleatorio(0,ataquesMokeponEnemigo.length -1)

if (ataquesMokeponEnemigo[ataqueAleatorio1].nombre === "Fuego"){
    ataqueEnemigo.push("FUEGO")
    jugadaEnemigo = "FUEGO"
    spanImagenAtaqueEnemigo = `<img id="${ataquesMokeponEnemigo[ataqueAleatorio1].id}" src="./imagenes/1200px-Pok茅mon_Fire_Type_Icon.svg.png" class="Fuego">`
}

else if (ataquesMokeponEnemigo[ataqueAleatorio1].nombre === "Agua"){
    ataqueEnemigo.push("AGUA")
    jugadaEnemigo = "AGUA"
    spanImagenAtaqueEnemigo = `<img id="${ataquesMokeponEnemigo[ataqueAleatorio1].id}" src="./imagenes/1024px-Pok茅mon_Water_Type_Icon.svg.png" class="Agua">`
}

 else if (ataquesMokeponEnemigo[ataqueAleatorio1].nombre === "Tierra") {
    ataqueEnemigo.push("TIERRA")
    jugadaEnemigo = "TIERRA"
    spanImagenAtaqueEnemigo = `<img id="${ataquesMokeponEnemigo[ataqueAleatorio1].id}" src="./imagenes/1200px-Pok茅mon_Ground_Type_Icon.svg.png" class="Tierra"></img>`
}

console.log(ataqueEnemigo)
ataquesMokeponEnemigo.splice([ataqueAleatorio1],1)

divResultado.style.display = "flex"
divVersus.style.display = "none"

pelea() 

}

Esta fue una manera en la que hice que los ataques del enemigo vayan de acuerdo al personaje y no se repitan

function ataqueAleatorioEnemigo(){
    let k=aleatorio(0,ataquesMokeponEnemigo.length-1)

    arregloAleatorios.push(k)
    do{
        let numeroAleatorio=aleatorio(0,ataquesMokeponEnemigo.length-1)

        if(arregloAleatorios.includes(numeroAleatorio)){

        }else{
            arregloAleatorios.push(numeroAleatorio)
        }
    }while(arregloAleatorios.length<5)

    arregloAleatorios.forEach((arregloBoton)=>{
        ataquecontrario.push( ataquesMokeponEnemigo[arregloBoton].nombre)
    })

    console.log(ataquecontrario)
    console.log(arregloAleatorios)
}

Yo lo que hice para que se tomar谩 en cuenta la mascota que el enemigo escogi贸 aleatoriamente y extraer los ataques fue declarar la variable 鈥榚xist鈥 como falso, esto nos ayudar谩 en el ciclo para cambiarla a verdadera cuando no se repitan los ataques del array de los ataques del enemigo.

Luego hice un ciclo que mientras la variable 鈥榚xist鈥 sea falsa nos tire un numero aleatorio que es la variable 鈥榬andomNumberAttack鈥, tambi茅n declare un array para contabilizar los n煤meros de los ataques que es 鈥榓mmountEnemyAttacks鈥 de ah铆 una condicional a la inversa que mientas en el array de 鈥榓mmountEnemyAttacks鈥 no exista el n煤mero aleatorio que prosiga con el c贸digo.
Si eso se cumple la variable 鈥榚xist鈥 cambia a verdadero y con push incluimos en el array de 鈥榓mmountEnemyAttacks鈥 el nuevo n煤mero aleatorio.
de ah铆 declaramos randomAttack como la nueva variable del n煤mero y hacemos las condicionales de los ataques del enemigo para ir metiendo en el array 鈥榚nemyAttack鈥 los ataques que vayan saliendo de acuerdo al n煤mero aleatorio que ha salido.

siguiendo con el ciclo, vas a estar tirando n煤meros aleatorios hasta que se cumpla la condional y asi evitamos que hayan ataques de mas respecto a la mascota que el enemigo escogi贸

Esta parte del curso si que esta dificil!! 馃槄

mirando los comentarios de todos, y volviendo a ver la clase un par de veces XD

aca mi solucion!

function seleccionarMascotaEnemigo() {
    let eleccionEnemigo = aleatorio(0, mokepones.length - 1);
    preAtaqueEnemigo = mokepones[eleccionEnemigo].ataques;
    $spanMascotaEnemigo.innerHTML = mokepones[eleccionEnemigo].nombre;

    ataqueEnemigoDefinitivo(preAtaqueEnemigo);
    secuenciaAtaque();
}

function ataqueEnemigoDefinitivo(preAtaqueEnemigo) {  
    preAtaqueEnemigo.forEach((boton2) => {
        if (boton2.nombre === "馃敟") {
          ataqueEnemigo.push("FUEGO");
        } else if (boton2.nombre === "馃挧") {
          ataqueEnemigo.push("AGUA");
        } else {
            ataqueEnemigo.push("TIERRA");
        }
     console.log(ataqueEnemigo);
    })
}

Este fue mi codigo para que tenga en cuenta los poderes de acuerdo al personaje y adicional cuando haga push lo haga con el nombre de y no con el emoji

function ataquealeatorioenemigo () {
        let ataquealeatorio = Math.floor(Math.random() * (ataquemokeponenemigo.length) )
        
   // la variable simbolo almacena el nombre  del ataque  que esta en emoji , segun el array del personaje que tenga el enemigo
        if (ataquealeatorio == 0) {
	   simboloataque = ataquemokeponenemigo[0].nombre
        } else if (ataquealeatorio == 1) {
                simboloataque = ataquemokeponenemigo[1].nombre
        }else if (ataquealeatorio == 2) {
                simboloataque = ataquemokeponenemigo[2].nombre
        } else if (ataquealeatorio == 3) {
                simboloataque = ataquemokeponenemigo[3].nombre
        } else if (ataquealeatorio == 4) {
                simboloataque = ataquemokeponenemigo[4].nombre
        } else if (ataquealeatorio == 5) {
                simboloataque = ataquemokeponenemigo[5].nombre
        }
        else {alert("hay un error")
        }
// aca ya se a帽ade al array en letras el poder que se este usando
        if (simboloataque === "馃敟") {
                ataqueenemigo.push ("FUEGO")
        } else if (simboloataque === "馃挧") {
                ataqueenemigo.push ("AGUA")
        }else if (simboloataque === "馃椈") {
                ataqueenemigo.push ("TIERRA")
        }else if (simboloataque === "馃寑") {
                ataqueenemigo.push ("AIRE")
        }else {alert("hay un error")
        }