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

Optimizando el frontend del juego

60/84
Recursos

Las optimizaciones del c贸digo no solo tienen que hacerse en el c贸digo Javascript para mejorar la l贸gica de un programa. Tambi茅n puede aplicarse en el front-end para mejorar la experiencia de usuario.

Mejoras de experiencia de usuario

Tal vez sea la primera vez que escuches sobre UX, User eXperience o experiencia de usuario. La misma es una pr谩ctica de dise帽o que busca entender el comportamiento de los usuarios de un software y buscar optimizar el mismo para que sea ameno el uso de la aplicaci贸n.

Por ejemplo, en el videojuego que te encuentras desarrollando pueden ocurrir errores visuales que no son gratos para el jugador.

Ejemplo punto de mejora de experiencia de usuario

Como los mokepones tienen muchos ataques, la pantalla queda chica y se rompe el HTML.

Puedes solucionarlo f谩cilmente modificando los estilos CSS del bot贸n de ataque y obtener el siguiente resultado.

.boton-de-ataque {
  background-color: #11468F;
  padding: 10px;
  box-sizing: border-box;
  border-radius: 20px;
  border-color: transparent;
  width: 80px;
  color: white;
  font-family: 'Poppins', sans-serif;
}
Mejora de experiencia de usuario en los botones

Otro problema que tiene el videojuego en este punto es que permite seleccionar todas las veces que el jugador quiera, el mismo ataque. Esto puede causar que el jugador haga trampa o simplemente es un comportamiento que no queremos.

Bloquea el bot贸n que el usuario seleccion贸 f谩cilmente con la propiedad del elemento bot贸n llamada disabled.

function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if (e.target.textContent === '馃敟') {
                // ...
                boton.disabled = true;
            } else if (e.target.textContent === '馃挧') {
                // ...
                boton.disabled = true;
            } else {
                // ...
                boton.disabled = true;
            }
            ataqueAleatorioEnemigo();
        })
    })
}

De esta forma, el usuario estar谩 obligado a seleccionar los cinco ataques de su mokepon y a no repetirlos.

Si recorres tu videojuego, tal vez encuentres muchos otros puntos de mejora que puedes utilizar para practicar y aprender m谩s. Si un amigo o familiar puede utilizar la aplicaci贸n, este puede recomendarte c贸mo mejorar la l贸gica del juego. Siempre es recomendable que otra persona prueba el software que uno mismo est谩 programando para ver cosas que nosotros no podemos ver.

Felicitaciones por llegar hasta este punto del Curso Gratis de Programaci贸n B谩sica de Platzi. Ya tienes toda una aplicaci贸n funcionando para jugar con tu videojuego y optimizada con buenas pr谩cticas de programaci贸n. A partir del siguiente m贸dulo, comenzar谩s a desarrollar un mapa para que los mokepones pueda pasearse por una ciudad antes de iniciar un nuevo combate.

No dudes en continuar. 隆Nos vemos ah铆!


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

Aportes 165

Preguntas 42

Ordenar por:

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

o inicia sesi贸n.

Asi vamos con los nuevos personajes

FRONTEND Y BACKEND EN PLATZI

Frontend

Backend

Creo que en la segunda secci贸n se ha podido hacer algo mejor con la l贸gica de perder vidas, y mejorar la experiencia de usuario.

Felicidades jugador


Has finalizado la secci贸n Optimizaci贸n de c贸digo, descansa aqu铆.

Tuve que repetir varias veces estas 煤ltimas clases, pero al final hemos conseguido el reto 馃挭馃徏

pude hacerlo tomando los nombres de los ataques en el array, y us茅 el m茅todo splice para borrar ataques ya usados por el enemigo, en la consola se puede ver como por cada ataque lanzado se reduce el array de los ataques del enemigo en 1.

He podido meter a las 6 mascotas:

Para poder tener las 6 mascotas centradas y divididas, quite flex y le puse un grip en 2 fracciones.

.tarjetas, .tarjetas-ataques {
    display: grid;
    grid-template-columns: 1fr 1fr;
    justify-items: center; 
    column-gap: 15px;
    row-gap: 15px;
  }


Agregu茅 dos ataques m谩s, viento con Tucapalma:

y veneno con Pydos:


Hay un ganador o perdedor, sin errores y es responsivo:

Les comparto mi avance en Github:
https://github.com/Torofms37/Juego-Web.git

S茅 que falta mejorar dise帽o, pero eso luego lo hago al terminar todas las clases.

Me tomo varias horas pero lo logre 馃槃 cumpl铆 el reto planteado por el profe Diego nnnice

Cuando el jugador selecciona el monstermon y el enemigoSelecionaMonster() se vera en pantalla la img .
y si el monstermon tiene ventaja de tipo se vera en el msm en pantalla otorg谩ndole con ataque adicional de su tipo-especial

el combate sin que el enemigo repita ataques

Pienso que Diego se sali贸 del m茅todo con el que ven铆an los anteriores instructores y no se si es el fin del curso pero lo hizo mas para expertos y aunque es normal tener tropiezos al programar nunca entend铆 por que y para que cambio la l贸gica con la que venia el c贸digo.

La manera en la que consegu铆 que las elecciones fueran aleatorias y no repetidas en el mismo indice fue el siguiente.

function ataqueAleatorioEnemigo() {
  let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length - 1);
  let ataque = ataquesMokeponEnemigo[ataqueAleatorio].nombre;
  ataquesMokeponEnemigo.splice(ataqueAleatorio, 1);

  if (ataque == "馃敟") {
    ataqueEnemigo.push("FUEGO");
  } else if (ataque == "馃挧") {
    ataqueEnemigo.push("AGUA");
  } else {
    ataqueEnemigo.push("TIERRA");
  }

  console.log(ataqueEnemigo);
  inicarPelea();
}

Asigno el valor del elemento del array, luego lo elimino y desp煤es lo valido. De esta manera no se repite. Espero que les sirva 馃槂

las ultimas 4 clases de esta secci贸n me volaron la cabeza que las repetir n n煤meros de veces xD.

Me demore bastante en los detalles de los honguitos pero vali贸 la pena 馃槂馃崉馃挆

hola !!
les comparto mi soluci贸n a los retos del profe Diego

aparte de desactivar los botones, Otra forma de evitar que el usuario pueda elegir el mismo ataque dos veces es hacer desaparecer el boton con el (display = none) que aprendimos a usar en clases anteriores.

en la imagen ya no se ven los botonen porque fueron desacareciendo cada vez que daba click.

Web:


M贸vil:

La verdad el juego me gustaba mas como estaba al principio y no con las modificaciones hechas hasta este punto, sobre todo porque cuando se seleccionaba un ataque aparecia inmediatamente el ataque del jugador y del enemigo, ahora toca esperar hasta que se selecionen los 5 ataques para ver como le fue tanto al jugador como al enemigo, ademas por ningun lado se le explica al jugador las reglas del juego, es decir, que el juego se gana por el n煤mero de victorias, eso le quita emocion y dinamismo鈥ue lastima, se tiro el jueguito馃槮

Asi me quedo despues de cambiar un poco la logica y de agregar las otras mascotas:

Cuando elijo mi mokepon, la mascota del enemigo se elige aleatoriamente y dependiendo de su tipo tambien tendra un ataque mas de ese elemento. y luego empieza el combate (mas estrategico que de suerte):

Para que el usuario no pueda darle click al mismo ataque dos veces los botones van desapareciendo cada que se eligen, y batalla a batalla se va llevando el conteo y te avisa si ganaste o perdiste esa batalla.(los ataques del oponente se eligen aleatoriamente sin repetirse).


Una vez se terminan los ataques te informa el resultado final y si ganaste o perdiste o si fue empate.
Ahora Sigamos Aprendiendo!馃馃馃挭

Saludos. Esta vez no le invert铆 mucho tiempo al UI, aparte de detalles peque帽os. Lo que si hice fue cambiar la l贸gica de algunas funciones para evitar validaciones innecesarias. Adem谩s entre la primera l贸gica (haciendo un combate a la vez) y la de secuencias, a m铆 personalmente me gusta m谩s la primera. Sin embargo le puse la opci贸n para que el usuario pueda escoger en qu茅 modo desea jugar.
Mokepon en GitHub

Live view

Lo que entiendo de esta secci贸n de optimizaci贸n de c贸digo, es que tomamos un proyecto de programaci贸n estructurada y lo migramos a un proyecto OOP, la transici贸n se volvi贸 engorrosa. Yo habr铆a preferido que escribi茅ramos el juego desde cero con la perspectiva OOP

Asi va mi juego de momento

Reto terminado, aunque considero que mostrar los combates uno a uno es mucho mejor y no dar un ataque extra al que tiene una evidente ventaja, pero como reto ya est谩. Soy aprendiz de javascript y mi c贸digo a煤n es bastante redundante, pero a煤n as铆 aqu铆 les dejo mi Codepen
por si les sirve a alguien.

Primera interfaz - Elecci贸n de mascota

Segunda interfaz - Elegir ataques

Tercera interfaz - Resultado del combate

Reto aceptado鈥
Soluci贸n para que los ataques del enemigo no est茅n hardcodeados:

function seleccionarAtaqueEnemigo() {
    let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length -1)
    if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === "馃敟") {
        ataquesEnemigos.push('FUEGO')
    } else if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === "馃挧") {
        ataquesEnemigos.push('AGUA')
    }else {
        ataquesEnemigos.push('PLANTA')
    }
    console.log(ataquesEnemigos)
    iniciarPelea()
}

MOKEPON listo


As铆 es como se ve:

Aqu铆 mi repositorio: Mokepon
Tambi茅n puedes probarlo: 隆Pru茅balo ahora!
Te agradezco mucho por leer 馃挌馃挌馃挌

Les comparto como se ve mi p谩gina al estilo Darksouls hasta el momento鈥

Esta es mi opci贸n de seleccionar el ataque del enemigo de forma aleatoria e independiente de la cantidad de ataques que tenga el personaje

function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo.length - 1)
    ataqueEnemigo.push(ataquesMokeponEnemigo[ ataqueAleatorio ].titulo)
    iniciarPelea()
}

y al guardar los ataques les agrego el titulo que se muestra

