Fundamentos de Programación

1

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

2

Programación en Navegadores: Primeros Pasos

3

Crea tu primer sitio web

4

Sitios web con HTML

5

Estructura de árbol en HTML

6

Instalando tu primer editor de código

7

Cómo declarar variables y usar prompt

8

Algoritmo de piedra, papel o tijera

9

Algoritmo avanzado de piedra, papel o tijera

10

Aleatoriedad

11

Refactor del código usando funciones

12

Ciclos

13

Gana 3 veces

14

Archivos de HTML y JavaScript

15

¿Qué es el DOM?

Quiz: Fundamentos de Programación

Desarrollando un juego con HTML y JavaScript

16

Maquetación con HTML

17

Sección de elegir mascota

18

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

19

Escuchando eventos con JavaScript

20

addEventListener

21

Manipulación del DOM

22

Enemigos aleatorios

23

Ataques en JavaScript

24

Ataques aleatorios del enemigo

25

Imprimiendo ataques del enemigo

26

¿Ganaste, perdiste o empataste?

27

Tablas de verdad

28

Creando el contador de vidas

29

¿Quién ganó el juego?

30

Reiniciando el juego

31

Ocultando elementos HTML con JS para mejorar la UX del juego

Quiz: Desarrollando un juego con HTML y JavaScript

Estilos con CSS

32

Anatomía de CSS

33

Tipos de display

34

Flexbox

35

Modelo de caja

36

Imágenes para los Mokepones

37

Estilos del botón

38

Adaptando HTML al diseño del juego

39

Layout: título y ataques

40

Adaptando JavaScript al diseño del juego

41

CSS Grid

42

Responsive Design

43

Detalles finales

Quiz: Estilos con CSS

Optimización de código

44

Revisión de código

45

Don't repeat yourself (DRY)

46

Clases y objetos

47

Clases y objetos de Mokepon

48

Arrays o arreglos

49

Objetos vs. arreglos

50

Ciclos: manipulando el DOM con iteradores

51

Declaración lenta de variables

52

Una sola fuente de la verdad

53

Mascotas aleatorias con arreglos

54

Ataques dinámicos por cada mascota: extraer

55

Renderizado dinámico en HTML

56

Eventos de click dinámicos

57

Secuencia de ataques del enemigo

58

Iniciando el combate

59

Resolviendo el reto de condicionales

60

Optimizando el frontend del juego

Quiz: Optimización de código

Mapa con canvas

61

Introducción a canvas: dibujando con JavaScript

62

Moviendo a Capipepo hacia la derecha

63

Movimiento hacia todas las direcciones

64

Movimientos con el teclado

65

Imágenes y personajes de fondo

66

Métodos en las clases

67

Obstáculos y colisiones

68

Combate entre mokepones colisionados

69

Mapa responsive

70

Botones bonitos y viewport

Quiz: Mapa con canvas

Backend: videojuego multijugador

71

¿Qué es backend?

72

Instalación de Node.js y NPM

73

Terminal de comandos y Node.js

74

Servidor web con Express.js

75

HTTP, localhost, servidores y puertos

76

Express.js y fetch: API REST con JavaScript

77

JSON y POST: mokepon online

78

Transmisión de coordenadas

79

Mokepones dinámicos en el mapa

80

Optimizando el mapa del juego

81

Batalla entre jugadores

82

Consumiendo la API de ataques del enemigo

Quiz: Backend: videojuego multijugador

Próximos pasos

83

Probando el juego en varios dispositivos

84

¿Y ahora qué curso tomar?

No tienes acceso a esta clase

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

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 160

Preguntas 44

Ordenar por:

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

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

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

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.

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

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

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.

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 😄

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í…

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

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.

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]

muy mal profesor

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

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();
}

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.

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()

}
"tu ya sabes como hacer esto".😅

Soy esta

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

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:

Yo también pensé en rendirme cuando había checado más de 3 veces la clase, modificado el código y probado sin éxito, al final lo logré, no solo con 3 si no con 6 mokepones. Si yo pude tu también puedes. 💪
recuerden este juego es sullo pueden modificar todo encambio yo no quise que sea como el profe yo quiso de otra manera haci es como hay que hacerlo como a ustedes les guste no estan obligados a hacer los mismo del profe
Cuando corro el programa no me imprime los ataques como aparecen en la clase del profesor, debajo del nombre de la mascota. Reviso el codigo y no encuentro la diferencia con la del profe. Si alguien le paso y lo soluciono favor compartirmelo. Gracias

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.

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!!.

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

