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

Iniciando el combate

58/84
Recursos

Tienes lista la lógica para preparar al mokepon del jugador y el mokepon del enemigo para el combate. Aun resta finalizar la lógica del propio combate para lograr determinar al ganador a partir de la cantidad de ataques ganados.

Cambiando la lógica del combate

Comienza declarando dos variables que utilizaremos para mostrar en el HTML el tipo de ataque del jugador y del enemigo (fuego, agua, tierra).

let indexAtaqueJugador;
let indexAtaqueEnemigo;

Luego de que la lógica de los ataques del jugador y del enemigo esté lista, ejecuta una nueva función iniciarPelea() que determinará si el combate está listo para iniciar o no.

function ataqueAleatorioEnemigo() {
    // ...
    iniciarPelea();
}

Implementaremos una nueva lógica para el combate donde es necesario que el jugador haya seleccionado el orden de sus cinco ataques para iniciar el combate. Para determinar esta lógica, utilizaremos el length del arreglo que guarda los ataques del jugador. Recuerda que, por cada ataque del jugador, se selecciona un ataque enemigo de forma aleatoria.

function iniciarPelea() {
    if (ataqueJugador.length === 5) {
        combate();
    }
}

Declara otra nueva función llamada indexAmbosOponente() que usaremos para renderizar en el HTML el orden de los ataques del mokepon del jugador y del enemigo.

function indexAmbosOponente(jugador, enemigo) {
    indexAtaqueJugador = ataqueJugador[jugador];
    indexAtaqueEnemigo = ataqueEnemigo[enemigo];
}

Esta variable es leída desde la función crearMensaje() que es la encargada de crear el HTML.

function crearMensaje(resultado) {
    // ...
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador;
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo;
}

Si la lógica para iniciar el combate se cumple, el mismo inicia y se realiza el cálculo para evaluar quién es el ganador de cada ataque del combate o si hay empate.

function combate() {
    for (let index = 0; index < ataqueJugador.length; index++) {
        if(ataqueJugador[index] === ataqueEnemigo[index]) {
            indexAmbosOponente(index, index);
            crearMensaje("EMPATE");
        }
        // RETO: Determinar lógica del combate por cada ataque
    }
    revisarVidas();
}

Queda pendiente un reto para ti. Cada ataque del jugador puede ganar, empatar o perder. Implementa esta lógica en la función combate() y realiza el cálculo para determinar al ganador de la pelea al mejor de 5 ataques.

Haz un esfuerzo por resolver este reto. En la siguiente clase, encontrarás la solución al mismo.


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

Aportes 131

Preguntas 38

Ordenar por:

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

o inicia sesión.

Al igual que muchas otras personas en las anteriores clases y comentarios, pienso que el grado de dificultad va avanzando pero seguimos el ritmo y repetimos algunas clases para analizar.

Hay algo que me deja pensando y es por que nunca establecieron un diagrama de flujo para el juego. Es fundamental para saber en que parte del procedimiento estas y como vas a trabajar.

Durante el transcurso del curso los profesores fueron cambiando el mismo funcionamiento del juego y no me parece mal pero hay personas que se están involucrando con términos y algoritmos de la programación y es posible que no tengan acceso a otros cursos para aclarar dudas.

Solo quiero dar mi aporte para que lo tengan en cuenta, lo he leído a lo largo del curso y me dejo pensando. Yo sin embargo seguiré con la escuela de desarrollo para aclarar y seguir aprendiendo.

Saludos.

Asi va mi Mokepon

Las ultimas 3 clases

Me cuesta mucho concentrarme en aprender cuando el que me está enseñando no lee lo que está escribiendo y sigue como si nada, ya van varias veces y desconozco el motivo pero es muy frustrante.

Inserte audio del titoc de : No puedo Martha… Ya descompuse mi código JAJAJA

Gente que ha llegado a este punto del curso, no desfallezcan, yo me he demorado unos días en repasar mi código, compararlo con el del profesor, pero lo que más me ha ayudado ha comprender y poder seguir el nivel es usar la consola en el navegador, imprimiendo las variables los arreglos eso me ha ayudado un montón, no desesperen solo continúen que se puede.

No me gusta como va el juego, eso de generar 5 ataques y validarlos en una vez, es aburrido. Y también en el fondo sigue siendo un piedra, papel o tijera porque los ataques son 3: fuego, agua y tierra.
También me parece más divertido el sistema de vidas.

Lo que hice para las validaciones fue coger las condiciones ya establecidas y agregarles el índice.

A las cuales le s agregué un contador para que el juego funcione con victorias.

Creo que hay un pequeño error cuando se escribe la función indexAmbosOponentes, según mi lógica, debería ser:

function indexAmbosOponentes(jugador, enemigo) {
  indexAtaqueJugador = ataqueJugador[jugador];
  indexAtaqueEnemigo = ataqueEnemigo[enemigo];
}

De lo contrario, el resultado de los mensajes será el mismo.
¡Espero sea útil, saludos! 😃

  • ¿Qué se hace en esta clase?
    Se comparan las secuencias de ataques (los arreglos) del jugador y el enemigo
  • ¿Cómo se hace?
    • Se hace la comparación (el combate) únicamente una vez se han seleccionado los ataques
      if (ataqueJugador.length === 5) { combate() }
    • En la función del combate se crea un ciclo para que reccorra ambas secuencias
      for (let index = 0; index < ataqueJugador.length; index++) { }
    • Dentro del ciclo se hace una validación para determinar si el jugador GANÓ, PERDIÓ o EMPATO
if (ataqueJugador[index] === ataqueEnemigo[index]) {
	crearMensaje("EMPATE 😑")
} else if ((ataqueJugador[index] == 'FUEGO' && ataqueEnemigo[index] == 'TIERRA') || (ataqueJugador[index] == 'AGUA' && ataqueEnemigo[index] == 'FUEGO') || (ataqueJugador[index] == 'TIERRA' && ataqueEnemigo[index] == 'AGUA')) {
	crearMensaje("GANASTE 🎉")
} else {
	crearMensaje("PERDISTE 😢")
}

Hola! Yo cambie un poco la logica para que cada vez que se le de click a un ataque el enemigo elija uno al azar y se comparen uno a uno y se vayan contando las victorias y las derrotas. de esa manera no habria que esperar a elegir los cinco ataques:

en la funcion combate le agregue un contador con los indices para no tener que hacer un ciclo y se compraren cada uno de los los ataques dependiendo de su indice y ademas agregue dos contadores mas para verificar las victorias y las derrotas:

function combate() {
    if (attackCounter[combatCounter] == enemyAttackCounter[combatCounter]) {
      result = "Empate";
    } else if (attackCounter[combatCounter] == "Fire" && enemyAttackCounter[combatCounter] == "Earth") {
      result = "Ganaste 🎉";
      victoryCounter++;
    } else if (attackCounter[combatCounter] == "Water" && enemyAttackCounter[combatCounter] == "Fire") {
      result = "Ganaste 🎉";
      victoryCounter++;
    } else if (attackCounter[combatCounter] == "Earth" && enemyAttackCounter[combatCounter] == "Water") {
      result = "Ganaste 🎉";
      victoryCounter++;
    } else {
      result = "Perdiste 😢";
      lossCounter++;
    }
    createMessage();
    endGame();
    enemysLife.innerHTML = lossCounter;
    playersLife.innerHTML = victoryCounter;
    combatCounter++
  } 

Este curso va bien, he aprendido mucho y solidado conocimientos que ya tenia, pero no estaria mal darle un repaso a cada clase cuando termine el curso

Yo opte por mantenerme en la mecanica anterior:
siento que si se evalua un encuentro a la vez, se me hace mas “tradicional” jajaja

Gente entiendo su frustación por el nivel de las clases pero me parece que deberían dejarla de lado y prestar atención a lo que la clase quiere que hagamos que es abrir la mente al análisis de programación. Es obvio que no están esperando que programemos el lanzamiento de un cohete o un GOTY en 3 días. Es una demostración de lo que podemos llegar a hacer, que nos impulse a seguir aprendiendo, a investigar por nuestra cuenta y adentrarnos en el tema. Es difícil manejar la frustacion pero peor es no aprender algo que te gusta porque la frustacion te controla.

Me rindo, sinceramente este bloque del curso no es claro. Es muy difícil seguirlo y no se trata de frustración se trata de falta de claridad. El profesor en otros cursos es muy claro pero la dinámica de cambiar todo cada clase sin que tengamos claras muchas cosas no ayuda mucho al aprendizaje.

En el minuto 13:12 el profesor se equivoco y puso ataqueEnemigo tanto al jugador como al enemigo, asi que si cuando les salgan los mensajes en pantallas son los mismos ya saben por que es 😄

El profe: Esto ya lo vimos antes…
YO:

Saludos, recomiendo a todos mis compañeros de curso que hagan un esfuerzo en mejorar su ortografía, recuerden que un programador, además de saber programar, debe saber escribir. No podemos desarrollar una web que contengan palabras mal escritas o verbos mal conjugados.

Mis validaciones! je

Yo llevo varios cursos en Platzi y sigo con el entusiasmo, pero alguien que apenas conoce estos conceptos (el curso es básico) la frustración lo debe llevar a renunciar. Entiendo también que pueda ser una clase de manejo de la frustración (Ya Freddy lo ha dicho) pero se están excediendo. En lugar de enamorar lo que generan es que se fastidien. Mal ahí…

para cumplir el reto, solo debemos cambiar en los ifs originales las variables siguientes:
-ataqueEnemigo por ataqueEnemigo[index]
-ataqueJugador por ataqueJugador[index]
ademas agregar en todos los ifs la linea siguiente

  • indexAmbosOponente(index,index)
    eso servira para superar el reto.
    Un comentario , debemos corregir la linea 215 del profesor, tiene que decir:
    indexAtaqueJugador = ataqueJugador[jugador]

Tengo la sensación desde que el bloque de Programación Básica lo está explicando el profesor Diego, el nivel a subido excesivamente para alguien que está empezando en programación como es mi caso aunque estoy más especializado en marketing digital algo básico conozco de código.

A modo de feedback la curva de aprendizaje es demasiado brusca y también es como agotadora 40 clases con el ejemplo de los mokepones, desde las últimas clases ya uno no sabe claramente el porque se hace esto o lo otro, el cerebro como que desconecta.

Voy a seguir adelante porque me he marcado aprender programación con 37 años pero de verdad que estas clases se están haciendo pesadas.

No me gusto la idea de seleccionar todo y luego que salgan el resultado, lo que hice fue que mostrara los resultados de cada ataque, cambie vidas por batallas ganadas y cuando en el array de ataques esten todos lo botones seleccionados le muestre el resultado final y el boton de reinicio. Mi codigo tambien toma los ataques teniendo en cuenta la mascota del enemigo.

function ataquealeatorioenemigo () {
        let ataquealeatorio = Math.floor(Math.random() * (ataquemokeponenemigo.length) )

        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")
        }

        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")
        }        

        console.log (ataqueenemigo)
        juego()
}
function juego () {
        if (ataquejugador == ataqueenemigo){
                resultado = "EMPATE 🤦‍♀️"
        } else if (ataquejugador == 'AGUA' && ataqueenemigo == "FUEGO"){
                resultado = "GANASTE ❗"
                ganadasjugador ++
                spanvidasenemigo.innerHTML = ganadasjugador
        } else if (ataquejugador == 'AIRE' && ataqueenemigo == "FUEGO"){
                resultado = "GANASTE ❗" 
                ganadasjugador ++
                spanvidasenemigo.innerHTML = ganadasjugador
        } else if (ataquejugador == 'FUEGO' && ataqueenemigo == "TIERRA"){
                resultado = "GANASTE ❗"
                ganadasjugador ++
                spanvidasenemigo.innerHTML = ganadasjugador
        } else if (ataquejugador == 'TIERRA' && ataqueenemigo == "AGUA"){
                resultado = "GANASTE ❗" 
                ganadasjugador ++
                spanvidasenemigo.innerHTML = ganadasjugador
        } else if (ataquejugador == 'AGUA' && ataqueenemigo == "AIRE"){
                resultado = "GANASTE ❗"
                ganadasjugador ++
                spanvidasenemigo.innerHTML = ganadasjugador
        } else if (ataquejugador == 'TIERRA' && ataqueenemigo == "AIRE"){
                resultado = "GANASTE ❗"       
                ganadasjugador
                spanvidasenemigo.innerHTML = ganadasjugador}
        else {
                resultado = "PERDISTE 💔"
                ganadasenemigo ++
                spanvidasjugador.innerHTML = ganadasenemigo 
        }
       mensajes ()
       resultadototal ()
       }

function mensajes (){        
        let nuevoataqueenemigo = document.createElement ("p")
        let nuevoataquejugador = document.createElement ("p")

        mresultado.innerHTML = resultado
        nuevoataquejugador.innerHTML= ataquejugador [ataquejugador.length -1]
        nuevoataqueenemigo.innerHTML= ataqueenemigo [ataqueenemigo.length -1]

        mataquejugador.appendChild(nuevoataquejugador)
        
        mataquesenemigo.appendChild(nuevoataqueenemigo)
        
}
function resultadototal (){
        if (ataquejugador.length == 6) {
                mensajefinal ()
        } else {}
}
function mensajefinal () {
        seccionreiniciar.style.display = "block"  
        
        if (ganadasjugador < ganadasenemigo) {
                resultadofinal = ("GANADOR")
        } else if (ganadasjugador > ganadasenemigo) {
                resultadofinal = ("GAME OVER")
        } else {}
        setionmensajes.innerHTML = resultadofinal                  
}
function reiniciar () {
        seccionataque.style.display = "none"
        seccionreiniciar.style.display = "none"
        location.reload ()
}
window.addEventListener("load", iniciarJuego)