ratigueya.ataques.push(
    { nombre: "馃敟", id: "boton-fuego", titulo: "FUEGO" },
    { nombre: "馃敟", id: "boton-fuego", titulo: "FUEGO" },
    { nombre: "馃敟", id: "boton-fuego", titulo: "FUEGO" },
    { nombre: "馃挧", id: "boton-agua", titulo: "AGUA" },
    { nombre: "馃尡", id: "boton-tierra", titulo: "TIERRA" }
)

As铆 qued铆 mi Juego!

https://estebanchica07.github.io/Mokepon-V1/

Gracias profesor Diego por las ense帽anzas. Optimizar el c贸digo es la clave para pensar nuevas soluciones, por eso se me hacia raro que no buscamos la soluci贸n de los ataques del enemigo en su momento, pero genial que aqu铆 lo dej贸 como tarea para nosotros.

Me quem茅 el cerebro mas de una vez pero 隆no desist铆 y no lo har茅!.

No s茅 como llegu茅 hasta aqu铆, y tampoco como le voy a seguir鈥

Dentro de la funci贸n 鈥渇unction combate()鈥 tenemos mensajes como crearMensaje(鈥楨MPATE鈥)/crearMensaje(鈥楪ANASTE鈥)crearMensaje(鈥楶ERDISTE鈥), las cuales ya no se est谩n utilizando, por lo que me parece que se podr铆an remover, ya que solo se muestra el mensaje final de funci贸n revisarVictorias/revisarVidas

Me di cuenta que hay un peque帽o Bug, no s茅 si ya alguien lo habr谩 comentado, cuando no seleccionamos ninguna mascota y le damos 鈥淐lick鈥 al bot贸n de 鈥淪eleccionar鈥 nos manda a la seccion 鈥渟elecionar ataque鈥 mi soluci贸n a este problema fue este.

En la funcion de 鈥淪eleccionarMascotaJugador鈥 lo dejamos as铆.

	//el error era que aqui se estaba mandando a llamar el display "none" y "flex" al  momento de darle click al 
 boton, la solucion fue ponerlos en cada condicional, para que no se ejecute autom谩ticamente al darle click, si no 
cuando este checkeado una mascota.

function seleccionarMascotaJugador() {

  if (inputHipodoge.checked) {
    spanMascotaJugador.innerHTML = inputHipodoge.id;
    mascotaJugador = inputHipodoge.id;
    sectionSeleccionarMascota.style.display = "none";
    sectionSeleccionarAtaque.style.display = "flex";
  } else if (inputCapipepo.checked) {
    spanMascotaJugador.innerHTML = inputCapipepo.id;
    mascotaJugador = inputCapipepo.id;
    sectionSeleccionarMascota.style.display = "none";
    sectionSeleccionarAtaque.style.display = "flex";
  } else if (inputRatigueya.checked) {
    spanMascotaJugador.innerHTML = inputRatigueya.id;
    mascotaJugador = inputRatigueya.id;
    sectionSeleccionarMascota.style.display = "none";
    sectionSeleccionarAtaque.style.display = "flex";
  } else {
    alert("Selecciona una mascota");
  }
  extraerAtaques(mascotaJugador);
  seleccionarMascotaEnemigo();
}

As铆 fue como me qued贸 el proyecto de Mokepon, la verdad tuve que ver clases pasadas y ver algunos de sus aportaciones. Se los agradezco bastante.

<code> 

    if (inputHipodoge.checked) {
        spanMascotaJugador.innerHTML = inputHipodoge.id
        mascotaJugador = inputHipodoge.id
    } else if(inputCapipepo.checked){
        spanMascotaJugador.innerHTML = inputCapipepo.id
        mascotaJugador = inputCapipepo.id
    } else if(inputRatigueya.checked){
        spanMascotaJugador.innerHTML = inputRatigueya.id
        mascotaJugador = inputRatigueya.id
    } else if(inputLangostelvis.checked){
        spanMascotaJugador.innerHTML = inputLangostelvis.id
        mascotaJugador = inputLangostelvis.id
    } else if(inputPydos.checked){
        spanMascotaJugador.innerHTML = inputPydos.id
        mascotaJugador = inputPydos.id
    } else if(inputTucapalma.checked){
        spanMascotaJugador.innerHTML = inputTucapalma.id
        mascotaJugador = inputTucapalma.id   
    } else {
        alert("Selecciona una mascota")
    }

https://andrescorreac.github.io/hunterXGame/

Subo mi aporte, queda mucho que me gustaria implementarle pero quiero seguir en el curso jejej

馃樆馃樆

Bueno as铆 va quedando mi videojuego, gracias a los profesores y ustedes chicos que mas de una vez me han ayudado a salir de dudas, os comparto la version movil.

Me demore un rato, pero al fin termine, igual tengo un problema el cual comentare al final.

array.splice(punto inicial, cantidad a eliminar)

primero con respecto a los ataque del enemigo use la funcion .splice(), la cual permite eliminar un valor en especifico del array y asi logre hacer que el mokepon enemigo logre seleccionar la cantidad de ataques que le toca

function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length -1)
    
    if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === '馃敟') {
        ataqueEnemigo.push('FUEGO')
    } else if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === '馃挧') {
        ataqueEnemigo.push('AGUA')
    } else {
        ataqueEnemigo.push('TIERRA')
    }
    ataquesMokeponEnemigo.splice(ataqueAleatorio,1)
    console.log(ataqueEnemigo)
    iniciarPelea()
}

Luego para lo que es la seleccion del tipo de mokepon, para validar el tipo, tuve que hacer algunas modificaciones dentro de las funciones, pero al final salio.
Ejemplos:
Mokepones iguales

Mokepon jugador con ventaja

Mokepon enemigo con ventaja

Ahora viene el problema, este es que no puedo deshabilitar el boton adicional despues de tirar los 5 ataques, he estado intentando, pero no se me ocurre nada, alguien tiene alguna idea de como hacerlo o algun profe? 馃槮

CODIGO COMPLETO

//Iniciar juego
const sectionSeleccionarAtaque = document.getElementById('seleccionar-ataque')
let sectionReiniciar = document.getElementById('reiniciar')
    sectionReiniciar.style.display = 'none'
const botonMascotaJugador = document.getElementById('boton-mascota')
const botonReiniciar = document.getElementById('boton-reiniciar')

//seleccionarMascotaJugador
const sectionSeleccionarMascota = document.getElementById('seleccionar-mascota')
const spanMascotaJugador = document.getElementById('mascota-jugador')

//selecionarMascotaEnemigo
const spanMascotaEnemigo = document.getElementById('mascota-enemigo')

//Combate
const spanVidasJugador = document.getElementById('vidas-jugador')
const spanVidasEnemigo = document.getElementById('vidas-enemigo')

//CrearMensaje
const sectionMensajes = document.getElementById('resultado')
const ataquesDelJugador = document.getElementById('ataques-del-jugador')
const ataquesDelEnemigo = document.getElementById('ataques-del-enemigo')

const contenedorTarjetas = document.getElementById('contenedorTarjetas')
const contenedorAtaques = document.getElementById('contenedorAtaques')

let mokepones = []
let ataqueJugador = []
let ataqueEnemigo = []
let opcionDeMokepones
let inputHipodoge
let inputCapipepo
let inputRatigueya
let inputPydos 
let inputTucapalma 
let inputLangostelvis 
let mascotaJugador
let ataquesMokepon
let ataquesMokeponEnemigo
let botonFuego 
let botonAgua 
let botonTierra
let tipoEnemigo
let tipoJugador
let botones = []
let indexAtaqueJugador 
let indexAtaqueEnemigo
let mascotaAleatoria
let VictoriasJugador = 0
let victoriasEnemigo = 0

//Clase para hacer clasificacion mokepones al juego
class Mokepon{
    constructor(nombre, foto, vida, tipo){
        this.nombre = nombre
        this.foto = foto
        this.vida = vida
        this.tipo = tipo
        this.ataques = [] //Variable para guardar ataques
    }
}

let hipodoge = new Mokepon('Hipodoge', './assets/mokepons_mokepon_hipodoge_attack.png', 5, '馃挧')

let capipepo = new Mokepon('Capipepo', './assets/mokepons_mokepon_capipepo_attack.png', 5, '馃尡')

let ratigueya = new Mokepon('Ratigueya', './assets/mokepons_mokepon_Ratigueya_attack.png', 5, '馃敟')

let langostelvis = new Mokepon('Langostelvis', './assets/mokepons_mokepon_langostelvis_attack.png', 5, '馃敟')

let pydos = new Mokepon('Pydos', './assets/mokepons_mokepon_Pydos_attack.png', 5, '馃挧')

let tucapalma = new Mokepon('Tucapalma', './assets/mokepons_mokepon_tucapalma_attack.png', 5, '馃尡')


hipodoge.ataques.push(
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃尡', id: 'boton-tierra'}
)

capipepo.ataques.push(
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃敟', id: 'boton-fuego'}
)

ratigueya.ataques.push(
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃尡', id: 'boton-tierra'}
)

tucapalma.ataques.push(
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃尡', id: 'boton-tierra'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃敟', id: 'boton-fuego'}
)   

pydos.ataques.push(
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃尡', id: 'boton-tierra'}
)

langostelvis.ataques.push(
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃敟', id: 'boton-fuego'},
    {nombre: '馃挧', id: 'boton-agua'},
    {nombre: '馃尡', id: 'boton-tierra'}
)

mokepones.push(hipodoge, capipepo, ratigueya, tucapalma, pydos, langostelvis)

function iniciarJuego() {
    sectionSeleccionarAtaque.style.display = 'none'

    //Creacion de tarjeta Mokepon en el html
    mokepones.forEach((mokepon) => {
        opcionDeMokepones = `
        <input type="radio" name="mascota" id=${mokepon.nombre} />
                <label class="tarjeta-de-mokepon" for=${mokepon.nombre}>
                    <p>${mokepon.nombre}</p>
                    <img src=${mokepon.foto} alt=${mokepon.nombre}>
                </label>
        `
        contenedorTarjetas.innerHTML += opcionDeMokepones

         inputHipodoge = document.getElementById('Hipodoge')
         inputCapipepo = document.getElementById('Capipepo')
         inputRatigueya = document.getElementById('Ratigueya')
         inputPydos = document.getElementById('Pydos')
         inputTucapalma = document.getElementById('Tucapalma')
         inputLangostelvis = document.getElementById('Langostelvis')
    })

    
    botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador)


    botonReiniciar.addEventListener('click', reiniciarJuego)
}