Mi solución al reto :) ![](https://static.platzi.com/media/user_upload/image-ed9119d9-2c71-47f0-8438-c13857726b81.jpg)
¿Yo no sé qué pasa, pero borre todo el código descargue el código de la clase y tengo todo tal cual, y no me aparecen los botones de los ataques, ya no sé qué más hacer alguien que me ayude? 😭😭
tengo un problema es que la pc solo me envia tierra
Primero hago un array con los resultados de victoria y derrota, donde los índices van a ser los ataques, victoria es un 1, empate 0 y derrota -1, así al final sumo cada uno de los elementos del array y si el resultado es mayor a 0 ganas, si es menor pierdes o si es 0 empatas, hay que convertir los a ataques a números del 0 al 2 para que pueden ser usados como los índices. Así es mas escalable si ponemos mas tipos de ataque. ```js /* Condición de victoria Fuego Agua Tierra Fuego [Empata] [Pierde] [Gana] Agua [Gana] [Empata] [Pierde] Tierra [Pierde] [Gana] [Empata] 0 = Empate, 1 = Gana jugador, 2 = Gana oponente */ const comparar = [ [0, -1, 1], [1, 0, -1], [-1, 1, 0] ]; /* ---------------------- */ function convertirAtaque(ataque){ if (ataque === "FUEGO") return 0 else if (ataque === "AGUA") return 1 else return 2 } function combate(){ let batallas = [] for (let i = 0; i < ataqueJugador.length; i++){ let ataqueJugadorNumero = convertirAtaque(ataqueJugador[i]) let ataqueEnemigoNumero = convertirAtaque(ataqueEnemigo[i]) let batallaActual = comparar[ataqueJugadorNumero][ataqueEnemigoNumero] batallas.push(batallaActual) mostrarMensajeAtaques(ataqueJugador[i], ataqueEnemigo[i]) } let resultado = 0 for (let i = 0; i < batallas.length; i++){ resultado += batallas[i] } if (resultado === 0) sectionMensajes.innerHTML = "EMPATE" else if (resultado > 0) sectionMensajes.innerHTML = "GANAS" else sectionMensajes.innerHTML = "PIERDES" seccionReiniciar.style.display = "block" } ```
no quiero que me cambie de color el botón que ya seleccione sino que desaparezca 😎 con esa línea de código que resalte para el que le guste
con las Tablas de Verdad 🤩 ![](https://static.platzi.com/media/user_upload/Captura%20de%20pantalla%202024-05-21%20114731-b579d227-2699-49c5-b225-19060748fd2c.jpg)
así quedó el código de la batalla. hay que destacar que había cometido 2 errores, 1 en indeAm....(index, ..) coloque fue (jugada, rival) 2 las vidas... ahí vamos...👇 ![](https://static.platzi.com/media/user_upload/reto-0fecd69c-bf29-41e1-a9e6-de050217a1a2.jpg)
Me he perddo un poco con el tema de IndexAmbosOponentes.... Espero volver a ponerme al día en la siguiente clase ;D
Antes ```js function combate() { for (let index = 0; index < ataqueJugador.length; index++) { if(ataqueJugador[index] === ataqueEnemigo[index]){ indexAmbosOponentes(index, index) crearMensaje("EMPATE") } } 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() } ``` Despues ```js function combate() { for (let index = 0; index < ataqueJugador.length; index++) { indexAmbosOponentes(index, index) if (indexAtaqueEnemigo == indexAtaqueJugador) { crearMensaje("EMPATE") } else if ( (indexAtaqueJugador == "FUEGO" && indexAtaqueEnemigo == "TIERRA") || (indexAtaqueJugador == "AGUA" && indexAtaqueEnemigo == "FUEGO") || (indexAtaqueJugador == "TIERRA" && indexAtaqueEnemigo == "AGUA") ) { crearMensaje("GANASTE") vidasEnemigo-- spanVidasEnemigo.innerHTML = vidasEnemigo } else { crearMensaje("PERDISTE") vidasJugador-- spanVidasJugador.innerHTML = vidasJugador } } revisarVidas() } ```
para los que les salga undefind revisen estas dos funciones y que sus ataques sean iguales puede que si hay una diferencia aunque sea minima a la hora de que se comparen salga undefind la verdad estuve 1 hora revisando mi codigo y tuve que sacar logica y entender bien el codigo hasta encontrarlo: espero que les sea de ayuda ![](https://static.platzi.com/media/user_upload/image-4dcbc8de-f1cb-4264-940b-1ae4a227553c.jpg)
¿Dañe el código alguien me ayuda a ver lo que le paso a mi código? const sectionReiniciar = document.getElementById("reiniciar");const sectionSeleccionatMascota = document.getElementById("seleccionar-mascota");const sectionSeleccionatAtaque = document.getElementById("seleccionar-ataque");const spanMascotaJugador = document.getElementById('mascota-jugador');const contenedorTarjetas = document.getElementById("contenedorTarjetas")const contenedorAtaques = document.getElementById("contenedorAtaques") let mokepones = \[];let ataqueJugador = \[]let ataqueEnemigo = \[]let inputCapipepo let inputRatigueya let inputHipodoge let personajeJugadorlet botonSanto let botonMaldicionlet botonFisico let reiniciar let opcionDePersonajeslet opcionDeAtaqueslet vidasJugador = 3;let vidasEnemigo = 3; class mokepon {    constructor(nombre, foto, vida) {        this.nombre = nombre;        this.foto = foto;        this.vida = vida;        this.ataques = \[];          }} let Marco = new mokepon("Marco", "./Imagenes/14aec2eb-7a41-41ac-86f8-825fb35a3466.png", 3);let Elena = new mokepon("Elena", "./Imagenes/889661b0-c35e-4462-83ba-607f699ecd22.png", 3);let Diego = new mokepon("Diego", "./Imagenes/Sett.png", 3); Marco.ataques.push(        {nombre: "⛩" , id: "boton-Santo"},        {nombre: "⛩" , id: "boton-Santo"},        {nombre: "⛩" , id: "boton-Santo"},        {nombre: "👺" , id: "boton-Maldicion"},        {nombre: "👊" , id: "boton-Fisico"},) Elena.ataques.push(    {nombre: "👺" , id: "boton-Maldicion"},    {nombre: "👺" , id: "boton-Maldicion"},    {nombre: "👺" , id: "boton-Maldicion"},    {nombre: "⛩" , id: "boton-Santo"},    {nombre: "👊" , id: "boton-Fisico"},) Diego.ataques.push(    {nombre: "👊" , id: "boton-Fisico"},    {nombre: "👊" , id: "boton-Fisico"},    {nombre: "👊" , id: "boton-Fisico"},    {nombre: "⛩" , id: "boton-Santo"},    {nombre: "👺" , id: "boton-Maldicion"},    ) mokepones.push(Marco, Elena, Diego) function iniciarJuego() {        sectionReiniciar.style.display = "none";    sectionSeleccionatAtaque.style.display = "none";     mokepones.forEach((mokepon) => {        opcionDePersonajes = `        \<input type="radio" name="mascota" id=${mokepon.nombre} />        \<label class="tarjeta-de-personaje" for=${mokepon.nombre}>${mokepon.nombre}            \        \</label>    `    contenedorTarjetas.innerHTML += opcionDePersonajes        inputHipodoge = document.getElementById('Marco');        inputCapipepo = document.getElementById('Elena');        inputRatigueya = document.getElementById('Diego');            ;    })     let botonMascotaJugador = document.getElementById('boton-mascota');    botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador);    } function seleccionarMascotaJugador() {    sectionSeleccionatMascota.style.display = "none";    sectionSeleccionatAtaque.style.display = "flex";     if (inputHipodoge.checked) {        spanMascotaJugador.innerHTML = inputHipodoge.id;        personajeJugador = inputHipodoge.id;    } else if (inputCapipepo.checked) {        spanMascotaJugador.innerHTML = inputCapipepo.id;        personajeJugador = inputCapipepo.id;    } else if (inputRatigueya.checked) {        spanMascotaJugador.innerHTML = inputRatigueya.id;        personajeJugador = inputRatigueya.id;    } else {        alert('Selecciona una mascota');    }    extraerAtaques(personajeJugador);    seleccionarMascotaEnemigo();} function extraerAtaques(personajeJugador) {    let ataques    for (let i = 0; i < mokepones.length; i++) {        if (personajeJugador == mokepones\[i].nombre) {            ataques = mokepones\[i].ataques                    }    }            mostrarAtaques(ataques)} function mostrarAtaques(ataques) {    ataques.forEach((ataque) =>{        ataquesPersonajes = `        \<button id=${ataque.id} class="boton-ataque BAtaque ">${ataque.nombre}\</button>        `            contenedorAtaques.innerHTML += ataquesPersonajes    })     botonSanto = document.getElementById("boton-Santo");    botonMaldicion = document.getElementById("boton-Maldicion");    botonFisico = document.getElementById("boton-Fisico");    reiniciar = document.getElementById("boton-reiniciar");    reiniciar.addEventListener("click", reiniciarJuego);    botones = document.querySelectorAll(".BAtaque")}function secuenciaAtaque() {    botones.forEach((boton) => {        boton.addEventListener("click", (e) => {            if (e.target.textContent === "⛩") {                ataqueJugador.push("⛩");                console.log(ataqueJugador);            } else if (e.target.textContent === "👺") {                ataqueJugador.push("👺");                console.log(ataqueJugador);            } else {                ataqueJugador.push("👊");                console.log(ataqueJugador);            }        });     }); } function iniciarPelea() {    if (ataqueJugador.length === 5) {        console.log("Ataque del jugador: ", ataqueJugador);        console.log("Ataque del enemigo: ", ataqueEnemigo);    }} ataqueAleatorioEnemigo();   function seleccionarMascotaEnemigo() {    let PersonajeAleatorio = aleatorio(0, mokepones.length - 1);     let spanMascotaEnemigo = document.getElementById('mascota-enemigo');    spanMascotaEnemigo.innerHTML = mokepones\[PersonajeAleatorio].nombre;    ataqueEnemigo = mokepones\[PersonajeAleatorio].ataque;       secuenciaAtaque()    } function ataqueAleatorioEnemigo() {    let ataqueAleatorio = aleatorio(0, ataqueEnemigo.length -1);            if (ataqueAleatorio == 0 || ataqueAleatorio == 1) {            ataqueEnemigo.push("Santo")        } else if (ataqueAleatorio == 3 || ataqueAleatorio == 4){            ataqueEnemigo.push("Maldicion")        } else {            ataqueEnemigo.push("Fisico")        }            Pelea(ataqueJugador, ataqueEnemigo);    }function Pelea(ataqueJugador, ataqueEnemigo) {    let resultado;    let spanVidasJugador = document.getElementById("vidas-jugador");    let spanVidasEnemigas = document.getElementById("vidas-enemigas");    for (let index = 0; index < ataqueJugador.length; index++) {        if (ataqueJugador\[index] === ataqueEnemigo\[index]) {            crearMensaje("EMPATE")        }    }    let ataqueJugadorString = ataqueJugador.join('');    let ataqueEnemigoString = ataqueEnemigo.join('');     if (ataqueJugadorString === ataqueEnemigoString) {        resultado = "Empate🤼‍♂️!";    } else if (        ((ataqueJugadorString === "Santo" && ataqueEnemigoString === "Maldicion") ||            (ataqueJugadorString === "Maldicion" && ataqueEnemigoString === "Fisico") ||            (ataqueJugadorString === "Fisico" && ataqueEnemigoString === "Santo"))    ) {        resultado = "¡GANASTE! 🥳";        vidasEnemigo--;        spanVidasEnemigas.innerHTML = vidasEnemigo;    } else {        resultado = "Perdiste! 😢";        vidasJugador--;        spanVidasJugador.innerHTML = vidasJugador;    }    revisarVidas();    creatMensaje(resultado);} function revisarVidas() {    if (vidasEnemigo == 0) {        creatMensajeFinal("Ganaste buena🎉🥳!");    } else if (vidasJugador == 0) {        creatMensajeFinal("Perdiste, que mal😢. Suerte la proxima!");    }} function creatMensaje(resultado) {    let notificacion = document.createElement("p");    let nuevoAtaqueDelJugador = document.createElement("p");    let nuevoAtaqueDelEnemigo = document.createElement("p");     notificacion.innerHTML = resultado;    nuevoAtaqueDelJugador.innerHTML = ataqueJugador;    nuevoAtaqueDelEnemigo.innerHTML = ataqueEnemigo;         // Se obtienen las referencias de los elementos donde se insertarán los mensajes        let sectionMensajes = document.getElementById("mensajes");        let ataquesDelJugador = document.getElementById("ataquesDelJugador");        let ataqueDelEnemigo = document.getElementById("ataqueDelEnemigo");            sectionMensajes.innerHTML = resultado;        sectionMensajes.appendChild(notificacion);        ataquesDelJugador.appendChild(nuevoAtaqueDelJugador);        ataqueDelEnemigo.appendChild(nuevoAtaqueDelEnemigo);            // Insertar el ataque del jugador debajo del nombre de la mascota del jugador        let mascotaJugador = document.getElementById('mascota-jugador');        mascotaJugador.insertAdjacentElement('afterend', nuevoAtaqueDelJugador);    }        function creatMensajeFinal(resultadoFinal) {        let sectionMensajes = document.getElementById("mensajes");        let parrafo = document.createElement("p");        parrafo.innerHTML = resultadoFinal;        sectionMensajes.appendChild(parrafo);        let botonSanto = document.getElementById("boton-Santo");        botonSanto.disabled = true;        let botonMaldicion = document.getElementById("boton-Maldicion");        botonMaldicion.disabled = true;        let botonFisico = document.getElementById("boton-Fisico");        botonFisico.disabled = true;            let sectionReiniciar = document.getElementById("reiniciar");        sectionReiniciar.style.display = "block";    }        function reiniciarJuego() {        location.reload();    }        function aleatorio(min, max) {        return Math.floor(Math.random() \* (max - min + 1) + min);    }        window.addEventListener('load', iniciarJuego);
Lo siento, Diego ☹️, no entendí en absoluto la función de `indexAmbosOponente(jugador, enemigo)`. En mi juego, inserto en el HTML la lista con los ataques de cada uno y lo hago con una función que he llamado `mostrarSecuencia(mascota, ataque, elementOList)` ![](https://static.platzi.com/media/user_upload/secuenciaAtaques-03c7b0ab-63b5-443d-aef8-6f4fb70715d4.jpg)
Yo solo hice una variable let v=0 que se fuera sumando cada que se ejecutaba la funcion de combate y cada que queria imprimir el ataqueJugador o ataqueEnemigo en otra funcion o hacer la validacion de quien gano empato o perdio lo hacia de esta forma ataqueJugador\[v] == ataqueEnemigo\[v] o ...innerHTML=ataqueJugador\[v] etc
Alguien se dio cuenta que el enemigo no sigue las reglas (Objetos literales) de sus ataques, si no que puede elegir el ataque al azar. Si lo resolvieron, pasen el código.
yo mantengo seradas las function y le pongo el punto rojo a las que utilizo y las abro
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.
```js if (ataqueJugador[i] === ataqueEnemigo[i]) { crearMensaje("EMPATE") indexAmbosOponentes(i, i) } else if (ataqueEnemigo[i] === 'AGUA' && ataqueEnemigo[i] === 'FUEGO' || ataqueEnemigo[i] === 'FUEGO' && ataqueEnemigo[i] === 'TIERRA' || ataqueEnemigo[i] === 'TIERRA' && ataqueEnemigo[i] === 'AGUA') { crearMensaje("GANASTE") vidasEnemigo-- spanVidasEnemigo.innerHTML = vidasEnemigo } else { crearMensaje("PERDISTE") vidasJugador-- spanVidasJugador.innerHTML = vidasJugador } ```if (ataqueJugador\[i] === ataqueEnemigo\[i]) {            crearMensaje("EMPATE")            indexAmbosOponentes(i, i)        } else if (ataqueEnemigo\[i] === 'AGUA' && ataqueEnemigo\[i] === 'FUEGO' || ataqueEnemigo\[i] === 'FUEGO' && ataqueEnemigo\[i] === 'TIERRA' || ataqueEnemigo\[i] === 'TIERRA' && ataqueEnemigo\[i] === 'AGUA') {            crearMensaje("GANASTE")            vidasEnemigo--            spanVidasEnemigo.innerHTML = vidasEnemigo        } else {            crearMensaje("PERDISTE")            vidasJugador--            spanVidasJugador.innerHTML = vidasJugador        }
Las validaciones que yo hice fueron estas, quedo corto y use los operadores lógicos: if (ataqueJugador\[i] === ataqueEnemigo\[i]) {            crearMensaje("EMPATE")            indexAmbosOponentes(i, i)        } else if (ataqueEnemigo\[i] === 'AGUA' && ataqueEnemigo\[i] === 'FUEGO' || ataqueEnemigo\[i] === 'FUEGO' && ataqueEnemigo\[i] === 'TIERRA' || ataqueEnemigo\[i] === 'TIERRA' && ataqueEnemigo\[i] === 'AGUA') {            crearMensaje("GANASTE")            vidasEnemigo--            spanVidasEnemigo.innerHTML = vidasEnemigo        } else {            crearMensaje("PERDISTE")            vidasJugador--            spanVidasJugador.innerHTML = vidasJugador        }```js if (ataqueJugador[i] === ataqueEnemigo[i]) { crearMensaje("EMPATE") indexAmbosOponentes(i, i) } else if (ataqueEnemigo[i] === 'AGUA' && ataqueEnemigo[i] === 'FUEGO' || ataqueEnemigo[i] === 'FUEGO' && ataqueEnemigo[i] === 'TIERRA' || ataqueEnemigo[i] === 'TIERRA' && ataqueEnemigo[i] === 'AGUA') { crearMensaje("GANASTE") vidasEnemigo-- spanVidasEnemigo.innerHTML = vidasEnemigo } else { crearMensaje("PERDISTE") vidasJugador-- spanVidasJugador.innerHTML = vidasJugador } ```
![](https://static.platzi.com/media/user_upload/Screenshot%202023-12-28%2023.29.38-8ec9815c-3580-4b63-9d6e-6d110dcee236.jpg)
Gente, les dejo una funcion general para poder aleatorizar cualquier arreglo que se le pase, muy util. ```js function reordenarAleatoriamente(array) { for (let i = array.length - 1; i > 0; i--) { let j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } return array; } ```
![](https://static.platzi.com/media/user_upload/2023-11-28-68a228b8-1722-4c17-9536-7964888c2c5e.jpg)tengo un problema, y no doy con el mismo... en el html no me imprime los ataques.. pero en la consola si los muestra.... alguna recomendación de que puedo hacer. Gracias
La dificultad va aumentando. Lo bueno es que podemos ver las clases cuantas veces queramos. Cuando nos piden que implementemos una parte del código por nuestra cuenta y logramos solucionarlo sin problemas, nos damos cuenta que estamos avanzando. Para el ejercicio propuesto en esta clase, lo solucione de la siguiente forma: ![](https://static.platzi.com/media/user_upload/image-bd493c24-6723-4ebf-a07e-45ef234c3bce.jpg) hice una validación de cuando gana el jugador y cuando gana el enemigo, para luego sumar victorias y por ultimo dar un mensaje final de ganador, perdedor o empate.

Me ha parecido un poco complicado seguir el ritmo en ocasiones, me frusta no ser tan hábil leyendo y entendiendo mi propio código. Pero veo la facilidad que tiene el profe Diego para identificar problemas en la lógica y me dan ganas de ser tan bueno algún día. Me gustaría saber cuántos años de experiencia tiene, y qué hizo para poder aprender tanto.

¿Es normal que el ataque del enemigo solo sea TIERRA, TIERRA, TIERRA y nunca elija FUEGO o AGUA?

impresionante esto loco hua hua

Estudiando el código encuentro(si no estoy equivocado) que el código está muy “cerrado” no? En el sentido de que si estamos haciendo el código de tal manera que podamos añadir los personajes que queramos, o el número de ataques que queramos etc… Veo que los ataques enemigos, en el momento que queramos hacer más de cinco ataques, la probabilidad de que salga tierra subirá mucho en relación al resto de ataques, porque todo lo que no vaya del 0 al 4 lo abarca “else”.

uffff no entendí nada desde la clases 44 😦

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()

}