yo agregue el operador OR (ll) para las validaciones y así evitar replicar muchos ELSE IF y usar solo un ELSE IF para todas las victorias posibles.

function combate() {

  for (let index = 0; index < ataqueJugador.length; index++) {
      if (ataqueJugador[index] === ataqueEnemigo[index]){
         indexAmbosOponentes(index, index)
         crearMensaje("EMPATE");
      }else if(ataqueJugador[index] === "AGUA" && ataqueEnemigo[index] === "FUEGO" || ataqueJugador[index] === "FUEGO" && ataqueEnemigo[index] === "TIERRA" || ataqueJugador[index] === "TIERRA" && ataqueEnemigo[index] === "AGUA"){
        indexAmbosOponentes(index, index)
        crearMensaje("GANASTE")
        victoriasJugador++
        spanVidasJugador.innerHTML = victoriasJugador
      }else {
        indexAmbosOponentes(index, index)
        crearMensaje("PERDISTE")
        victoriasEnemigo++
        spanVidasEnemigo.innerHTML = victoriasEnemigo
      }
  }
 
  revisarVictorias();
}

Listo, espero te sirva


Recomiendo leer este aporte en una nueva pestaña para una lectura mas amena.

Me demoré unas horas, pero creo que valió la pena.

Hemos cambiado el modelo de combate, ya no es por vidas, sino por rondas de cinco ataques (el que obtenga mas victorias gana.

  • Esta en la mi antigua función combate():
function combate() {
    
    if (ataqueEnemigo == ataqueJugador) {
        crearMensaje("EMPATE 🙂")
    } else if (
        (ataqueJugador == "Fuego🌋" && ataqueEnemigo == "Tierra🗻") ||
        (ataqueJugador == "Agua💧" && ataqueEnemigo == "Fuego🌋") ||
        (ataqueJugador == "Tierra🗻" && ataqueEnemigo == "Agua💧")
    ) {
        crearMensaje("GANASTE 😎")
        vidasEnemigo--
        spanVidasEnemigo.innerHTML = vidasEnemigo
    } else {
        crearMensaje("PERDISTE 😫")
        vidasJugador--
        spanVidasJugador.innerHTML = vidasJugador
    }

    revisarVidas()
}

  • Esta es la nueva función combate()

function combate() {
    // fuego le gana a tierra, agua le gana a fuego, tierra le gana a agua
    let resultado
    for (let i = 0; i < ataqueJugador.length; i++) {
        if (ataqueJugador[i] === ataqueEnemigo[i]) {
            indexAtaques(i, i)
            resultado = "EMPATE 🙂"
        } else if (
            (ataqueJugador[i] == "FUEGO" && ataqueEnemigo[i] == "TIERRA") ||
            (ataqueJugador[i] == "AGUA" && ataqueEnemigo[i] == "FUEGO") ||
            (ataqueJugador[i] == "TIERRA" && ataqueEnemigo[i] == "AGUA")
        ) { 
            indexAtaques(i, i)
            resultado = "GANASTE 😎"
        } else {
            indexAtaques(i, i)
            resultado = "PERDISTE 😫"
        }
        console.log(ataqueJugador[i], ataqueEnemigo[i])
    }
    crearMensaje(resultado)
    iniciarValidacion()
}

Es similar a la funcion anterior en cuanto a la logica de victorias.
He creado una variable “let resultado” que guardara el valor de cada combate individual en vez de llamar a la funcion crearMensaje() al final de cada bucle, (volveremos a esta funcion mas tarde).
Seguimos usando la funcion de IndexAtaques() que explico el profesor.

  • Antigua función crearMensaje()
function crearMensaje(resultadoCombate){
    sectionResultadoCombate.innerHTML = resultadoCombate
    
    
    function crearMensajeAtaqueJugador() {
        let parrafo = document.createElement("li")
        parrafo.innerHTML = "Atacó con " + ataqueJugador

        statusJugador.appendChild(parrafo)
    }
    function crearMensajeAtaqueEnemigo() {
        let parrafo = document.createElement("li")
        parrafo.innerHTML = "Atacó con " + ataqueEnemigo

        statusEnemigo.appendChild(parrafo)
    }
    crearMensajeAtaqueJugador()
    crearMensajeAtaqueEnemigo()
}

  • Nueva función crearMensaje()

function crearMensaje(resultadoCombate){
    sectionResultadoCombate.innerHTML = resultadoCombate
    crearMensajeAtaqueJugador()
    crearMensajeAtaqueEnemigo()
    function crearMensajeAtaqueJugador() {
        let parrafo = document.createElement("li")
        if (resultadoCombate === "GANASTE 😎") {
            parrafo.style.color = "#186A3B"
            victoriasJugador++
            spanVictoriasJugador.innerHTML = victoriasJugador
        }if (resultadoCombate === "PERDISTE 😫") {
            parrafo.style.color = "#EB1D36"
        }
        parrafo.innerHTML = "Atacó con " + indexAtaqueJugador
        console.log(parrafo.innerHTML)
        statusJugador.appendChild(parrafo)
    }
    function crearMensajeAtaqueEnemigo() {
        let parrafo = document.createElement("li")
        if (resultadoCombate === "PERDISTE 😫") {
            parrafo.style.color = "#186A3B"
            victoriasEnemigo++
            spanVictoriasEnemigo.innerHTML = victoriasEnemigo
        }if (resultadoCombate === "GANASTE 😎") {
            parrafo.style.color = "#EB1D36"
        }
        parrafo.innerHTML = "Atacó con " + indexAtaqueEnemigo
        statusEnemigo.appendChild(parrafo)
    }
}
 

Quizas se vea mas grande de lo que es (tal vez sea por los if; estos son detalles mio, permiten designar un color dependiento el resultado del combate; rojo para derrotas y verdede para victorios, esto para jugador y enemigo).
Decidi cambiar de lugar estas lineas de código de combate() a una de las subfunciones de crearMensaje() dependiento si son del jugador o enemigo, son las siguinetes lineas

victoriasJugador++          	
spanVictoriasJugador.innerHTML = victoriasJugador

victoriasEnemigo++
spanVictoriasEnemigo.innerHTML = victoriasEnemigo

…sigue, esto lo hice asi porque me di cuenta de que si dejo que fluya como lo hace siempre la funcion combate() con las lineas anteriormente mencionadas, en vez de esperar a una validacion que nos muestre al final cual fue el resultado de los cinco ataques como lo dijo el profe (cosa que no me gusto, despues te explico la secuencia) me junta los resultados anteriores mostrando 15 ataques en vez de 5 (1 + 2 + 3 + 4 + 5 = 15, esto cada vez que se seleciona un ataque y se suma al array), espor eso que decidi ponerlas aqui.

  • Veamos la secuencia impuesta por el profesor para la función combate()
function ataqueAleatorioEnemigo(){
.
.
.
	iniciarPelea()
}
function iniciarPelea(){
	if(ataqueJugador.length===5){
	combate()
	}
}

  • Esta es mi secuencia:

function ataqueAleatorioEnemigo(){
.
.
.
    combate()
}
function iniciarValidacion(){
    if (ataqueJugador.length === 5) {
        revisarVictorias()
    }
}

De esta manera los combates se imprimen en momento real, en ves de esperar la validación (lo hice de esta manera para que se sienta mas real, nosotros al programas esto sabemos que el ataque del enemigo es completamente aleatorio, pero el usuario final no lo sabe, se sentiria como si el enemigo ya supiera nuestros ataques de antemano y podria tomar ventaja.
.
Recuerda que la funcion iniciar validacion es llamada al final de combate(), por lo que se enterara cuando el array tenga los elementos suficientes (en este caso 5) y llamara a la funcion revisarVictorias()

  • Mi antigua función
function revisarVidas(){

    if(vidasEnemigo == 0){
        crearMensajeFinal("GANASTE LA BATALLA✌")
    }else if(vidasJugador == 0){
        crearMensajeFinal("PERDISTE LA BATALLA😞")
    }

}
//Recordemos que antes aun era por vidas
  • Mi nueva función


function revisarVictorias(){

    if(victoriasJugador > victoriasEnemigo){
        crearMensajeFinal("GANASTE LA BATALLA✌")
    }else if(victoriasJugador < victoriasEnemigo){
        crearMensajeFinal("PERDISTE LA BATALLA😞")
    }else {
        crearMensajeFinal("HA SIDO UN EMPATE⚖")
    }

}
// La nueva modalidad impera por la victorias

Y así es como se ve:


Aqui mi repositorio: Mokepon
Tambien puedes probarlo: ¡Juega ahora!

Te agradezco mucho por leer hasta el final💚💚💚

muy mal profesor

Mi solución al reto:

function combate () {
    for (let index = 0; index < attackPlayer.length; index++) {
        if (attackPlayer[index] === attackEnemy[index]) {
            indexAmbosAtaques (index, index)
            createMessage('Empate')
        } else if (attackPlayer[index] == 'PIEDRA' && (attackEnemy[index] == 'TIJERA' || attackEnemy[index] == 'LAGARTO') || attackPlayer[index] == 'PAPEL' && (attackEnemy[index] == 'PIEDRA' || attackEnemy[index] == 'SPOCK') || attackPlayer[index] == 'TIJERA' && (attackEnemy[index] == 'PAPEL' || attackEnemy[index] == 'LAGARTO') || attackPlayer[index] == 'LAGARTO' && (attackEnemy[index] == 'PAPEL' || attackEnemy[index] == 'SPOCK') || attackPlayer[index] == 'SPOCK' && (attackEnemy[index] == 'PIEDRA' || attackEnemy[index] == 'TIJERA')) {
            indexAmbosAtaques (index, index)
            createMessage('Ganaste')
        } else {
            indexAmbosAtaques (index, index)
            createMessage('Perdiste')
        }
    }

    phCounter()

}

A los dioses el codigo les ofrezco mi disculpa, no me rindo jamas, pero siendo que está nivel avanzado para mí, y seguire persistiendo

Para quienes ya vayan por aquí y vean esto, mi consejo: no se desanimen si no entienden mucho, sigan con el curso, no se rindan, tomen notas de lo que no entienden y traten de al menos tener el programa funcionando. Terminen el curso y luego tomen uno de los cursos básicos de algún lenguaje en concreto, como Python, JavaScript, C#, etc., donde se ve más a detalle temas básicos y van subiendo la dificultad con cursos de programación orientada a objetos, estructuras de datos, control de flujo, manejo de errores y así. Manden correo a [email protected] pidiendo ayuda de que camino y cursos tomar para ir de poco en poco con esto. Entiendo su frustración si no entienden mucho, yo tampoco le entiendo tanto, se que difícil, es frustrante y es fácil tirar la toalla, pero hagan su esfuerzo, aunque les tome tiempo, tengan fe en ustedes mismos y continúen. Es un camino complicado para algunos de nosotros, pero háganlo para ustedes y por ustedes, ya sea tanto por crecer profesionalmente, o como mero reto personal o pasatiempo. Les deseo lo mejor a todos.

un curso super necesario para entender todas las herramientas que se usan aqui y donde explican su concepto es el de PENSAMIENTO LOGICO, ahi explican que es un ciclo For, If/Else, While, Do While, que son los arrays, ETC ETC ETC… lo estoy haciendo a la par de este curso y me ha ayudado a entender muchas cosas!!!

Hola, mi solución fue extraer los ataques válidos, a partir de la mascota enemiga, hice en el proceso varias funciones, y acupe varios métodos del array.
Finalmente, después de muchas horas de leer, de probar ensayo y error, y solucionar bug, logre que funcionara.
Si algo me ayudó mucho, fue ocupar

console.log()

Mi lógica es que, por cada ataque seleccionado por parte del jugador, se escoja uno de los ataques disponibles por parte del enemigo, termina cuando no queda elementos en el array.
Obtengo un array con los ataques del enemigo, la cual es la forma en la que los elementos fueron saliendo del array ataques enemigos. Dicho array fue el utilizado en la lógica de los combates.

Dejo mi codigo… por si quieren revisar y preguntarme de lo que escribi…

https://drive.google.com/file/d/1Sq2Qm1-1TL8l13t-6GsGzDJVpofqhbQU/view?usp=sharing

Bueno, se me hizo fácil terminar las validaciones en la función combate(), Pero al terminarlas hice algunas pruebas y note que algunos ataques que se imprimían no coincidían con los botones que había presionado.
Estuve un rato depurando, cambie la funcionalidad de vidas a victorias. Declare 3 variables globales (victorias, perdidas, empates) que use para cambiar el funcionamiento de revisar vidas().
También quite el parámetro “resultado” que tenia la función crearMensaje(), sentí que ya no tenia una funcionalidad clara ya que ese mensaje solo se iba a mostrar al finalizar los 5 ataques.

Algo así fue como me quedo, lo importante es que funciona y que ya empiezo a ver errores con mas facilidad que antes al igual que he podido resolverlos por mi cuenta.

Me esta encantando este curso, algunas clases son complicadas, pero basta con repetir y ser paciente.
Ya estoy viendo resultados y eso me tiene muy entusiasmado!

let victorias = 0
let perdidas = 0
let empates = 0

function combate() {
    for (let index = 0; index < ataqueJugador.length; index++) {
        if(ataqueJugador[index] === ataqueEnemigo[index]){
            indexAmbosOponentes(index, index)
            crearMensaje()
            empates ++
            console.log("EMPATE")
        }else if (ataqueJugador[index] === "FUEGO" && ataqueEnemigo[index] === "TIERRA") {
            indexAmbosOponentes(index, index)
            crearMensaje()
            victorias ++
            console.log("GANASTE")
        }else if (ataqueJugador[index] === "AGUA" && ataqueEnemigo[index] === "FUEGO") {
            indexAmbosOponentes(index, index)
            crearMensaje()
            victorias ++
            console.log("GANASTE")
        }else if (ataqueJugador[index] === "TIERRA" && ataqueEnemigo[index] === "AGUA") {
            indexAmbosOponentes(index, index)
            crearMensaje()
            victorias ++
            console.log("GANASTE")
        } else {
            indexAmbosOponentes(index, index)
            crearMensaje()
            perdidas ++
            console.log("PERDISTE")
        }
        revisarVidas() // Ya no son vidas
        console.log(victorias, perdidas, empates)
        console.log()
    }
}

function crearMensaje() {
    let nuevoAtaqueDelJugador = document.createElement("p")
    let nuevoAtaqueDelEnemigo = document.createElement("p")

    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo

    ataqueDelJugador.appendChild(nuevoAtaqueDelJugador)
    ataqueDelEnemigo.appendChild(nuevoAtaqueDelEnemigo)
}

function revisarVidas() {
    if (victorias > perdidas) {
        crearMensajeFinal ("FELICITACIONES! Ganaste :)")
    }else if (perdidas > victorias) {
        crearMensajeFinal ("Lo siento, perdiste :c")
    } else if (empates > 2) {
        crearMensajeFinal ("Empate! Nadie Gana.")
    } else {
        crearMensajeFinal ("Empate! Nadie Gana.")
    }
}

Ahi quedo, use un contador para victorias y derrotas, hice que
el mensaje final se mandara a llamar una vez que escogiera los 5 ataques y en este ultimo es cuando me imprime el resultado de la batalla, cuantas victorias obtuvo cada contrincante y que ataques usaron en cada ronda, que buen curso lptm

psdt: Alguien sabe como desactivar los botones de ataque una vez que ya lo haya seleccionado?

<code> 
//.... 
function iniciarPelea(){
    if(ataqueJugador.length === 5){
        let styleAtaquesJugador= document.getElementById('ataques-jugador')
        styleAtaquesJugador.style.cssText = "border:4px solid rgb(196 15 231);background-color: rgb(241 195 195); border-style: dotted;";
        let styleAtaquesEnemigo= document.getElementById('ataques-enemigo')
        styleAtaquesEnemigo.style.cssText = "border:4px solid rgb(196 15 231);background-color: rgb(241 195 195); border-style: dotted;";
        resultadoCombate()
        mensajeFinal()
    }
}

function indexAmbosOponentes(jugador,enemigo){
    indexAtaqueJugador = ataqueJugador[jugador]
    indexAtaqueEnemigo = ataqueEnemigo[enemigo]
}

function resultadoCombate(){

    for(let index=0;index < ataqueJugador.length; index++){
        if(ataqueJugador[index] === ataqueEnemigo[index]){
            indexAmbosOponentes(index,index)
                crearMensaje()                 
        }  else if (ataqueJugador[index] =="FUEGO" && ataqueEnemigo[index]=="TIERRA"||ataqueJugador[index] == "AGUA" && ataqueEnemigo[index]=="FUEGO"||ataqueJugador[index] == "TIERRA" && ataqueEnemigo[index]=="AGUA") {
                  indexAmbosOponentes(index,index)
                    crearMensaje() 
                  victorias++
                }   
                else{
                    indexAmbosOponentes(index,index)
                    crearMensaje() 
                    derrotas++
                }
    }
}

function crearMensaje(){
    
    let nuevoAtaqueDelJugador = document.createElement('p')
    let nuevoAtaqueDelEnemigo = document.createElement('p')
    

    
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo

    sectionAtaqueJugador.appendChild(nuevoAtaqueDelJugador)
    sectionAtaqueEnemigo.appendChild(nuevoAtaqueDelEnemigo)
}

function mensajeFinal(){
        if(victorias==derrotas)
        sectionResultado.innerHTML = "EMPATE"
        else if(victorias > derrotas)
        sectionResultado.innerHTML = "GANASTE"
        else{
        sectionResultado.innerHTML = "PERDISTE"
        }

    spanVidasJugador.innerHTML = victorias + " Victorias"
    spanVidasEnemigo.innerHTML = derrotas + " Victorias"
    sectionReiniciar.style.display = 'block'
    botonFuego.disabled = true
    botonAgua.disabled = true
    botonTierra.disabled = true

}

Este es un cambio en la función combate que inicie en el nivel anterior del curso, es reducir las condiciones usando conectores, de momento ha funcionado, aqui se las dejo:

Está muy interesante el nivel del curso a esta altura, pero en cuanto a gameplay, me parece que está desbalanceado, es mucho menos divertido jugar sabiendo que dependiendo de las mascotas elegidas hay muy pocas chances de ganar. O al revés, que tengamos una mascota que prácticamente la tiene ganada por la cantidad de ataques que decidimos añadir.

No les pasa que duran hasta 2 horas en una clase de 20min Jejejeje ! Vamos por buen camino !

esto ya lo hemos visto en clases pasadas…
sii???

La lógica inicial del lenguaje con el que Freddy y Juan David comenzaron el curso me había parecido sencilla y fácil de comprender, luego, cuando entró la profe Estefany sentí que el nivel de complejidad había aumentado, y eso no está mal ya que la idea es entender el cómo y el porqué en programación.
Sin embargo, con el profe Diego me doy cuenta que prácticamente el código con el que inicialmente empezamos desapareció o fué cambiado casi que por completo.
Aclaro que no estoy criticando, al contrario, estoy disfrutando de aprender la variedad de maneras con las que se puede programar. Y aunque estoy adaptandome a las nuevas y múltiples formas de desarrollar código, creo que el proceso de enseñanza de profesor a profesor hubiera podido ser mejor escalonado. Hubo un cambio muy alto en el nivel de dificultad entre módulos. Y espero no estar dando una idea equivocada con mi comentario, espero que esto pueda ser tomado en cuenta. Ya que de verdad agradezco a Platzi por los conocimientos que brindan y me siento alegre de haber tomado la decisión de aprender con ustedes.
Sólo quiero decir “GRACIAS”.

Gracias por la clase. De verdad que hay muchas cosas que ya en este punto parecen imposibles de aprender. Pero seguiré hasta el final.

Soy esta

Vengo a dar mi aporte luego de estar 5 dias estancado porque si seleccionaba agua decia que era tierra y todos daban tierra.
Conclusion, mi vsc me agrego el “textcontent” con las C minuscula y era con mayuscula "textContent"
Solucionado, hora de seguir.

en secuencia de ataque hay un error grave ya que por defecto su eleccion es else tierra ha pesar de que de click fuego o agua

Me cansé de tantos if-else-if, así que me hice una tabla de verdad, al menos como la imaginé y como pude, le envías los ataques y te devuelve el resultado:

Que terrible la clase ha roto mi codigo y he visto en tantas oportunidades y no doy de aquellos nuevos errores que mal tanta confusion del profesor

En este momento el nivel de programación es elevado, para mejorar los vacíos que se puedan tener es bueno mirar otros complementos que platzi brinda. Por que este curso da por encima lo que en otros profundiza.

se me exploto la cabeza

Aquí utilicé las validaciones con las que veníamos trabajando en las primeras clases. Con la diferencia de que cuento las victorias en lugar de restar vidas y no manejo una validación que verifique el empate sino una que compruebe la desigualdad de los ataques después de los casos en los que gane el jugador, ya que si los valores son diferentes y no gana el jugador entonces sólo puede ganar el oponente y no me importa el empate.


Y así fue como hice la validación por victorias en lugar de vidas


Aquí abajo dejo otra forma que se me ocurrió para mostrar los ataques escogidos por cada oponente utilizando también lo que teníamos de clases pasadas. Tanto los ataques del jugador y del enemigo están guardados en sus respectivas variables(arreglos) para luego recorrer cada uno con un .forEach() para agregar cada ataque a “nuevoAtaqueDel…” (el .toUpperCase() es para que se vea en mayúscula) y luego insertarlo en el HTML a la sección “ataquesDel…” con .appendChild()

Y así va quedando…

Yo estaré encantado de recibir su feedback y también quiero mandarles un mensaje de motivación a aquellos que se les está rompiendo todo… No se preocupen, yo también he roto hasta los platos de mi casa pero así es esto, saber manejar la frustración y al final no importa si no lo hacen igual que el profesor, ahora que estamos iniciando lo importante es que funcione porque si funciona significa que está buena la lógica, lo demás ya son buenas prácticas y esas se aprenden cometiendo errores. ¡¡NO SE RINDAN!!, un abrazo y nunca paremos de aprender!!.

En la Linea 213 y 214 se está usando los mismos Arrays (arreglos), no se dañará el código, pero si la lógica del juego.

No entiendo de donde se sacó el index del enemigo en el loop for el profe, dice:

if (ataquejugador[index] == ataqueEnemigo[Index])

No se supone que la variable index solo existe dentro de loop fot?

No basta con colocar:
if(ataquejugador[index] == ataqueEnemigo).

Sabemos que para asimilar el conocimiento adquirido en las clases hay que practicar, pero también podemos aprender bastante tomándonos una pausa y leyendo nuestro código una y otra vez. En lo personal pienso que a veces este curso avanza a pasos agigantados y está bien seguir ese paso, pero por otro lado también debemos tomarnos un buen rato para leer, comprender y tratar de optimizar el código por nuestra cuenta.

Pesimo profesor zzz

Hubo error de typo en la función indexAmbosOponentes ya que se agregó a la variable del enemigo en la variable de jugador

me perdi hace como 5 clases atras!!! pero aun sigo el codigo! HELP Dioses del internet!

No le cambie el nombre a las variables solo la lógica, en ves de restar vidas, sumamos victorias y se comparan las victorias al final del for para determinar al ganador

lo de ver las clases mas de una vez es muy bueno, es la segunda vez que veo estas dos ultimas clases y me di cuenta que me perdi varias cosas

No se estresen! Si no entienden, enfoquense en la primera reproducción a entender la lógica general (qué pretende, cuál es el objetivo) sin fijarse en el paso a paso. Después de tener claro el objetivo no vean el video sino que hagan un paso a paso mental de qué harían y escríbanlo y en la segunda reproducción del video, poco a poco van pasando por ese paso a paso y lo van comparando con lo que dice el profe. Ánimo! Recuerden que si fuera un trabajo fácil no estaríamos moldeando el futuro de los humanos!!!

tengo la sensacion de que escribio mal este parte del codigo?

“function indexAmbosOponente(jugador,enemigo){indexAtaqueJugador=ataqueEnemigo[jugador]
indexAtaqueEnemigo=ataqueEnemigo[enemigo]}”

se repite ataqueEnemigo y le pide jugador a una y enemigo a otra, no tendria que ser ataqueJugador?

Así me quedó, sencillo pero aprendiendo mucho. Gracias

Yo solucioné el problema del minuto 3:33 añadiendo un contador y que sume cada vez que hago click en un botón

hola, si esoy entendiendo lo que el esta haciendo pero me confunde con tanto poner y quitar, hago mi mejor esfuerzo de comprender algunas coas

De momento al querer abrir los archivos de clase en el apartado de recursos ya no se abren los documentos donde vienia el codigo para poder estar revisando que e slo que puedo estar fallando, le doy click y sale una linea que esta cargando, termina de cargar y no se abre

Plazti al final del dia me muestra que “estudie en el dia” 2 horas, despues de que fueron mas de 10 o 12 horas en promedio diario, termine de ver esta clase a las 12:46, agregare otro comentario al terminar

Si alguient iene el error “undefined” en la seccion de los logs de ataque, por favor intenten reemplazar con este codigo:

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

    if(ataqueAleatorio==0||ataqueAleatorio == 1){
        ataqueEnemigo.push("FUEGO")
    }
    if(ataqueAleatorio==2||ataqueAleatorio==4){
        ataqueEnemigo.push("AGUA")
    }
    else{
        ataqueEnemigo.push("TIERRA")
    }
    iniciarPelea()   
}

Me gustaría comentar, que realmente asi es como va la vida real, pasa que te equivocas, y tienes que volver en tus pasos, o revisar si al cambiar elementos debes corregir otros, sin embargo al final es algo que probablemente valga la pena n.n

este tipo de problemas con javascript es la razon por la que han creado lo que se llaman “frameworks” o basicamente recomposiciones de la forma en la que funciona un lenguaje para personalizar como este funciona, y en este caso, hacerlo más amigable con el programador c:

Era preferible que tumbaran todo el juego y nos enseñaran a como hacerlo mas optimo desde el principio, es algo enredado seguirle el ritmo ya que exiten varias variables que sirven y unas que ya no…

Lo realice así y me corre bien, pero el crearMensaje no me funciona así que lo voy a quitar

function combate() {

  for (let index = 0; index < ataqueJugador.length; index++) {
    if(ataqueJugador[index] === ataqueEnemigo[index]) {
      indexAmbosOponetes(index, index)
      crearMensaje("EMPATE 🙄")
    } else if (ataqueJugador[index] === "FUEGO" && ataqueEnemigo[index] == "TIERRA") {
      indexAmbosOponetes(index, index)
      crearMensaje("GANASTE 😁")
      victoriasJugador++
      spanvidaJugador.innerHTML = victoriasJugador
    } else if (ataqueJugador[index] == "AGUA" && ataqueEnemigo[index] == "FUEGO") {
      indexAmbosOponetes(index, index)
      crearMensaje("GANASTE 😁")
      victoriasJugador++
      spanvidaJugador.innerHTML = victoriasJugador
    } else if (ataqueJugador[index] == "TIERRA" && ataqueEnemigo[index] == "AGUA") {
      indexAmbosOponetes(index, index)
      crearMensaje("GANASTE 😁")
      victoriasJugador++
      spanvidaJugador.innerHTML = victoriasJugador
    } else {
      indexAmbosOponetes(index, index)
      crearMensaje("PERDISTE 😢")
      victoriasEnemigo++
      spanvidaEnemigo.innerHTML = victoriasEnemigo
    }
  }
  revisarVictorias()
}

ayuda!!! cuando selecciono mi ataque no lo toma en cuenta oseaa no me sale lo que eleji solo sale como si no existiera mi bariable de ataqueJugador que supuestamente guarda mis ataques tampoco cambia de color mi botn al seleccionarlo

A estas alturas, he estado sintiendo que se hace cada vez más dificil seguir el ritmo, respecto a entendimiento de como estamos estructurando el juego, que soluciones vamos dando para la implementación de nueva lógica, etc, a este punto solo he estado haciendo lo mismo que el profesor más que sentirme motivado a buscar mis soluciones y otras formas de implementar código, cosa que tenía haciendo a lo largo del curso

Que cansado estoy de los Mokepones jaja, un poco frustrado, la verdad, como alguien dijo por ahí la curva de aprendizaje de repente y sin previo aviso paso de 30 a 80!!! Cuando paso eso?, la verdad como curso de programación básica, aunque en verdad aunque sea básico o lo que sea, como que el cambio fue demasiado brusco! Sin previo aviso, sin preámbulo, tan solo de repente cambio de 30 a 80!, y creo que para el manejo del aprendizaje y la frustración no sé que tan útil es enseñar así , pero buen seguimos dándole y poniéndole entusiasmo solo pensando en que de poquito entre el conocimiento, preocupado de ser detallista y no romper el código, pero que difícil es entender tanto concepto junto por clase sin mucha explicación de por medio, frustra mucho eso la verdad. ¡Quizás no sería mejor meter menos conceptos, pero explicar un poco más?, bueno en fin mi humilde opinión, de todas formas doy muchas gracias a Platzi por qué se que es gratis y bueno tratamos de sacar las cosas adelante a pesar de la frustración!! Vamos equipo!

mi solución:

function crearMensaje(){
        
            for (let i = 0; i < ataquesJugador.length; i++) {
                let resultadoParcial = batalla(ataquesJugador[i],ataquesEnemigo[i])
                resultado.push(resultadoParcial)
                let opcionAtaqueJugador = `<p> ${ataquesJugador[i]} </p>`
                sectionAtaquesJugador.innerHTML += opcionAtaqueJugador
                let opcionAtaqueEnemigo = `<p> ${ataquesEnemigo[i]} </p>`
                sectionAtaquesEnemigo.innerHTML += opcionAtaqueEnemigo
                victoriasJugador += resultadoParcial[0]
                victoriasEnemigo += resultadoParcial[1]

            }

Esto teniendo en cuenta que mi función de batalla devuelve un array
posición 0: 1 si ganó el jugador o 0 si fue empate o ganó el enemigo
posición 1: 1 si ganó el enemigo o 0 si fue empate o ganó el jugador
posición 2: String con “Ganaste”, “Perdiste” o “Empate” según el caso

function batalla(jugador1, jugador2){
    if (jugador1 ==jugador2){
    return([0,0,'EMPATE 🤝'])
} else if((jugador1 =="Fuego" && jugador2 =="Tierra")||
         (jugador1 =="Agua" && jugador2 =="Fuego")||
         (jugador1 =="Tierra" && jugador2 =="Agua")){

    return([1,0,'GANASTE 🎉🥳'])
        }else{
            
        return([0,1,'PERDISTE 😿💔'])
        }
}

function combate () {

for (let index = 0; index < ataqueJugador.length; index++) 
   if(ataqueJugador[index] == ataqueEnemigo[index]) {
        indexAmbosOponentes (index, index)
        crearMensaje("EMPATE")
        //desafio completado
   }else if (ataqueJugador[index] > ataqueEnemigo[index]){
    indexAmbosOponentes (index, index)
    crearMensaje("GANASTE")
    vidasEnemigos--
    spanVidasEnemigos.innerHTML = vidasEnemigos  
   }else {
    indexAmbosOponentes (index, index)
    crearMensaje("PERDISTE")
    vidasJugador--
    spanVidasJugador.innerHTML = vidasJugador 
}
revisarVidas()

}

Se que la probabilidad es baja que ayuden a responder 😅 pero ¿alguien sabe porque el array que guarda los ataques “hasta 5” solo sigue alimentando con los dos botones que agregamos? ¿si se supone que son el mismo?
Si encuentro la respuesta espero acordarme a venir a dejarla 😅

Supongo que la lógica es más para cuando va a ser multiplayer, y de paso contra el pc. Que locura enlazar tantas cosas en la cabeza y más si toca esperar hasta el final para ver realmente que quiere generar 😅

Ya estoy desviándome, porque decidí continuar las clases sin antes corregir el error de que al presionar cualquier ataque, la consola sólo me imprime ‘TIERRA’, y hasta este punto veo obligatoriamente que debo corregir eso, porque así nunca voy a perder, siempre será empate ya que el jugador y el enemigo sólo atacan con ‘TIERRA’, aunque esté dándole al botón de agua o fuego.

Hasta estas clases sólo voy avanzando por llevarle el ritmo al profe, pero no es que esté entendiendo lo que hago del todo, por eso no he podido corregirlo y no sé cómo me pueda ayudar alguien aquí.

Reto cumplido y arreglo de los bugs faltantes como

  • Elemento seleccionar, si no se elige un animal se reiniciara hasta que se escoja alguna opción
  • Que se muestren todos los ataques, no solo el primero, con cada validación se entra en una nueva función que muestra el mensaje actual de fuego tierra etc
  • El reto de validar si el ataque dado gana o se pierde era igual que la anterior pero ahora se valida es con un array
  • Cree una logica para que cada animal tenga una vida diferente, entonces en el constructo le agrege el elemento vida, y cuando se seleccionara un animal este tendria la vida del mokepon elegido, se tubo que borrar la vida que estaba contenida en el html y este valor lo pondría en la mitad del juego cuando ya tanto el jugador como el enemigo escogieran una mascota

Se acuerdan del 5 que era una cantidad de los elementos del array ja que creen esa monda también se puede automatizar pillen
En resumen se crea un ciclo con la cantidad de elementos existentes en este caso son 3 pokemones, durante ese ciclo se verifica que la selección del jugador sea igual al elemento del array seleccionado cuando este valor es valido se verifica si su contenido llega al limite se ejecute la función

alguien mas se dio cuenta de que la mascota enemiga y sus ataques no coinciden pensé que solo era en mi código pero viendo la clase me di cuenta de que a el también le pasa aunque escojan la misma mascota los ataques del enemigo no coinciden con la mascota

me paso factura el ponerle nombres diferentes a las variables pero me ayuda a estar mas atento a mi código y no solo copiar el de el

Emmm, lo intenté, pero ahaora no me sale el boton de reiniciar xD

function combate(){  
    for (let index = 0; index < ataqueJugador.length; index++) {
        if(ataqueJugador[index] === ataqueEnemigo[index]){
            indexAmbosOponentes(index, index)
            crearMensaje("EMPATE")
        } else if(ataqueJugador[index] == 'FUEGO' && ataqueEnemigo[index] == 'TIERRA' || ataqueJugador[index] == 'TIERRA' && ataqueEnemigo[index] == 'AGUA' || ataqueJugador[index] == 'AGUA' && ataqueEnemigo[index] == 'FUEGO'){
            indexAmbosOponentes(index, index)
            crearMensaje("GANASTE")}
            else{crearMensaje("PERDISTE")}
    }
}

Siento que los ataques pudieron haberse creado con una clase en la cual le podriamos indicar los ataques a los que son debiles y asi hacer una validacion parecida a esta

 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';
    }

Lo del reto

me encanta las clases. allí decía básico, pero ahora se vuelve muy interesante …
¡Cada día es una nueva oportunidad para aprender algo nuevo y crecer como persona! No importa cuán difícil pueda parecer un desafío, siempre hay una manera de superarlo.

Genial…!

Asi es que lo hice yo 😃 despues de estar un poco enredado y tener un error en un boton, me siento feliz de poder hacer esto yo solo y que funciona

function combate(){

    for (let index = 0; index < ataqueJugador.length; index++) {
        if(ataqueJugador[index] == ataqueEnemigo[index]) {
            indexAmbosOponentes(index, index)
            crearMensaje("EMPATE🤡")
        } else if (ataqueJugador[index] == "FUEGO🔥" && ataqueEnemigo[index] == "TIERRA🌱") {
            indexAmbosOponentes(index, index)
            crearMensaje("GANASTE🤑")
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = vidasEnemigo
        } else if (ataqueJugador[index] == "AGUA💧" && ataqueEnemigo[index] == "FUEGO🔥") {
            indexAmbosOponentes(index, index)
            crearMensaje("GANASTE🤑")
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = vidasEnemigo
        } else if (ataqueJugador[index] == "TIERRA🌱" && ataqueEnemigo[index] == "AGUA💧") {
            indexAmbosOponentes(index, index)
            crearMensaje("GANASTE🤑")
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = vidasEnemigo
        } else {
            indexAmbosOponentes(index, index)
            crearMensaje("PERDISTE🤐")
            vidasJugador--
            spanVidasJugador.innerHTML = vidasJugador
        }
        
    }
    revisarVidas()
}

lo logre 😄 ya pase todo de vidas a victorias he ice que el combate funcionara, lo unico es que no logro aun que muestre todos los ataques solo muestra lo último seleccionado :'u

Desde mi punto de vista creo que hubiera sido mas fácil y entendible si se hubiera hecho todo este nuevo código en contraste con el anterior, en lugar de ir borrando y moviendo todo, es muy fácil perderse, en lo personal estoy entendiendo todo pero mi código ya no funciona desde hace 2 clases jajaja

Por alguna razon me daba error con la siguiente funcion :

function seleccionarMascotaEnemigo() {
    const mascotaAleatorio = aleatorio(0,mokepones.length -1)
    spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatorio].nombre

    ataquesMokeponEnemigo = mokepones[mascotaAleatorio].ataques
    secuenciaAtaque()
}