function seleccionarMascotaJugador() {

    sectionSeleccionarMascota.style.display = 'none'
    
    sectionSeleccionarAtaque.style.display = 'flex'
    
    
    if (inputHipodoge.checked) {
        spanMascotaJugador.innerHTML = inputHipodoge.id
        mascotaJugador = inputHipodoge.id
    } else if (inputCapipepo.checked) {
        spanMascotaJugador.innerHTML = inputCapipepo.id
        mascotaJugador = inputCapipepo.id
    } else if (inputRatigueya.checked) {
        spanMascotaJugador.innerHTML = inputRatigueya.id
        mascotaJugador = inputRatigueya.id
    }else if (inputLangostelvis.checked) {
        spanMascotaJugador.innerHTML = inputLangostelvis.id
        mascotaJugador = inputLangostelvis.id
    }else if (inputTucapalma.checked) {
        spanMascotaJugador.innerHTML = inputTucapalma.id
        mascotaJugador = inputTucapalma.id
    }else if (inputPydos.checked) {
        spanMascotaJugador.innerHTML = inputPydos.id
        mascotaJugador = inputPydos.id
    } else {
        alert('Selecciona una mascota')
    }
    mascotaAleatoria = aleatorio(0, mokepones.length-1)
    tipoEnemigo = mokepones[mascotaAleatoria].tipo
    
    extraerAtaques(mascotaJugador)
    seleccionarMascotaEnemigo()
    
}

function extraerTipo(){
    if(tipoJugador == '馃敟' && tipoEnemigo == '馃尡'){
        ataques.push(tipoJugador)
    } else if(tipoJugador == '馃挧' && tipoEnemigo == '馃敟'){
        ataques.push(tipoJugador)
    } else if(tipoJugador == '馃尡' && tipoEnemigo == '馃挧'){
        ataques.push(tipoJugador)
    }else if(tipoJugador==tipoEnemigo){
    }else{
        ataques.push(tipoEnemigo)
    }


}

function extraerAtaques(mascotaJugador){    
    let ataques
    for (let i = 0; i < mokepones.length; i++) {
        if (mascotaJugador === mokepones[i].nombre){
            
           
            tipoJugador = mokepones[i].tipo
            

            if(tipoJugador == '馃敟' && tipoEnemigo == '馃尡'){
                mokepones[i].ataques.push(mokepones[i].ataques[0])
            } else if(tipoJugador == '馃挧' && tipoEnemigo == '馃敟'){
                mokepones[i].ataques.push(mokepones[i].ataques[0])
            } else if(tipoJugador == '馃尡' && tipoEnemigo == '馃挧'){
                mokepones[i].ataques.push(mokepones[i].ataques[0])
            }else if(tipoJugador == tipoEnemigo){
                
            }else {
                mokepones[mascotaAleatoria].ataques.push(mokepones[mascotaAleatoria].ataques[0])

            }
             ataques = mokepones[i].ataques
        }
        
        
    }
    console.log(tipoJugador)
    console.log(ataques)
    mostrarAtaques(ataques)
}


function mostrarAtaques(ataques){
    ataques.forEach((ataque) => {
        ataquesMokepon = `
        <button id=${ataque.id} class="boton-de-ataque BAtaques">${ataque.nombre}</button>
        `
        contenedorAtaques.innerHTML +=  ataquesMokepon
    })
    botonFuego = document.getElementById('boton-fuego')
    botonAgua = document.getElementById('boton-agua')
    botonTierra = document.getElementById('boton-tierra')
    botones = document.querySelectorAll('.BAtaques')

}

function secuenciAtaque(){
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if(e.target.textContent === '馃敟'){
                ataqueJugador.push('FUEGO')
                console.log(ataqueJugador)
                boton.style.background = '#2B7A0B'
                boton.disabled = true
            } else if(e.target.textContent === '馃挧'){
                ataqueJugador.push('AGUA')
                console.log(ataqueJugador)
                boton.style.background = '#2B7A0B'
                boton.disabled = true
            } else {
                ataqueJugador.push('TIERRA')
                console.log(ataqueJugador)
                boton.style.background = '#2B7A0B'
                boton.disabled = true
            }
            ataqueAleatorioEnemigo()
        })
    })

}

function seleccionarMascotaEnemigo() {
    console.log(tipoEnemigo)
    spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatoria].nombre
    ataquesMokeponEnemigo = mokepones[mascotaAleatoria].ataques
    console.log(ataquesMokeponEnemigo)
    secuenciAtaque()
}



function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length -1)
    
    if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === '馃敟') {
        ataqueEnemigo.push('FUEGO')
    } else if (ataquesMokeponEnemigo[ataqueAleatorio].nombre === '馃挧') {
        ataqueEnemigo.push('AGUA')
    } else {
        ataqueEnemigo.push('TIERRA')
    }
    ataquesMokeponEnemigo.splice(ataqueAleatorio,1)
    console.log(ataqueEnemigo)
    iniciarPelea()
}

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

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

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")
            VictoriasJugador++
            spanVidasJugador.innerHTML = VictoriasJugador
        } else if(ataqueJugador[index] == 'AGUA' && ataqueEnemigo[index] == 'FUEGO') {
            indexAmbosOponentes(index,index)
            crearMensaje("GANASTE")
            VictoriasJugador++
            spanVidasJugador.innerHTML = VictoriasJugador
        } else if(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
        }
        
    }
    

    revisarVidas()
}

function revisarVidas() {
    if (victoriasEnemigo == VictoriasJugador) {
        crearMensajeFinal("EMPATE")
    } else if (VictoriasJugador > victoriasEnemigo) {
        crearMensajeFinal("FELICITACIONES! Ganaste :)")
    } else {
        crearMensajeFinal('Lo siento, perdiste :(')
    }
}

function crearMensaje(resultado) {
    
    let nuevoAtaqueDelJugador = document.createElement('p')
    let nuevoAtaqueDelEnemigo = document.createElement('p')
    botones.disabled = true
    sectionMensajes.innerHTML = resultado
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo

    ataquesDelJugador.appendChild(nuevoAtaqueDelJugador)
    ataquesDelEnemigo.appendChild(nuevoAtaqueDelEnemigo)
}

function crearMensajeFinal(resultadoFinal) {
    
    sectionMensajes.innerHTML = resultadoFinal

    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)

Mucho 谩nimo a quienes todav铆a siguen aqu铆, con cada clase vista y con cada reto superado nuestro poder crece exponencialmente

boton.style.cursor = 'not-allowed'

Esta propiedad puede ser 煤til para que el usuario note que ya no puede usar los botones de ataques que ya fueron usados una vez (de lo contrario solo se dar谩 cuenta que no pasa nada al hacer click, no es intuitivo), en caso de que a alguien pueda servirle.

Definitivamente mi profesor favorito, Diego supo hacer muy f谩cil lo que es m谩s complicado, a la velocidad perfecta, realmente queda como mi ejemplo a seguir en t茅rminos de optimizaci贸n y programaci贸n din谩mica, una l谩stima no poderlo ver m谩s adelante

En este m贸dulo aprend铆 el porqu茅 dicen que el programar es tener una tolerancia a la frustraci贸n, con todas las veces que se me rompi贸 el c贸digo y lo tuve que ver y rever para poder continuar clase por clase, pero al final se lleg贸 馃槃

Que satisfacci贸n llegar al fin de este modulo. dolio, mucho pero al final se siente una recompensa. Gracias al profesor

Esto es lo que decid铆i hacer como reto, los que son Miku y Arceus los agregu茅 como extras, dandole a ellos un ataque que obtienen cuando se enfrentan antes ciertos mokepons como ventaja, magia para Arceus, y Psiquico para Miku

Veo comentarios quej谩ndose de como el profe cambio la l贸gica del juego pero poco se habla de que es otra forma de hacer un juego.

As铆 vamos con nuevos personajes con doble tipo de ataque!
https://github.com/sariswis/Mokepon.git

Yo creo que agregar la propiedad de tipo no es necesario, ya que al elegir un tipo que es fuerte contra otro cont谩s con una ventaja:

3 de tus ataques son fuertes contra 3 de los ataques del rival!

Hola a todos, pensando en la opci贸n de 鈥淣ot repeat yourself鈥 cuando vamos a crear m谩s mokepones, tenemos una parte del c贸digo donde verificamos cada una de las opciones de mokepon y revisamos si es el que est谩 checkeado o no, para asi asignarlo a la variable mascotaJugador y hacer el innerHTML.

Buscando en la web encontr茅 que podemos usar este c贸digo

inputMascotaSeleccionada = document.querySelector('input[type="radio"]:checked').id

Esto con el fin de buscar en todos los input de type 鈥渞adio鈥 para saber cual es el que est谩 seleccionado.
Luego hice un for para compararlo con los mokepones que tenemos y asi asignar el mokepon asignado

Este ser铆a el for:

for (let im = 0; im < mokepones.length; im++) {
        if (inputMascotaSeleccionada == mokepones[im].nombre) {
            spanMascotaJugador.innerHTML = inputMascotaSeleccionada
            mascotaJugador = mokepones[im]
        }
    }

Yo detect茅 desde el principio que los empates no se dan puntos a favor ni en contra, o pueden ser para nadie o para los dos.

Agregu茅 esto y me funcion贸, pero igual esta mejor quitarlo:

function combate() {
    for (let index = 0; index < ataqueJugador.length; index++) {
        if(ataqueJugador[index] === ataqueEnemigo[index]) {
            indexAmbosOponentes(index, index)
            crearMensaje('Empate');
            victoriasJugador++;
            victoriasEnemigo++;
            spanVidasEnemigo.innerHTML = victoriasJugador;

te quiero mucho Pedro Pascal me ha encantado esta clase 鉂わ笍

POR FIN LOGRADO鈥 SUBIRIA IMAGENES PERO NO ME DEJA ASI QUE DEJO EL DEPLOY鈥
never stop learning!!

https://bartydev.github.io/mokeponNewGame.github.io/


Asi lo llevo, Zapato el mejor personaje 馃槑

Hola necesito ayuda con mi c贸digo, no encuentro el error

<code> 
const sectionSeleccionarAtaque = document.getElementById("seleccionar-ataque")
const sectionReiniciar = document.getElementById("reiniciar")
const BotonMascotaJugador = document.getElementById('Boton-Mascota')
const botonReiniciar = document.getElementById("boton-reiniciar") 
sectionReiniciar.style.display = "none"
const sectionSeleccionarMascota = document.getElementById("seleccionar-mascota")
const spanMascotaJugador = document.getElementById("mascota-jugador")
const spanMascotaEnemigo = document.getElementById("mascota-enemigo")
const spanVidasJugador = document.getElementById ( "vidas-jugador")
const spanVidasEnemigo = document.getElementById ( "vidas-enemigo")
const sectionMensajes = document.getElementById("resultado")
const ataquesDelJugador = document.getElementById("ataques-del-jugador")
const ataquesDelEnemigo = document.getElementById("ataques-del-enemigo")
const contenedorTarjetas = document.getElementById("contenedorTarjetas")
const contenedorAtaques = document.getElementById("contenedorAtaques")
let dogfights = []
let ataqueJugador = []
let ataqueEnemigo = []
let opcionDeDogfights
let inputBombon 
let inputJack 
let inputYamiro  
let mascotaJugador
let ataquesDogfight
let ataquesDogfightEnemigo
let botonFuego 
let botonAgua
let botonTierra 
let botones = []
let indexAtaqueJugador
let indexAtaqueEnemigo
let victoriasJugador = 0
let victoriasEnemigo = 0
let vidasJugador = 3
let vidasEnemigo = 3 
class dogfight {
    constructor(nombre, foto, vida) {
        this.nombre = nombre
        this.foto = foto
        this.vida = vida
        this.ataques = []
    }
}
// tengo que agregar las fotos//
let bombon = new dogfight('Bombon', '', 5)

let jack = new dogfight('Jack', ' ', 5)

let yamiro = new dogfight('Yamiro', ' ', 5)

bombon.ataques.push(
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃尡', id: 'boton-tierra' },
)

jack.ataques.push(
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃敟', id: 'boton-fuego' },
    
)

yamiro.ataques.push(
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃敟', id: 'boton-fuego' }, 
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃尡', id: 'boton-tierra' },
)

dogfights.push(bombon,jack,yamiro)
 
function iniciarJuego() {
    
    sectionSeleccionarAtaque.style.display = 'none'

    dogfights.forEach((dogfight) => {
        opcionDeDogfights = `
        <input type="radio" name="mascota" id=${dogfight.nombre} />
        <label class="tarjeta-de-dogfight" for=${dogfight.nombre}>
            <p>${dogfight.nombre}</p>
            <img src=${dogfight.foto} alt=${dogfight.nombre}>
        </label>
        `
    contenedorTarjetas.innerHTML +=opcionDeDogfights

     inputBombon= document.getElementById("Bombon")
     inputJack= document.getElementById("Jack")
    inputYamiro= document.getElementById("Yamiro")

    })
    BotonMascotaJugador.addEventListener('click',seleccionarMascotaJugador)  

    botonReiniciar.addEventListener("click", reiniciarJuego)
   }
function seleccionarMascotaJugador() {
   
    sectionSeleccionarMascota.style.display = "none"

   
    sectionSeleccionarAtaque.style.display = "flex"

    

   if (inputBombon.checked) {   
    spanMascotaJugador.innerHTML = inputBombon.id
    mascotaJugador = inputBombon.id
   } else if (inputJack.checked) {
    spanMascotaJugador.innerHTML = inputJack.id
    mascotaJugador = inputJack.id
   }else if (inputYamiro.checked){
    spanMascotaJugador.innerHTML = inputYamiro.id  
    mascotaJugador = inputYamiro.id
    } else {
        alert('Selecciona una mascota')
    }

    extraerAtaques(mascotaJugador)
    seleccionarMascotaEnemigo()
}
function extraerAtaques(mascotaJugador) {
    let ataques
    for (let i = 0; i < dogfights.length; i++) {
        if (mascotaJugador === dogfights [i].nombre) {
            ataques = dogfights[i].ataques
        }
        
    }
    mostrarAtaques(ataques)
}
function mostrarAtaques(ataques){
    ataques.forEach((ataque) => {
        ataquesDogfight = `
        <button id=${ataque.id} class="boton-de-ataque BAataque">${ataque.nombre}</button>
        `
        contenedorAtaques.innerHTML += ataquesDogfight
    })
     botonFuego = document.getElementById("Boton-Fuego")
     botonAgua = document.getElementById("Boton-Agua")
     botonTierra = document.getElementById("Boton-Tierra")
    botones = document.querySelectorAll (".BAataque")
function secuenciaAtaque () {
    botones.forEach((boton) => {
        boton.addEventListener("click", (e) => {
           if (e.target.textContent === "馃敟") {
            ataqueJugador.push("FUEGO")
            console.log(ataqueJugador)
                boton.style.background = "#112f58"
                boton.disabled = true
           } else if (e.target.textContent ==="馃挧" ){
            ataqueJugador.push("AGUA")
            console.log(ataqueJugador)
            boton.style.background = "#112f58"
            boton.disabled = true
           } else {
            ataqueJugador.push("TIERRA")
            console.log(ataqueJugador)
           boton.style.background = "#112f58"
           boton.disabled = true
           }
           ataqueAleatorioEnemigo()
       })        
    })
}
function seleccionarMascotaEnemigo() {
    let mascotaAleatorio = aleatorio(0, dogfights.length -1)
    spanMascotaEnemigo.innerHTML = dogfights [mascotaAleatorio].nombre
    ataquesDogfightEnemigo = dogfights [mascotaAleatorio].ataques
    secuenciaAtaque ()

} 
function ataqueAleatorioEnemigo (){
    let ataqueAleatorio = aleatorio(0,ataquesDogfightEnemigo.lenght -1)

    if (ataqueAleatorio == 0 || ataqueAleatorio == 1){
        ataqueEnemigo.push ("Fuego")
    } else if (ataqueAleatorio == 3 || ataqueAleatorio== 4) {
        ataqueEnemigo.push ("Agua")
    } else {
        ataqueEnemigo.push ("Tierra")
    }
    console.log(ataqueEnemigo)
    iniciarPelea()    
} 

function iniciarPelea () {
    if (ataqueJugador.length === 5) {
        combate() 
    }
}
function indexAmbosOponentes(jugador,enemigo) {
    indexAtaqueJugador = ataqueJugador[jugador]
    indexAtaqueEnemigo = ataqueEnemigo [enemigo]
}

function combate (){
    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");
                victoriasJugador++;
                spanVidasJugador.innerHTML = victoriasJugador;
            } else if (ataqueJugador[index] ==='AGUA' && ataqueEnemigo[index] === 'FUEGO') {
                indexAmbosOponentes(index, index);
                crearMensaje("GANASTE");
                victoriasJugador++;
                spanVidasJugador.innerHTML = victoriasJugador;
            } else if (ataqueJugador[index] === 'TIERRA' && ataqueEnemigo[index] === 'AGUA') {
                indexAmbosOponente(index, index);
                crearMensaje("GANASTE");
                victoriasJugador++;
                spanVidasJugador.innerHTML = victoriasJugador;
            } else {
                indexAmbosOponentes(index, index);
                crearMensaje("PERDISTE");
                victoriasEnemigo++;
                spanVidasEnemigo.innerHTML = victoriasEnemigo;
            }
        }
        revisarVidas();
    }
   
      revisarVidas()
}
function revisarVidas() {
 if (victoriasJugador === victoriasEnemigo ) {
    crearMensajeFinal("Esto fue un empate")
 } else if (
    victoriasJugador> victoriasEnemigo
 ) {
    crearMensajeFinal("FELICITACIONES! Ganaste 馃帀馃榿")
 } else {
    crearMensajeFinal ("Lo siento, perdiste 馃槩 ")
 }
}
function crearMensaje(resultado) {
    let nuevoAtaqueDelJugador = document.createElement("p")
    let nuevoAtaqueDelEnemigo = document.createElement("p")

    sectionMensajes.innerHTML=resultado
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo
  
    ataquesDelJugador.appendChild(nuevoAtaqueDelJugador)
    ataquesDelEnemigo.appendChild(nuevoAtaqueDelEnemigo)
}
function crearMensajeFinal(resultadoFinal) {
    sectionMensajes.innerHTML = resultadoFinal
    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)
}

reto 1 solucionado pero no me demore mucho, le pregunte a GPT y compare con comentarios a ver que tenian, hay muchos incompletos. Pero se logro este reto con dos nuevos ataques.
Pero para el reto 2 del tipo y agregar un nuevo ataque y quede funcional, ni modos. Porque si quedo pero no funcional. El reto estaba interesante ojala hubieran dado la soluci贸n.

As铆 va el proyecto!


Agregue las nuevas mascotas continuando con la l贸gica de programaci贸n de la class Mokepon, colocando la nueva caracter铆stica del tipo.

Utilice splice para los ataques aleatorios del enemigo y el condicional if para otorgar un punto de victoria al tipo de mokepon m谩s fuerte entre jugador y pc

Finalmente Ya esta completo el Reto:

Fue Tardado pero lo hize jeje

No he puesto nada a lo largo del curso pero aqui dejo mi huella de como va mi proyecto a este punto.

  1. Logr茅 completar ambos retos, a帽adi el ataque extra (El que se tiene fondo dorado) cuando el elemento de tu mascota es superior al del oponente (O lo mismo en viceversa)
  1. Ademas de que resolvi el problema de no tomar en cuenta los ataques de la mascota del enemigo investigando metodos de array y ocupando 鈥淪plice鈥.

Aprovecho para mencionar que hasta este punto todos los profesores han hecho un excelente trabajo en explicar las cosas muy bien y todos han sido muy carismaticos y agradables鉂わ笍



2do Reto cumplido

Agrego un guerrero mas me da miedo da帽ar todo lo que llevo Jajaja鈥

Cumpl铆 ambos retos y un poco mas

  • Extra:
    Como habia que poner nuevos mokepones a la hora de poner las comprobaciones de los inputs vi que era muy repetitivo y extenso asi que opte por lo siguiente:
inputsMokepones.push(
        [inputCapipepo, capipepo], 
        [inputHipodoge, hipodoge], 
        [inputRatigueya, ratigueya], 
        [inputPydos, pydos], 
        [inputTucapalma, tucapalma], 
        [inputLangostelvis, langostelvis]
 );

function comprobarInputChecked() 
{
    for (let index = 0; index < inputsMokepones.length; index++) 
    {
        const inputEscogido = inputsMokepones[index]
        if (inputEscogido[0].checked == true)
        {
            spanMascotaJugador.innerHTML = inputEscogido[0].id;
            mokeponJugador = inputEscogido[1];
            return true;
        }
    }
}

function seleccionarMascotaJugador() 
{
    let escogioMokepon = comprobarInputChecked();

    if (escogioMokepon == true){
        seleccionarMascotaEnemigo();
    } else {
        alert("Escoge un Mokepon");
    }
}

Lo que hice fue guardar la referencia tanto del input como de su mokepon correspondiente, a partir de ahi hice una funcion que compruebe que input esta 鈥渃hecked鈥 y segun eso poner al mokepon escogido tanto en el html como para el codigo en adelante ahorrandome el tener que hacer un nuevo if cada vez que meto un nuevo mokepon al juego

  • Reto1: No sacarse ataques de la manga
    Eso lo resolvi con el siguiente codigo algo largo:
function ataqueAleatorioEnemigo() {

    let ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo .length - 1);
    let ataquePosible;
    console.log(ataqueAleatorio)
    
    if (ataquesEnemigoEscogido.length == 0)
    {
        ataquesEnemigoEscogido = ataquesMokeponEnemigo;
    }
    
    ataquePosible = ataquesMokeponEnemigo[ataqueAleatorio];

    for (let index = 0; index < ataqueEnemigo.length; index = index) {
        if (ataquesEnemigoEscogido[ataqueAleatorio] == "NaN")
        {
            ataqueAleatorio = aleatorio(0, ataquesMokeponEnemigo .length - 1);
            ataquePosible = ataquesMokeponEnemigo[ataqueAleatorio];
            console.log("ReRoll")
        } else {
            console.log("Despues de evaluar se ha escogido el ataque: "+ index + ataquePosible.nombre);
            console.log(ataquesEnemigoEscogido[ataqueAleatorio])
            index++;
        }
        
    }
    if (ataquePosible.nombre == "馃敟")
    {
        ataqueEnemigo.push("FUEGO");
        ataquesEnemigoEscogido[ataqueAleatorio] = "NaN";
    } else if (ataquePosible.nombre == "馃挧") {
        ataqueEnemigo.push("AGUA");
        ataquesEnemigoEscogido[ataqueAleatorio] = "NaN";
    } else {
        ataqueEnemigo.push("TIERRA");
        ataquesEnemigoEscogido[ataqueAleatorio] = "NaN";
    }
    console.log(ataqueEnemigo);
    console.log(ataquesEnemigoEscogido);
    iniciarCombate()
}

Comprueba que ataque escogio la maquina si es uno nuevo lo descarta con el NaN y el for comprueba que si ya fue escogido ese ataque vuelva a escoger otro hasta que sea uno nuevo

  • Reto2: Agregar mas mokepones y la mecanica de los tipos:
    Pues agregar los mokepones nuevos fue 鈥渟encillo鈥 y lo de los tipos lo hice con la siguientes funciones:
function ventajaPorTipo() {
    const tipoJugador = mokeponJugador.tipo;
    const tipoEnemigo = mokeponEnemigo.tipo;

    if ((tipoJugador == "馃敟" && tipoEnemigo == "馃尡") || (tipoJugador == "馃挧" && tipoEnemigo == "馃敟") || (tipoJugador == "馃尡" && tipoEnemigo == "馃挧")){
        ventajaJugadorTipo = true;

        const ataquesJugador = mokeponJugador.ataques;
        const ataquesEnemigo = mokeponEnemigo.ataques;

        mokeponJugador.ataques.push({ nombre: ataquesJugador[0].nombre, id: ataquesJugador[0].id})
        mokeponEnemigo.ataques.push({ nombre: ataquesEnemigo[0].nombre, id: ataquesEnemigo[0].id})

        console.log(mokeponJugador.ataques);
        console.log(mokeponEnemigo.ataques);
    }
    mostrarAtaques();
}

function iniciarCombate()
{
    if (ataqueJugador.length == 5 && ventajaJugadorTipo == false)
    {
        combate()
    } else if (ataqueJugador.length == 6 && ventajaJugadorTipo == true) {
        combate()
    }
}

La puse justo despues de que se escoja el mokepon del jugador y del enemigo y solo comprueba si el jugador tiene un mokepon con tipo dominante si es haci agrega tanto al jugador como al enemigo un ataque que sea de su tipo y en la otra funcion comprueba si hay ventaja de tipo para que sepa cuantos turnos debe contar

Asi va mi proyecto ; )

Mi humilde proyecto

Esta parte del curso con Diego, sufri pero tambien aprendi bastante, vi que varios se quejaron, pero la realidad es que asi es como trabaja un dev en su dia a dia, haciendo muchos cambios a un proyecto鈥

Creo que en este curso falt贸 un poquito de game design / gesti贸n / producci贸n / planificaci贸n para el juego al menos hasta donde estoy viendo. Igualmente un 茅xito y gracias por compartir sus conocimientos.

Es interesante el complemento de los elementos de funcionamiento del juego. Sabia algunas partes, pero no esta mal complementar algunas mejoras y hacer robusta la pagina

Mi versi贸n del juego:
[](
[](

Oportunidades en el juego mejorar el juego con el recurso aprendido: completar el ataque aleatorio, adicionar mascotas yadicionar un ataque a la mascota mas fuerte
2. Adicionar mascotas

1.Funcion AtaqueAleatorioEnemigo, agrupe por mascota
function ataqueAleatorioEnemigo(){
let ataqueAleatorio=aleatorio(0,ataquesMokeponEnemigo.length-1)
if (mascotaAleatorio === 0){
if ((ataqueAleatorio >= 0) && (ataqueAleatorio 鉂わ笍)){
ataqueEnemigo.push(鈥楢GUA鈥)
}else if(ataqueAleatorio == 3) {
ataqueEnemigo.push(鈥楩UEGO鈥)
}else {
ataqueEnemigo.push(鈥楾IERRA鈥)
}
}else mascota 1{ la logica anterior cambia el tipo de ataque
}else mascota 2{ la logica anterior cambia el tipo de ataque
}else mascota 3{ la logica anterior cambia el tipo de ataque
} 鈥
iniciarPelea()
}//fin ataque enemigo

  1. de momento si de antemano se conoce cual es la mascota que es mas fuerte, agregarle el ataque adicional y en vez de 5 tendr铆a 6. la situaci贸n es que para el usuario ya estar铆a por entendido y seleccionar铆a la fuerte, el azar (que le salga o no la mascota fuerte) solo lo tendr铆a el enemigo.

Definitivamente de inicio a fin fue muy emocionante todo el aprendizaje. Sin embargo confieso que el aumento de la dificultal hace que en algunos casos el nivel de frustacion aumente cuando no logras entender la logica.

Sin mas, se logro solucionar el reto y se continua con el aprendizaje.

Gran esfuerzo de los docentes de Platzi en armar este curso. Puede parecer algo complicado y confuso, pero no deja de ser programaci贸n b谩sica.
脡xitos en las clases que vienen, contin煤en esforz谩ndose por aprender a programar.

No me gust贸 el dise帽o del juego con el que se ha estado trabajando en el curso hasta este punto, me pareci贸 aburrido que el juego fuera tan simple as铆 que hice mi propia versi贸n llamada Plagiomon, le agregu茅 m谩s mec谩nicas de combate y a帽ad铆 varios personajes con movimientos diferentes, habilidades especiales y as铆 me ha quedado hasta ahora. Quer铆a agregar m谩s cosas como items y la habilidad para jugar con varios Plagiomon al mismo tiempo, mejor conocido como batallas dobles pero la cabeza solo me dio para hacerlos 1 vs 1, estuve como 2 semanas haci茅ndolo me dicen qu茅 tal les parece pueden probar el juego aqu铆. https://leodexe.github.io/jsmokepon/index.html

Despu茅s de unas cuantas revisiones, logre mejorar la parte de ataque aleatorio del enemigo.
Primero, declare randomPet por fura de la funci贸n para poder usar su valor en la funci贸n de ataques del enemigo.
Esto lo hice debido a que, anteriormente, el PC ya hab铆a elegido sus ataques antes de que lo hiciera el jugador.



Luego guarde el arreglo de los ataques seg煤n la mascota elegida por el PC en la variable pcAttacks para poder ejecutar la selecci贸n aleatoria de ataques.



Primero compar茅 el ataque random con el nombre del ataque. Si coinciden, entonces agrego ese ataque a la variable **pcAttack **que m谩s adelante me permite mostrar los ataques que eligi贸 el PC.
Luego, elimin茅 ese ataque del arreglo pcAttacks para limitar las opciones del PC y que solo pueda elegir los ataques correspondientes a su mascota.

Asi me quedo.!

Esta parte con Diego ha sido una locura, el salto que se ha dado me ha costado, pero llegue! 馃槃

Por ahora mi 煤nico problema es que no logro que el enemigo no repita ataques que no pueda repetir.

De momento quedo as铆 馃槃

Agregue las im谩genes de los Mokepones que iban a combatir, tambien pude hacer responsiva la parte del duelo

Hice mis propios mokepones y mi hija los nombro

驴Alguien me puede ayudar por favor?

Funci贸n ataque enemigo que tiene encuenta los ataques de cada mokepon y los elige de manera aleatoria.

function ataqueAleatorioEnemigo(){
    
    let condicion = 0

    while (condicion == 0) {
        let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length-1)
        if(ataqueAleatorio == 0 || ataqueAleatorio == 1 || ataqueAleatorio == 2 && ataqueEnemigo1 > 0){
            ataqueEnemigo.push(ataquesMokeponEnemigo[ataqueAleatorio].nombre)
            ataqueEnemigo1--
            condicion++
        }else if(ataqueAleatorio == 3 && ataqueEnemigo2 > 0){
            ataqueEnemigo.push(ataquesMokeponEnemigo[ataqueAleatorio].nombre)
            ataqueEnemigo2--
            condicion++
        }else if(ataqueAleatorio == 4  && ataqueEnemigo3 > 0){
            ataqueEnemigo.push(ataquesMokeponEnemigo[ataqueAleatorio].nombre)
            ataqueEnemigo3--
            condicion++
        }
    }
    console.log(ataqueEnemigo)
    iniciarPelea()

}

Pude agregar los otros tres personajes.

Mejore la l贸gica con la que los ataques del enemigo son elegidos (gracias al m茅todo splice)

Agregue la mec谩nica que permite que cuando haya desventaja de tipo le de al jugador un ataque adicional para que pueda ganarle al contrincante

En esta clase me he sentido muy bien, porque todo lo que el profesor aplico a la mejora, lo fui realizando mientras iba desarrollando el c贸digo!

Asi me quedo

As铆 quedo mi juego con todo lo que trabajamos.
Mokepon

Espero en el futuro dejar un enlace con algunas mejoras que no he hecho, pero por ahora as铆 quedo.

Asi quedo el mio.

tambien les comparto mi codigo.

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>MOKEPON</title>
        <style></style>
        <link rel="stylesheet" href="./styles.css">
    </head>
    <body>
        <section id="seleccionar-mascota">
            <h1 class="titulo">Mokepon</h1>
            <h2 class="subtitulo">Elige a tu mascota</h2>
            <div id="contenedor-tarjetas" class="tarjetas"></div>
            <button id="boton-mascota">Seleccionar</button>
        </section>
        <section id="seleccionar-ataque">
            <h1 class="titulo">Mokepon</h1>
            <h2>Elige tu ataque</h2>
            <div id="contenedor-ataques" class="poderes"></div>
            <h2>Marcador</h2>
            <div id="marcador">
                    <h4 id="victorias">Victorias: 0</h4>
                    <h4 id="derrotas">Derrotas: 0</h4>
                    <h4 id="empates">Empates: 0</h4>
            </div>
            <div id="mensajes">
                <p id="resultado">Muchos exitos!!</p>
                <section id="reiniciar">
                    <button id="boton-reiniciar">Reiniciar</button>
                </section>
            </div>
            <div class="ataques">
                <div class="ataques-jugador">
                    <div class="vidas-jugador">
                        <h3>Jugador</h3>
                        <span id="mascota-jugador"></span>
                        <p><span id="vidas-jugador">鉂わ笍鉂わ笍鉂わ笍</span></p>
                    </div>
                    <div id="ataques-del-jugador"></div>
                </div>
                <div class="ataques-enemigo">
                    <div class="vidas-enemigo">
                        <h3>Enemigo</h3>
                        <span id="mascota-enemigo"></span>
                        <p><span id="vidas-enemigo">鉂わ笍鉂わ笍鉂わ笍</span></p>
                    </div>
                    <div id="ataques-del-enemigo"></div>
                </div>
            </div>
        </section>
        <script src="./js/script.js"></script>
    </body>
</html>
@import url('https://fonts.googleapis.com/css2?family=Fredoka&family=Poppins:wght@300&display=swap');

body {
    font-family: 'Poppins', sans-serif;
    background-color: #041562;
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

#seleccionar-mascota {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
}

.titulo {
    color: #EEEEEE;
    font-size: 60px;
    font-family: 'Fredoka', cursive;
}

.subtitulo {
    color: #EEEEEE;
    font-size: 20px;
}

.tarjetas, .poderes {
    display: flex;
    gap: 10px;
}

.tarjeta-de-mokepon {
    color: #EEEEEE;
    width: 180px;
    height: 100px;
    background-color: #11468F;
    padding: 10px;
    box-sizing: border-box;
    border-radius: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-family: 'Poppins', sans-serif;
}

.tarjeta-de-mokepon:hover {
    cursor: pointer;
    background-color: #5D8BF4;
}

.tarjeta-de-mokepon:active {
    background-color: #041562;
}
.tarjeta-de-mokepon img {
    width: 80px;
}

input {
    display: none;
}
input:checked + label{
    background-color: #5D8BF4;
    border: 1px solid #EEEEEE;
}

#boton-mascota {
    width: 180px;
    height: 40px;
    border-radius: 20px;
    background: transparent;
    border: 2px solid #EEEEEE;
    color: #EEEEEE;
    font-family: 'Poppins', sans-serif;
    margin-top: 30px;
}