No sé porque al poner el “;” en spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatorio].nombre; se quitaba el error, alguien me lo puede explicar, no entiendo, yo hice tal cual la clase

Buenas noches
Comparto mi solución del reto así me quedo

y el código lo valide con estas dos funciones

Al final el código se perdió todo y se desordenó quedando en mi opinión muy poco “optimizado”

Esta fue mi solución del pequeño reto:

Y este es el código:

[](

Estuve cacharreando un tiempo para hacer las siguientes mejoras:

  • Determinar la mascota del enemigo y seleccionar los ataques
  • Solo seleccionar los ataques de la mascota del enemigo
  • Iluminar el boton de ataque del enemigo del momento
  • Si ya se utilizo el boton del enemigo, seleccionar otro boton
  • Mostrar los resultados del combate
    Aqui unos apartados:
function selectAttackEnemy() {
    //  Debemos buscar en los botoles del enemigo uno con el ataque    
    let buttonSelectEnemy = document.getElementsByName("attacksenemy")
    let attackEnemyNumber

    let freeArray = false
    while (freeArray === false) {
        attackEnemyNumber = random(1, 5);

        // Para que lo ubique en el array correctamente        
        attackEnemyNumber = attackEnemyNumber - 1;

        if (buttonSelectEnemy[attackEnemyNumber].title != 'XXXX') {
            freeArray = true
        }
    }

    // Leo el array, para traer todos los ataques
    attackEnemy = ContainArrayAttacksEnemy[attackEnemyNumber];

    arrayAttackEnemy.push(attackEnemy.title)
    idAttackEnemyCombat.innerHTML = attackEnemy.title

    buttonSelectEnemy[attackEnemyNumber].style.background = '#8a2be2'
    buttonSelectEnemy[attackEnemyNumber].title = 'XXXX' //Para que ese boton no lo vuelva a colorear
}

```![](![pet.png](https://static.platzi.com/media/user_upload/pet-a87491c0-f97d-4d76-a0de-574b4e679175.jpg)

💔 Cómo cuando mi código está roto, al igual que mi corazón 😭

Es mucha información, quizás deberían dividir el curso de programación básica, en vez de tener 84 clases juntas

Presento mi solución 😁

Hice una pequeña modificación en mi función iniciarPelea().
Utilicé dos variables en la validación, lo que hace el código un poco más escalable, debido a que es una modificación menos que se haría indistintamente si la cantidad de ataques cambia a 10, 20, 50, etc.:

function inicioataque() {
    if (ataqueJug.length == ataquesMascota.length) {
        verificarataques()
    }
}

Algo que pueden hacer es llamar mejor a las variables, a mi parecer es mejor poner ataques y no ataque, ya que ponerlo en plural da a entender que son varios y por ende una lista, en este caso los ataques pero sirve para cualquier código que estén desarrollando

Es increible la forma en que se utiliza los codigos de ciclo “for” para establecer un listado de variables declaradas en un videojuego. Sigo impresionado. Si asi se optimiza o se trabaja un codigo en el trabajo, se nota que me faltaba esa parte cuando empece.

Creamos nueva función con nuevas variables para asignarle a sus variables el resultado de index que seria un numero y luego estas variables las hacemos globales y de tipo let para que que vaya modificando su contenido(numeros), para poder usarlas después.