#boton-mascota:hover {
    cursor: pointer;
    background-color: #0d63db;
    transform: scale(1.05);
}

#seleccionar-ataque {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
}

#seleccionar-ataque h2 {
    color: #EEEEEE;
}
/* #contenedor-ataques {
    display: flex;
    width: 300px;
} */
.boton-ataque {
    background-color: #11468F;
    padding: 10px;
    border-radius: 20px;
    border-color: transparent;
    width: 80px;
    color: #EEEEEE;
    font-family: 'Poppins', sans-serif;
}

.boton-ataque:hover {
    cursor: pointer;
    background-color: #0d63db;
}

.boton-ataque:active {
    background-color: #041562;
}

.vidas {
    display: flex;
    align-items: center;
    width: 530px;
    justify-content: space-between;
}

.vidas div {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 260px;
    background: rgba(192, 227, 255, 0.233);
    box-sizing: border-box;
    border-radius: 20px;
    gap: 10px;
    margin-top: 20px;
}

.vidas-jugador, .vidas-enemigo {
    display: flex;
    flex-direction: column;
    align-items: center;
}

#mensajes {
    width: 350px;
    padding: 20px;
    background: rgba(192, 227, 255, 0.233);
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 20px;
    box-sizing: border-box;
    border-radius: 20px;
    text-align: center;
}

#resultado {
    font-size: 15px;
    color: #EEEEEE;
}

#boton-reiniciar {
    width: 180px;
    height: 40px;
    border-radius: 20px;
    background: #11468F;
    border: none;
    color: #EEEEEE;
    font-family: 'Poppins', sans-serif;
    margin-top: 30px;
}

#boton-reiniciar:hover {
    cursor: pointer;
    background-color: #0d63db;
    transform: scale(1.05);
}
#marcador {
    display: flex;
    justify-content: space-evenly;
    background-color: #11468f42;
    padding: 10px;
    box-sizing: border-box;
    border-radius: 20px;
    color: #EEEEEE;
    font-family: 'Poppins', sans-serif;
    width: 350px;
}

.ataques {
    display: flex;
    grid-template-columns: 250px 250px;
    justify-items: center;
    color: #EEEEEE;
}

.ataques-jugador, .ataques-enemigo {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: rgba(192, 227, 255, 0.233);
    box-sizing: border-box;
    border-radius: 20px;
    margin: 20px;
}

.vidas-jugador, .vidas-enemigo {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 200px;
    height: 150px;
}

#ataques-del-jugador, #ataques-del-enemigo {
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-bottom: 40px;
}
#ataques-del-jugador p, #ataques-del-enemigo p {
    text-align: center;
    border: #EEEEEE solid 1px;
    box-sizing: border-box;
    border-radius: 20px;
    width: 120px;
    background-color: #041562;
}


@media (max-width: 650px) {
    body {
        font-size: 15px;
    }
    .tarjetas, .poderes {
        display: flex;
        flex-direction: column;
    }
    .ataques-jugador, .ataques-enemigo {
        width: 140px;
    }
    #ataques-del-jugador, #ataques-del-enemigo {
        width: 100px;
    }


}
// const = crear una variable fija
const sectionSeleccionarAtaque = document.getElementById('seleccionar-ataque')
const sectionSeleccionarMascota = document.getElementById('seleccionar-mascota')
const sectionReiniciar = document.getElementById('reiniciar')
const botonMascotaJugador = document.getElementById('boton-mascota')
const botonReiniciar = document.getElementById('boton-reiniciar')

const spanMascotaJugador = document.getElementById('mascota-jugador')
const spanMascotaEnemigo = document.getElementById('mascota-enemigo')

const spanVidasJugador = document.getElementById('vidas-jugador')
const spanVidasEnemigo = document.getElementById('vidas-enemigo')

const victoriasElement = document.getElementById('victorias')
const derrotasElement = document.getElementById('derrotas')
const empatesElement = document.getElementById('empates')

const sectionMensajes = document.getElementById('resultado')

const ataquesDelJugador = document.getElementById('ataques-del-jugador')
const ataquesDelEnemigo = document.getElementById('ataques-del-enemigo')

const contenedorTarjetas = document.getElementById('contenedor-tarjetas')
const contenedorAtaques = document.getElementById('contenedor-ataques')

// let = crear una variable cambiante
let mokepones = []

let opcionDeMokepones

let inputHipodoge
let inputCapipepo
let inputRatigueya

let mascotaDelJugador
let ataquesMokepon
let ataquesMokeponEnemigo

let ataqueJugador = []
let ataqueEnemigo = []

let botonAgua
let botonTierra
let botonFuego

let botones = []

let indexAtaqueJugador
let indexAtaqueEnemigo

let vidasJugador = 3
let vidasEnemigo = 3

let victoriasJugador = 0
let victoriasEnemigo = 0

let victorias = 0
let derrotas = 0
let empates = 0

class Mokepon {
    constructor(nombre, foto, vida) {
        this.nombre = nombre
        this.foto = foto
        this.vida = vida
        this.ataques = []
    }
}

let hipodoge = new Mokepon('Hipodoge', './assets/mokepons_mokepon_hipodoge_attack.png', 5)
let capipepo = new Mokepon('Capipepo', './assets/mokepons_mokepon_capipepo_attack.png', 5)
let ratigueya = new Mokepon('Ratigueya', './assets/mokepons_mokepon_ratigueya_attack.png', 5)

hipodoge.ataques.push(
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃敟', id: 'boton-fuego' }
)
capipepo.ataques.push(
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃尡', id: 'boton-tierra' },
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃挧', id: 'boton-agua' }
)
ratigueya.ataques.push(
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃敟', id: 'boton-fuego' },
    { nombre: '馃挧', id: 'boton-agua' },
    { nombre: '馃尡', id: 'boton-tierra' }
)
mokepones.push(hipodoge, capipepo, ratigueya)
//function = crear una funci贸n
function iniciarJuego() {
    sectionSeleccionarAtaque.style.display = 'none'

    mokepones.forEach((mokepon) => {
        opcionDeMokepones = `
            <input id=${mokepon.nombre} type="radio" name="mascota">
            <label class="tarjeta-de-mokepon" for=${mokepon.nombre}>
                <p>${mokepon.nombre}</p>
                <img src=${mokepon.foto} alt=${mokepon.nombre}>
            </label>
        `
        // innerHTML = nos ayuda a cambiar su contenido
        contenedorTarjetas.innerHTML += opcionDeMokepones

        inputHipodoge = document.getElementById('Hipodoge')
        inputCapipepo = document.getElementById('Capipepo')
        inputRatigueya = document.getElementById('Ratigueya')
    })

    sectionReiniciar.style.display = 'none'

    // addEventListener = crear un evento
    botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador)
    botonReiniciar.addEventListener('click', reiniciarJuego)
}
function seleccionarMascotaJugador() {
    sectionSeleccionarMascota.style.display = 'none'
    sectionSeleccionarAtaque.style.display = 'flex'

    if (inputHipodoge.checked) {
        spanMascotaJugador.innerHTML = inputHipodoge.id
        mascotaDelJugador = inputHipodoge.id
    }else if (inputCapipepo.checked) {
        spanMascotaJugador.innerHTML = inputCapipepo.id
        mascotaDelJugador = inputCapipepo.id
    }else if (inputRatigueya.checked) {
        spanMascotaJugador.innerHTML = inputRatigueya.id
        mascotaDelJugador = inputRatigueya.id
    }else {
        alert("No has elegido una mascota")
        location.reload()
    }
    extraerAtaques(mascotaDelJugador)
    seleccionarMascotaEnemigo()
}
function extraerAtaques(mascotaDelJugador) {
    let ataques

    for (let i = 0; i < mokepones.length; i++) {
        if (mascotaDelJugador === mokepones[i].nombre) {
            ataques = mokepones[i].ataques
        }

    }
    mostrarAtaques(ataques)
}
function mostrarAtaques(ataques) {
    ataques.forEach((ataque) => {
        ataquesMokepon = `
        <button id=${ataque.id} class="boton-ataque BAtaque">${ataque.nombre}</button>
        `
        contenedorAtaques.innerHTML += ataquesMokepon
    })

    botonAgua = document.getElementById('boton-agua')
    botonTierra = document.getElementById('boton-tierra')
    botonFuego = document.getElementById('boton-fuego')
    botones = document.querySelectorAll('.BAtaque')
}
function seleccionarMascotaEnemigo() {
    let mascotaAleatoria = aleatorio(0, mokepones.length -1)

    spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatoria].nombre
    ataquesMokeponEnemigo = mokepones[mascotaAleatoria].ataques
    secuenciaAtaque()
}
function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if (e.target.textContent === '馃敟') {
                ataqueJugador.push('馃敟')
                boton.style.background = '#112f58'
                boton.disabled = true
            } else if (e.target.textContent === '馃挧') {
                ataqueJugador.push('馃挧')
                boton.style.background = '#112f58'
                boton.disabled = true
            } else {
                ataqueJugador.push('馃尡')
                boton.style.background = '#112f58'
                boton.disabled = true
            }
            ataqueAleatorioEnemigo()
        })
    })
}
function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(0,ataquesMokeponEnemigo.length -1)

    if (ataqueAleatorio == 0 || ataqueAleatorio == 1) {
        ataqueEnemigo.push('馃敟')
    }else if (ataqueAleatorio == 3 || ataqueAleatorio == 4) {
        ataqueEnemigo.push('馃挧')
    }else {
        ataqueEnemigo.push('馃尡')
    }
    console.log(ataqueEnemigo)
    iniciarCombate()
}
function iniciarCombate() {
    if (ataqueJugador.length === 5) {
        combate()
    }
}
function indexAmbosOponentes(jugador, enemigo) {
    indexAtaqueJugador = ataqueJugador[jugador]
    indexAtaqueEnemigo = ataqueEnemigo[enemigo]
}
function combate() {
    for (let index = 0; index < ataqueJugador.length; index++) {
        if (ataqueJugador[index] === ataqueEnemigo[index]) {
            indexAmbosOponentes(index, index)
            crearMensaje(" EMPATE 馃ぜ鈥嶁檪锔")
            spanVidasJugador.innerHTML = victoriasJugador
            spanVidasEnemigo.innerHTML = victoriasEnemigo
            empates = empates + 1
        } else if (ataqueJugador[index] === '馃挧' && ataqueEnemigo[index] === '馃敟') {
            indexAmbosOponentes(index, index)
            crearMensaje(" GANASTE 馃弳")
            victoriasJugador++
            spanVidasJugador.innerHTML = victoriasJugador
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = victoriasEnemigo
            victorias = victorias + 1
        } else if (ataqueJugador[index] === '馃尡' && ataqueEnemigo[index] === '馃挧') {
            indexAmbosOponentes(index, index)
            crearMensaje(" GANASTE 馃弳")
            victoriasJugador++
            spanVidasJugador.innerHTML = victoriasJugador
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = victoriasEnemigo
            victorias = victorias + 1
        } else if (ataqueJugador[index] === '馃敟' && ataqueEnemigo[index] === '馃尡') {
            indexAmbosOponentes(index, index)
            crearMensaje(" GANASTE 馃弳")
            victoriasJugador++
            spanVidasJugador.innerHTML = victoriasJugador
            vidasEnemigo--
            spanVidasEnemigo.innerHTML = victoriasEnemigo
            victorias = victorias + 1
        }  else {
            indexAmbosOponentes(index, index)
            crearMensaje(" PERDISTE 馃拃")
            vidasJugador--
            spanVidasJugador.innerHTML = victoriasJugador
            victoriasEnemigo++
            spanVidasEnemigo.innerHTML = victoriasEnemigo
            derrotas = derrotas + 1
        }
        vidas()
        marcador()
    }
}
function vidas() {
    if (victoriasJugador === victoriasEnemigo) {
        MensajeFinal("WOW!! Esto es un EMPATE!! 馃ぜ鈥嶁檪锔")
    }else if (victoriasJugador > victoriasEnemigo) {
        MensajeFinal("FELICITACIONES!! Eres el GANADOR!! 馃弳")
    } else {
        MensajeFinal("Lo siento PERDISTE 馃拃, El enemigo es el GANADOR!! 馃弳")
    }

    spanVidasJugador.innerHTML = "鉂わ笍".repeat(vidasJugador);
    spanVidasEnemigo.innerHTML = "鉂わ笍".repeat(vidasEnemigo);
}
function marcador() {

    victoriasElement.innerHTML = "Victorias: " + victorias;
    derrotasElement.innerHTML = "Derrotas: " + derrotas;
    empatesElement.innerHTML = "Empates: " + empates;
}
function crearMensaje(resultado) {
    let nuevoAtaqueDelJugador = document.createElement('p')
    let nuevoAtaqueDelEnemigo = document.createElement('p')

    sectionMensajes.innerHTML = resultado
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo

    ataquesDelJugador.appendChild(nuevoAtaqueDelJugador)
    ataquesDelEnemigo.appendChild(nuevoAtaqueDelEnemigo)
}
function MensajeFinal(resultadoFinal) {
    sectionMensajes.innerHTML = resultadoFinal
    sectionReiniciar.style.display = 'block'
    contenedorAtaques.style.display = 'none'
}
function reiniciarJuego() {
    location.reload()
}
function aleatorio(min,max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
}
// en este campo llamamos a la funci贸n iniciar juego para que lea primero todo mi html antes de mi java script
window.addEventListener('load', iniciarJuego)

Me gustar铆a poder enlazar una funci贸n gen茅rica de los datos de los mokepones , como es nuestra funci贸n Mokepon, con una tabla, para que solo hubiera que a帽ador elementos a la tabla y directamente se implementaran.
No se como se hace鈥igo investigando ajjaja

Aqui la funcion para comparar las mascotas y sumar un ataque dependiendo el tipo

Hola a todos, as铆 vamos:

  • Ac谩 se muestra cuando el mokepon es m谩s fuerte y tiene 6 ataques:

  • As铆 se ve cuando el mokepon enemigo es m谩s fuerte y tiene 4 ataques:

  • Y as铆 se ve el responsive:

Bueeeeno, no entendiiiii porque mi codigo se rompio y tampoco entendi nada desde la clase 44, me rindoooo

Hola alguien me podria explicar en que parte falle al terminar una partida veo que en el codigo del profesor imprime en pantalla los ataques que usaron y en que orden se usaron pero el mio solo imprime el ultimo ataque

tuve un problema por mas de 1 hora, siempre me arrojaba tierra aunque le diera a agua o fuego, y el problema fue la mayusculas de target.textContent

function secuenciaAtaque() {
    botones.forEach((boton) => {
        boton.addEventListener('click', (e) => {
            if (e.target.textContent === '馃敟') {
                ataqueJugador.push('FUEGO')
                console.log(ataqueJugador)
                boton.style.background = "#112f58"
                boton.disabled = true
            } else if (e.target.textContent === '馃挧') {
                ataqueJugador.push('AGUA')
                console.log(ataqueJugador)
                boton.style.background = "#112f58"
                boton.disabled = true
            } else {
                ataqueJugador.push('TIERRA')
                console.log(ataqueJugador)
                boton.style.background = "#112f58"
                boton.disabled = true
            }

            ataqueAleatorioEnemigo()
        })
    })


}

Aca dejo mi reto (nintendo no me demandes D:)

Falto yunobo pero si lo metia no quedaba simetrico xd

Hola Compa帽eros.
Tengo un problema la primer comparaci贸n de los ataques me sale undefined, alguien sabe depronto el 驴por que? , llevo ya rato revisando el c贸digo y no encuentro la solucion, si alguien me puede ayudar se lo agradeceria.

<const sectionReiniciarJuego = document.getElementById ("reiniciar")
const sectionSeleccionarataque = document.getElementById ("seleccionar-ataque")
const botonMascotasJugador = document.getElementById("boton-mascotas")

const sectionSeleccionarmascota = document.getElementById ("seleccionar-mascotas")
const botonReiniciar = document.getElementById ("boton-reiniciar")
const spanMascotaJugador = document.getElementById("mascota-jugador")

const spanMascotaEnemigo = document.getElementById("mascota-enemigo") 

const spanVidaJugador = document.getElementById ("vidas-jugador")
const spanVidaEnemigo = document.getElementById ("vidas-enemigo")

const sectionMensajes = document.getElementById ("resultado")
const ataqueDelJugador = document.getElementById ("ataque-del-jugador")
const ataquesDelEnemigo = document.getElementById ("ataques-del-enemigo")
const contenedorDeTarjetas = document.getElementById ("contenedorTarjetas")
const conteneodrDeAtaque = document.getElementById("contenedor-de-ataque")

let mokepones = []
let ataqueJugador = []
let ataqueEnemigo = []
let opcionDeMokepones
let inputHipodoge 
let inputCapipepo
let inputRatigueya 
let mascotaJugador
let ataquesMokepon
let ataqueMokeponEnemigo 
let botonFuego 
let botonAgua 
let botonTierra
let botones = [] 
let indexAtaqueJugador
let indexAtaqueEnemigo
let victoriasJugador = 0
let victoriasEnemigo = 0 
let vidaJugador = 3 
let vidaEnemigo = 3

class Mokepon {
    constructor (nombre, foto, vida){
        this.nombre = nombre;
        this.foto = foto;
        this.vida = vida;
        this.ataques = []
    }
}
 let hipodoge = new Mokepon (`Hipodoge`, "./assest/mokepons_mokepon_hipodoge_attack.png", 5)

 let capipepo = new Mokepon (`Capipepo`, "./assest/mokepons_mokepon_capipepo_attack.png", 5)

 let ratigueya = new Mokepon (`Ratigueya`, "./assest/mokepons_mokepon_ratigueya_attack.png",5)

 hipodoge.ataques.push(
    {nombre: "馃挧", id: "boton-agua"},
    {nombre: "馃挧", id: "boton-agua"},
    {nombre: "馃挧", id: "boton-agua"},
    {nombre: "馃敟", id: "boton-fuego"},
    {nombre: "馃尡", id: "boton-tierra"}
 )
 
 capipepo.ataques.push(
    {nombre: "馃尡", id: "boton-tierra"},
    {nombre: "馃尡", id: "boton-tierra"},
    {nombre: "馃尡", id: "boton-tierra"},
    {nombre: "馃挧", id: "boton-agua"},
    {nombre: "馃敟", id: "boton-fuego"}
    
 )

 ratigueya.ataques.push(
    {nombre: "馃敟", id: "boton-fuego"},
    {nombre: "馃敟", id: "boton-fuego"},
    {nombre: "馃敟", id: "boton-fuego"},
    {nombre: "馃挧", id: "boton-agua"},
    {nombre: "馃尡", id: "boton-tierra"}
 )

 mokepones.push(hipodoge, capipepo, ratigueya)

function iniciarJuego(){
    sectionSeleccionarataque.style.display = "none"
    
    mokepones.forEach((Mokepon)=> {
       opcionDeMokepones = `
        <input type="radio" name="mascota" id=${Mokepon.nombre} />
        <label class= "targeta-de-mokepon" for=${Mokepon.nombre}>
            <p>${Mokepon.nombre}</p>
            <img src=${Mokepon.foto} alt=${Mokepon.nombre}>
         </label>
       `
       contenedorDeTarjetas.innerHTML += opcionDeMokepones
            inputHipodoge = document.getElementById("Hipodoge")
            inputCapipepo = document.getElementById("Capipepo")
            inputRatigueya = document.getElementById("Ratigueya")
    })

    botonMascotasJugador.addEventListener("click", seleccionarMascotaJugador)
    
    botonReiniciar.addEventListener ("click", reinicarJuego)
}
 
function seleccionarMascotaJugador (){

    sectionSeleccionarmascota.style.display = "none"
    sectionSeleccionarataque.style.display = "flex"
    if (inputHipodoge.checked==true){
        spanMascotaJugador.innerHTML = inputHipodoge.id
        mascotaJugador = inputHipodoge.id
    }
    else if (inputCapipepo.checked==true){
        spanMascotaJugador.innerHTML = inputCapipepo.id
        mascotaJugador = inputCapipepo.id
    }
    else if (inputRatigueya.checked==true){
        spanMascotaJugador.innerHTML = inputRatigueya.id
        mascotaJugador = inputRatigueya.id
   }
   else {
    alert("No has elegido a tu compa帽ero")
    location.reload();
   }
   extraerAtaques (mascotaJugador)
   seleccionarMascotaEnemigo ()
}
function extraerAtaques (mascotaJugador){
    let ataques 
    for (let i =0; i < mokepones.length; i++){
        if(mascotaJugador==mokepones[i].nombre){
            ataques=mokepones[i].ataques
        }
    }
    mostrarAtaques(ataques)
}
function mostrarAtaques(ataques){
    sectionReiniciarJuego.style.display = "none"
    ataques.forEach((ataques)=> {
        ataquesMokepon = `
        <button id=${ataques.id} class="boton-de-ataque BAtaque">${ataques.nombre}</button>     
        `
        conteneodrDeAtaque.innerHTML +=ataquesMokepon
     })
      botonFuego = document.getElementById("boton-fuego")
      botonAgua = document.getElementById("boton-agua")
      botonTierra = document.getElementById("boton-tierra")

      botones = document.querySelectorAll(".BAtaque")
      
}
function secuenciaAtaque(){
    botones.forEach((boton)=>{
        boton.addEventListener("click", (e) =>{
           if(e.target.textContent==="馃敟"){
            ataqueJugador.push("FUEGO")
            console.log(ataqueJugador)
            boton.style.background = `#F6FA70` 
            boton.disabled = true       
           }
           else if (e.target.textContent==="馃挧"){
            ataqueJugador.push("AGUA")
            console.log(ataqueJugador)
            boton.style.background = `#F6FA70` 
            boton.disabled = true            
           }
           else{
            ataqueJugador.push("TIERRA")
            console.log(ataqueJugador)
            boton.style.background = `#F6FA70` 
            boton.disabled = true            
           }
           ataqueAleatorioEnemigo()
        })
    })
}

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

    spanMascotaEnemigo.innerHTML = mokepones[mascotaAleatoria].nombre
    ataqueMokeponEnemigo = mokepones[mascotaAleatoria].ataques
    secuenciaAtaque()
            
}

function ataqueAleatorioEnemigo () {
    let ataqueAleatorio = aleatorio(0,ataqueMokeponEnemigo.length)
    
        if (ataqueAleatorio == 0 || ataqueAleatorio==1){
            ataqueEnemigo.push("FUEGO")
        } 
        else if (ataqueAleatorio == 3 || ataqueAleatorio ==4){
            ataqueEnemigo.push("AGUA")
        }
        else {
            ataqueEnemigo.push("TIERRA")
        }
        
        console.log(ataqueEnemigo)
    iniciarPelea()
}
function iniciarPelea () {
    if(ataqueJugador.length ===5){
        combate ()
    }
}

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

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")
            victoriasJugador++
            spanVidaJugador.innerHTML = victoriasJugador
        }
        else if (ataqueJugador[index] === "AGUA" && ataqueEnemigo[index] === "FUEGO"){
            indexAmbosOponentes(index,index)
            crearMensaje("GANASTE")
            victoriasJugador++
            spanVidaJugador.innerHTML = victoriasJugador
        }
        else if (ataqueJugador[index] === "TIERRA" && ataqueEnemigo[index] === "AGUA"){
            indexAmbosOponentes(index,index)
            crearMensaje("GANASTE")
            victoriasJugador++
            spanVidaJugador.innerHTML = victoriasJugador
        }
        else {
              crearMensaje("PERDISTE")
              indexAmbosOponentes(index,index)
              victoriasEnemigo++
              spanVidaEnemigo.innerHTML = victoriasEnemigo
            }
        }
    revisarVidas ()

}
function revisarVidas(){
    if (victoriasJugador==victoriasEnemigo){
        crearMensajefinal ("EMPATE 馃槗馃槗鈿栵笍")
    }
    else if (victoriasJugador > victoriasEnemigo){
        crearMensajefinal ("GANASTE 馃コ馃コ馃帀")
    }
    else if (victoriasJugador < victoriasEnemigo){
        crearMensajefinal ("PERDISTE 馃槩馃槩馃憥")
    }
    else {
        crearMensajefinal ("PERDISTE 馃槩馃槩馃憥")
    }
}

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

    sectionMensajes.innerHTML = resultado
    nuevoAtaqueDelJugador.innerHTML = indexAtaqueJugador
    nuevoAtaqueDelEnemigo.innerHTML = indexAtaqueEnemigo
    
    ataqueDelJugador.appendChild (nuevoAtaqueDelJugador)
    ataquesDelEnemigo.appendChild (nuevoAtaqueDelEnemigo)
}
function crearMensajefinal(resultadofinal){

    sectionMensajes.innerHTML = resultadofinal
    
    sectionReiniciarJuego.style.display = "block" 
 }

function reinicarJuego (){
    location.reload()
}
function aleatorio(min, max) {
    return Math.floor(Math.random() * (max - min +1) + min)
    }

 window.addEventListener('load',iniciarJuego)>![](![](url)![](url))

Claramente platzi no estar谩 al nivel de un aula presencial donde podemos en tiempo real, conocer la respuesta a una inquietud nuestra, pero esta super

function AtaqueAleatorioEnemigo() {

let seleccionarAtaque = aleatorio(0, ataquesMokeponEnemigo.length - 1);

let ataqueImprimir = ataquesMokeponEnemigo[seleccionarAtaque].nombre

if(ataqueImprimir === '馃敟'){

    ataqueEnemigo.push('FUEGO')
    
}else if(ataqueImprimir === '馃挧'){

    ataqueEnemigo.push('AGUA')
   
}else if(ataqueImprimir === '馃尡'){

    ataqueEnemigo.push('TIERRA')

}

console.log(ataqueEnemigo);
iniciarCombate()

}