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

Don't repeat yourself (DRY)

45/84
Recursos

Uno de los consejos m谩s importantes para la optimizaci贸n de c贸digo, es no repetir el mismo.

Qu茅 significa DRY: 隆no te repitas!

El acr贸nimo DRY significa 鈥淒on鈥檛 repeat yourself鈥, es uno de los principios del buen desarrollo de software que nos recomienda no repetir c贸digo fuente que ya hemos escrito.

Repetir c贸digo puede generar que, si el d铆a de ma帽ana debemos modificarlo en un lugar, tambi茅n debamos modificarlo en los otros y si nos olvidamos de esto causar谩 problemas en nuestra aplicaci贸n, adem谩s del esfuerzo que conlleva tener que realizar todas las modificaciones.

Si tenemos un mismo c贸digo fuente en un 煤nico punto de nuestra app, ser谩 mucho m谩s f谩cil cambiarlo y tambi茅n mejoraremos el rendimiento y el peso de los archivos.

Identificando puntos de mejora

A medida que tus habilidades y conocimiento en programaci贸n crezca, lograr谩s identificar con m谩s claridad puntos donde est谩s repitiendo c贸digo y este pueda mejorarse.

Si por ejemplo tienes dos funciones que realizan la misma acci贸n:

sumarNumeros(a, b) {
    return a + b;
}
realizarSumar(a, b) {
    return a + b;
}

Debes eliminar una de ellas, dado que estamos repitiendo c贸digo innecesariamente y podemos reutilizar la funci贸n en todos los puntos de nuestro c贸digo que necesitemos.

Si te encuentras capturando elementos HTML en las funciones del c贸digo Javascript:

function iniciarJuego() {
    let botonFuego = document.getElementById('boton-fuego');
    // ...
}
function realizarAtaque() {
    let botonFuego = document.getElementById('boton-fuego');
    // ...
}

Puedes realizar esta captura del elemento una sola vez por fuera de las funciones y utilizarla siempre que necesites:

let botonFuego = document.getElementById('boton-fuego');
function iniciarJuego() {
    // ...
}
function realizarAtaque() {
    // ...
}

La no repetici贸n de c贸digo suele estar muy ligado al uso de funciones que poseen la l贸gica de tu aplicaci贸n. Pero tambi茅n es un concepto que tambi茅n tienes que aplicar al c贸digo CSS. 驴C贸mo har铆as para no repetir clases CSS y poder reutilizarlas cuando las necesites?

Tipos de variables

Habr谩s observado que cuando declaramos una variable, utilizamos la palabra let por delante. La misma permite que el valor de esa variable cambie con el tiempo a medida que el usuario utiliza el software. Puedes modificar la variable siempre que lo necesites.

En ciertas ocasiones, modificar el valor de una variable puede generar problemas. Por ejemplo, eval煤a el siguiente c贸digo:

let botonFuego = document.getElementById('boton-fuego');
function iniciarJuego() {
    // ...
}
function realizarAtaque() {
    // ...
}

驴Qu茅 ocurrir铆a si la funci贸n iniciarJuego() altera el valor de la variable botonFuego, y posteriormente la funci贸n realizarAtaque() intenta utilizar la misma? Posiblemente, la aplicaci贸n se rompa y ocurrir铆a alg煤n comportamiento inesperado.

Para evitar que una variable cambie de valor, sabiendo previamente que nunca debe cambiar, puedes usar el tipo de variable const en lugar de let.

const botonFuego = document.getElementById('boton-fuego');
// ...

Las variables 鈥淐onstantes鈥 no podr谩n cambiar nunca su valor. Ocurrir谩 un error si lo intentas.

Con este simple cambio, tu aplicaci贸n ya es un poco m谩s segura a evitar errores inesperados por cambios en los valores de las variables que no deber铆an cambiar. A medida que ganes en conocimiento y experiencia en programaci贸n, sabr谩s cu谩ndo utilizar let o cu谩ndo utilizar const.

Conclusi贸n

No es necesario obsesionarse con no repetir c贸digo fuente. A veces es necesario o no puede evitarse. Siempre es recomendable hacer un esfuerzo de escribir c贸digo de la forma m谩s escalable y limpia posible y no repetirlo es uno de los principales factores.

Evaluar la repetici贸n de c贸digo y el uso correcto de los tipos de variables son dos conceptos que tienes que comenzar a asimilar para convertirte en ese gran desarrollador de software que sue帽as.

Son principios que aplican para casi cualquier lenguaje de programaci贸n, no solo para Javascript.


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

Aportes 121

Preguntas 46

Ordenar por:

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

o inicia sesi贸n.

Para evitar tener que esperar ir al navegador y ver los errores en consola, podemos descargar la extensi贸n:


as铆 poder ver los errores de esta manera:

espero les sirva!

despues de un rato buscando el atajo del teclado para seleccionar las let y cambiarlas por const鈥 eso se hace con CTRL+ALT+FLECHA HACIA ABAJO

Resumen

Es buena pr谩ctica sacar las variables del tipo .getElementById de las funciones y colocarlas al inicio del js para ser usadas como variables globales. As铆 nos aseguramos de no estar repitiendo c贸digo. Es importante no definir m谩s de una vez la misma variable y las funciones deben tener nombres distintos para evitar problemas.

Tipos de variables:
let = su valor puede variar, es decir cambia a lo largo del c贸digo
const = su valor ser谩 el mismo de inicio a fin

pro tip: cuando quieran seleccionar un palabra espec铆fica m煤ltiples veces, pueden pararse sobre ella con el mouse y luego usar

ctrl + D 

con esto empezar谩n a seleccionar las palabras que est茅n escritas exactamente igual, una por uno de ah铆 para abajo

La linea 5 del c贸digo no es una variable. Cuidado ah铆.

Una de las frases que m谩s paz mental me da es esa de que podemos llegar a diferentes soluciones y si funciona, EST脕 BIEN HECHO.

Les dejo un buen articulo para complementar el principio DRY

7 acr贸nimos que cualquier developer deber铆a conocer

Les dejo esta extension, esta super porque te permite editar tus tags apertura y cierre de HTML al mismo tiempo.

Creo que es una practica muy avanzada para alguien que va empezando en la programacion, porque retirar los getElementByID de su locazlizacion original puede afectar al momento de querer leer el codigo siendo nuevo en la programacion, yo por mi parte las deje como comentario.

le agregue en el HTML la propiedad name con el valor boton a los 3 botones, entonces con el metodo getElementsByName()
me trae los 3 botones juntos en un array el cual recorro con un forEach y de esa manera les agrega uno por uno la propiedad disabled

<code> 
```let botones = document.getElementsByName("boton");
  botones.forEach((boton) => {
    boton.disabled = true;
  });

Tambi茅n pueden seleccionar toda la l铆nea de c贸digo haciendo click en el n煤mero que la identifica a la izquierda.

Variables:

Imag铆nate que te gusta el sushi de camar贸n 馃崣 馃崵y nomas compras ese.

const sushiDeCamaron

Como siempre compras ese sushi y no lo cambias, lo metes a esa variable const.

El asunto ser谩 cuando quieras pagar ese sushi de camar贸n y ver su precio. El precio no ser谩 el mismo este mes y dentro de 6 meses, el costo cambia.

As铆 que su precio ser谩 una variable let:

// lunes, 8 de agosto de 2022, precio de sushi de camar贸n:
 let sushiDeCamar贸n = 129

// lunes, 8 de marzo de 2023, precio de sushi de camar贸n:
 let sushiDeCamar贸n = 179

Primera vez que para una constante no se dice 鈥淐omo por ejemplo el n煤mero pi鈥濃 Muchas, muchas, muchas y m谩s gracias por dar un ejemplo de que es un valor constate en el mundo real!!!馃槃

Yo instale esta extensi贸n, me parece graciosa y 煤til

Con alt + arriba o abajo, pueden mover una linea de c贸digo sin cortar y pegar 馃槃

Si sienten que se van a perder durante el transcurso de la clase hagan un respaldo .txt de su script JS original, cuando est茅n moviendo sus variables let comenten a function pertenecen, as铆 podr谩n saber en donde se ubican en caso de que c贸digo se rompa.

El c贸digo se puede mejorar

Despues de haber escrito el c贸digo y tenerlo funcional, se puede pasar a mejorarlo, hacerlo m谩s corto y hacer que sea m谩s agradable para el usuario. En lugar de tener una misma linea de c贸digo repetida m煤lples veces

<aside>
馃挕 Existe una opci贸n para no tener lineas largas de c贸digo en visual studio
Solo hay que ir a view 鈫 word wrap y listo! tambi茅n se puede usar alt + z

</aside>

Con esto podemos sacar variables locales que tienen el mismo nombre y se declaran m煤ltiples veces y volverlas globales, esto evita repeticiones, adem谩s

Existen distintos tipos de variables

  • let es un tipo de variable que permite modificar el valor contenida en ella
  • const es un tipo de variable que guarda un valor que no queremos modificar en el futuro, una constante

Tengo este problema y no se como resolver 馃槮![]

Esta clase es oro puro

Otro atajo que me sirvi贸 much铆simo, espero que a ustedes igual

Para MAC Command
Para Windows Control

Command + D: Para seleccionar todos los similares uno por uno.
Command + Shift + L: Para seleccionar todos los similares al mismo tiempo.

Consejo VS Code

.
Para hacer m谩s r谩pida la b煤squeda de c贸digo duplicado pueden usar el atajo

Control +F

Despu茅s de seleccionar el c贸digo elegido. Esto har谩 que busque, cuente y se帽ale todas las coincidencias que haya en el c贸digo.

En pocas palabras, lo recomendable es crear nuestras variables como variables globales a menos que estas sean espec铆ficas para una funci贸n en particular.

Comparto mi c贸digo js

let ataqueJugador
let ataqueEnemigo
let vidasJugador = 3
let vidasEnemigo = 3

const $ = id => document.getElementById(id)
const $createE = element => document.createElement(element)

const $botonMascotaJugador = $('boton-mascota')
const $inputHipodoge = $('hipodoge')
const $inputCapipepo = $('capipepo')
const $inputRatigueya = $('ratigueya')

$botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador)

const $spanMascotaJugador = $('mascota-jugador')

const $spanMascotaEnemigo = $('mascota-enemigo')

const $sectionMensajes = $('resultado')
const $ataquesJugador = $('ataques-jugador')
const $ataquesEnemigo = $('ataques-enemigo')
const $nuevoAtaqueJugador = $createE('p')
const $nuevoAtaqueEnemigo = $createE('p')

const $spanVidasJugador = $('vidas-jugador')
const $spanVidasEnemigo = $('vidas-enemigo')

const $botonReiniciar = $('boton-reiniciar')

let $botonFuego = $("boton-fuego")
let $botonAgua = $("boton-agua")
let $botonTierra = $("boton-tierra")

$botonFuego.addEventListener('click', ataqueFuego)
$botonAgua.addEventListener('click', ataqueAgua)
$botonTierra.addEventListener('click', ataqueTierra)

$botonReiniciar.addEventListener('click', reiniciarJuego)

const $sectionSeleccionarAtaque = $('seleccionar-ataque')

const $sectionSeleccionarMascota = $('seleccionar-mascota')

const $sectionReiniciar = $('reiniciar')

$sectionSeleccionarAtaque.style.display = 'none'
$sectionReiniciar.style.display = 'none'

function seleccionarMascotaJugador() {
    $sectionSeleccionarMascota.style.display = 'none'
    $sectionSeleccionarAtaque.style.display = 'flex'

    if($inputHipodoge.checked) {
        $spanMascotaJugador.innerHTML = 'Hipodoge'
    }
    else if ($inputCapipepo.checked) {
        $spanMascotaJugador.innerHTML = 'Capipepo'
    }
    else if ($inputRatigueya.checked) {
        $spanMascotaJugador.innerHTML = 'Ratigueya'
    }
    else {
        alert('Selecciona un Moqopon')
    }
    seleccionarMascotaEnemigo()
}

function seleccionarMascotaEnemigo() {
    let mascotaAleatoria = aleatorio(1,3)

    if (mascotaAleatoria == 1) {
        $spanMascotaEnemigo.innerHTML = 'Hipodoge'
    } else if (mascotaAleatoria == 2) {
        $spanMascotaEnemigo.innerHTML = 'Capipepo'
    } else {
        $spanMascotaEnemigo.innerHTML = 'Ratigueya'
    }
}

function ataqueFuego() {
    ataqueJugador = 'FUEGO馃敟馃敟馃敟'
    ataqueAleatorioEnemigo()
}
function ataqueAgua() {
    ataqueJugador = 'AGUA馃挧馃挧馃挧'
    ataqueAleatorioEnemigo()
}
function ataqueTierra() {
    ataqueJugador = 'TIERRA馃尡馃尡馃尡'
    ataqueAleatorioEnemigo()
}

function ataqueAleatorioEnemigo() {
    let ataqueAleatorio = aleatorio(1,3)

    if(ataqueAleatorio == 1) {
        ataqueEnemigo = 'FUEGO馃敟馃敟馃敟'
    } else if (ataqueAleatorio == 2) {
        ataqueEnemigo = 'AGUA馃挧馃挧馃挧'
    } else {
        ataqueEnemigo = 'TIERRA馃尡馃尡馃尡'
    }
    combate()
}

function combate() {
    if (ataqueJugador == ataqueEnemigo) {
        crearMensaje('EMPATE')
    } else if (ataqueJugador == 'FUEGO馃敟馃敟馃敟' && ataqueEnemigo == 'TIERRA馃尡馃尡馃尡') {
        crearMensaje('GANASTE')
        vidasEnemigo--
        $spanVidasEnemigo.innerHTML = vidasEnemigo
    } else if (ataqueJugador == 'AGUA馃挧馃挧馃挧' && ataqueEnemigo == 'FUEGO馃敟馃敟馃敟') {
        crearMensaje('GANASTE')
        vidasEnemigo--
        $spanVidasEnemigo.innerHTML = vidasEnemigo
    } else if (ataqueJugador == 'TIERRA馃尡馃尡馃尡' && ataqueEnemigo == 'AGUA馃挧馃挧馃挧') {
        crearMensaje('GANASTE')
        vidasEnemigo--
        $spanVidasEnemigo.innerHTML = vidasEnemigo
    } else {
        crearMensaje('PERDISTE')
        vidasJugador--
        $spanVidasJugador.innerHTML = vidasJugador
    }
    revisarVidas()
}

function revisarVidas() {
    if (vidasEnemigo == 0) {
        crearMensajeFinal('Felicitaciones Ganaste :)')
    } else if (vidasJugador == 0) {
        crearMensajeFinal('Felicitaciones Perdiste :(')
    }
}

function crearMensaje(resultado) {
    $sectionMensajes.innerHTML = resultado
    $nuevoAtaqueJugador.innerHTML = ataqueJugador
    $nuevoAtaqueEnemigo.innerHTML = ataqueEnemigo

    $ataquesJugador.appendChild($nuevoAtaqueJugador)
    $ataquesEnemigo.appendChild($nuevoAtaqueEnemigo)
}

function crearMensajeFinal(resultadoFinal) {
    $sectionMensajes.innerHTML = resultadoFinal

    $botonFuego.disabled = true
    $botonAgua.disabled = true
    $botonTierra.disabled = true

    $sectionReiniciar.style.display = 'block'

    $botonFuego.style.background = '#fff'
    $botonAgua.style.background = '#fff'
    $botonTierra.style.background = '#fff'
}

function reiniciarJuego() {
    location.reload()
}

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

muy buena clase para aprender otro tipo de opinion sobre js y otro tipo de variables, lo que hice fue dejar el documento anterior tal cual y crear otro para hacer las modificaciones 馃槂

La estructura del curso esta genial, de esta manera se comprende mejor el porqu茅 de las cosas y para que la usamos.

Me dio paz mental y tranquilidad ver el c贸digo mejor ordenado aunque sigo sin entender del todo, TODO lo que he escrito XD. A煤n as铆 seguimos en la batalla.

woow, super muy buena clase

Uno de las herramientas de Visual Estudio Code es que podemos darle un formato al c贸digo al dar un 鈥渃lick derecho鈥 a la pagina y luego 鈥淒ar formato al documento鈥 o mediante su atajo del teclado " Shift + Alt + F "
Si el formato no te gusta puedes quitarlo con " Ctrl + Z "

El formato por defecto le pone " ; " al final de las l铆neas de c贸digo

WOW QUE GRAN PROFESOR QUE ERES DIEGO, TODO SE ENTIENDE RAPIDISIMO.

Excelente inicio del Profesor, para la optimizaci贸n del c贸digo en JS. Muy claro y conciso al momento de explicar las mejores practicas y la diferencia entre let y const. 馃馃徏鈥嶐煉

JavaScript me rompe la cabeza ahora que estoy reci茅n comenzando, pero el profesor Diego me la vuelve a armar.
Un genio y le entiendo todo.
Muchas gracias Diego

Les dejo este atajo, espero que les sirva.

Para MAC Option
Para Windows ALT

Para seleccionar varias l铆neas de c贸digo:

  1. Presionan Option
  2. Sin dejar de presionar Option ir谩n marcando las l铆neas de c贸digo con el mouse.

(ctrl + d ) estos teclados es para seleccionar en serie hacia abajo como hacia a los let.

cuando usamos la variable let : se puede modificar esta variable podr谩 modificarse es decir ser谩 din谩mica durante un juego podr铆a cambiar de texto etc.

cuando usamos const :es lo contrario se queda estable y no se modificara en el juego o en la pagina. puede servir para t铆tulos.

esta fue la soliucion que logre antes de empezar esta clase 馃槂

// al crear una constante asignamos el $ con el fin de ahorrarno el texto del evento getElementById
const $ = selector => document.getElementById(selector)
let ataqueJugador 
let ataqueRival
let triunfosJugador = 3
let triunfosRival = 3
let sectionReiniciar = $('reiniciar')
let imgAvatar
let spanAvatar
let boton
let sectionSeleccionar
let alAzar

function iniciarJuego(){
    sectionSeleccionar = $('elegir-ataque')
    sectionSeleccionar.style.display = "none"
    
    sectionReiniciar.style.display = "none"

    //creaci贸n de variable con LET enlazando con el HTML el id del boton ( esto se podria ver como una conversi贸n de HTML a JS)
    boton = $('boton-avatar') //nombre variable = objeto. tipo de metodo ('nombre de id en html')
    boton.addEventListener('click', seleccionarAvatarJugador) // nombre variable (el que se va manipular presente). tipo de metodo ( evento"argumento", variable que se va ejecutar despu茅s)
    
    boton = $('boton-aire')
    boton.addEventListener('click', ataqueAire)
    boton = $('boton-agua')
    boton.addEventListener('click', ataqueAgua)
    boton = $('boton-fuego')
    boton.addEventListener('click', ataqueFuego)
    boton = $('boton-tierra')
    boton.addEventListener('click', ataqueTierra)

    boton = $('boton-reiniciar')
    boton.addEventListener('click', reiniciarJuego)
}

// esta funci贸n permite identificar que avatar selecccionaste y dependiendo del valor verdadero dara a conocer tu elecci贸n
function seleccionarAvatarJugador(){
    sectionSeleccionar = $('elegir-avatar')
    sectionSeleccionar.style.display = "none"

    sectionSeleccionar = $('elegir-ataque')
    sectionSeleccionar.style.display = "flex"

    let inputAng = $('ang')
    let inputKatara = $('katara')
    let inputSuko = $('suko')
    let inputToph = $('toph')
    spanAvatar = $('avatar-jugador')
    imgAvatar = $('img-avatar-jugador')

    if(inputAng.checked){
        spanAvatar.innerHTML = 'Ang'
        imgAvatar.src = "../img/ang.png"
    } else if(inputKatara.checked){
        spanAvatar.innerHTML = 'Katara'
        imgAvatar.src = "../img/katara.png"
    } else if (inputSuko.checked){
        spanAvatar.innerHTML = 'Suko'
        imgAvatar.src = "../img/zuko.png"
    } else if(inputToph.checked){
        spanAvatar.innerHTML = 'Toph'
        imgAvatar.src = "../img/toph.png"
    } else{
        alert("Debes seleccionar un avatar para iniciar el juego.")
        reiniciarJuego()
    }

    seleccionarAvatarRival()
}

function Aleatorio(min,max){
    return Math.floor(Math.random()*(max - min + 1 ) + min )
}

//Funci贸n para seleccionar rival la misma logica con el piedra, papel y tijeras
function seleccionarAvatarRival(){ 
    alAzar = (1,4)
    spanAvatar = $('avatar-rival')
    imgAvatar = $('img-avatar-rival')

    if(alAzar == 1){
        spanAvatar.innerHTML ='Ang'
        imgAvatar.src = "../img/ang.png"
    } else if(alAzar == 2){
        spanAvatar.innerHTML = 'Katara'
        imgAvatar.src = "../img/katara.png"
    } else if(alAzar == 3){
        spanAvatar.innerHTML = 'Suko'
        imgAvatar.src = "../img/zuko.png"
    } else if(alAzar == 4){
        spanAvatar.innerHTML = 'Toph'
        imgAvatar.src = "../img/toph.png"
    } else{
        alert("Debes seleccionar un avatar para dar inicio al juego.")
    }

}

function ataqueAire(){
    ataqueJugador = 'Aire'   
    seleccionarElementoRival()
}

function ataqueAgua(){
    ataqueJugador = 'Agua'
    seleccionarElementoRival()
}

function ataqueFuego(){
    ataqueJugador = 'Fuego'
    seleccionarElementoRival()
}

function ataqueTierra(){
    ataqueJugador = 'Tierra'
    seleccionarElementoRival()
}

function seleccionarElementoRival(){ 
    alAzar = Aleatorio(1,4)

    if(alAzar == 1){
        ataqueRival = 'Aire'
    } else if(alAzar == 2){
        ataqueRival = 'Agua'
    } else if(alAzar == 3){
        ataqueRival = 'Fuego'
    } else if(alAzar == 4){
        ataqueRival = 'Tierra'
    }

    combate()
}

function combate(){
    let spanVidasJugador = $('vida-jugador')
    let spanVidasRival = $('vida-rival')

    if( ataqueJugador == ataqueRival ){
        crearMensaje("Empataron")
    } else if((ataqueJugador == 'Aire' && ataqueRival == 'Agua')
    || (ataqueJugador == 'Tierra' && ataqueRival == 'Fuego') 
    || (ataqueJugador == 'Tierra' && ataqueRival == 'Aire')
    || (ataqueJugador == 'Fuego' && ataqueRival == 'Aire')
    || (ataqueJugador == 'Agua' && ataqueRival == 'Fuego')
    || (ataqueJugador == 'Agua' && ataqueRival == 'Tierra')){
        crearMensaje("Ganaste")
        triunfosRival --
        spanVidasRival.innerHTML = triunfosRival
    } else{
        crearMensaje("Perdiste")
        triunfosJugador --
        spanVidasJugador.innerHTML = triunfosJugador
    }

    revisarVidas()
}   

function revisarVidas(){
    if(triunfosRival == 0){
        crearMensajeFinal ('Felicitaciones, Ganaste! 馃巻')
    } else if(triunfosJugador == 0){
        crearMensajeFinal ('A dado una gran pelea, pero tu rival a sido muy fuerte. Perdiste. 馃檨')
    }
}

function crearMensaje(resultado){
    // en esta l铆nea estamos ayudando a identificar createElement que etiqueta editar en HTML
    let sectionMensajes = $('resultado')
    let ataqueDelJugador = $('ataques-jugador')
    let ataqueDelRival = $('ataques-rival')

    // el metodo createElement permite editar el HTML desde JS cualquier etiqueta
    let nuevoAtaqueJugador = document.createElement('p')
    let nuevoAtaqueRival = document.createElement('p')
    
    sectionMensajes.innerHTML = resultado
    nuevoAtaqueJugador.innerHTML = ataqueJugador
    nuevoAtaqueRival.innerHTML = ataqueRival

    ataqueDelJugador.appendChild(nuevoAtaqueJugador)
    ataqueDelRival.appendChild(nuevoAtaqueRival)

}

function crearMensajeFinal(resultadoFinal){

    let sectionMensajes = $('resultado')

    sectionMensajes.innerHTML = resultadoFinal
    
    boton = $('boton-aire')
    boton.disabled = true
    boton = $('boton-agua')
    boton.disabled = true
    boton = $('boton-fuego')
    boton.disabled = true
    boton = $('boton-tierra')
    boton.disabled = true

    sectionReiniciar.style.display = "block"

}    

function reiniciarJuego(){
    location.reload()
}


//este metodo lo que hace es ejecutar la carga de la pagina despu茅s de haber invocado la funcion de la l铆nea 1
window.addEventListener('load', iniciarJuego )

Intent茅 usar variables globales para ahorrar algunas l铆neas de c贸digo. Solo que, el juego est谩 presentando errores con el bot贸n de reiniciar y seleccionar la mascota 馃槓

yo lo que hice fue mandar todas las variables que usaba en 2 o mas funciones y las dejaba como global.

let ataqueJugador = ''
let ataqueEnemigo = ''
let vidaJugador = 3
let vidaEnemigo = 3
let sectionMensajeCombate  = document.getElementById('resultado')
let sectionSeleccionarAtaque = document.getElementById('seleccionar-ataque')
    sectionSeleccionarAtaque.style.display = 'none'
let sectionMensajeFinal = document.getElementById('mensajes')
    sectionMensajeFinal.style.display = 'none'
let btnReiniciar = document.getElementById('Reiniciar')
    btnReiniciar.style.display = 'none'  
let botonMascotaJugador = document.getElementById('boton-mascota')
    botonMascotaJugador.addEventListener('click', seleccionarMascotaJugador)
let botonFuego = document.getElementById('boton-fuego')
    botonFuego.addEventListener('click',ataqueFuego)
let botonAgua = document.getElementById('boton-agua')
    botonAgua.addEventListener('click',ataqueAgua)
let botonPlanta = document.getElementById('boton-planta') 
    botonPlanta.addEventListener('click',ataquePlanta)
let botonReiniciar = document.getElementById('reiniciar')
    botonReiniciar.addEventListener('click',reiniciarJuego)   
            


// funci贸n para saber que eleccion tomo el jugador
function seleccionarMascotaJugador(){
    let mokeponHipodoge = document.getElementById('hipodoge')
    let mokeponCapipepo = document.getElementById('capipepo')
    let mokeponRatigueya = document.getElementById('ratigueya')
    let mokeponLangostelvis = document.getElementById('langostelvis')
    let mokeponTucapalma = document.getElementById('tucapalma')
    let mokeponPydos = document.getElementById('pydos')
    let spanMascotaJugador = document.getElementById('mascota-jugador')
    let imagenMokeponCombate = document.getElementById('imagen-mokepon-jugador')
    let eleccionJugador= ''
    if(mokeponHipodoge.checked){         
        eleccionJugador = 'Hipodoge'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/hipodoge.jpg" alt="">')        
    }else if(mokeponCapipepo.checked){
        eleccionJugador = 'Capipepo' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/capipepo.jpg" alt="">')         
    }else if(mokeponRatigueya.checked){
        eleccionJugador = 'Ratigueya' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/ratigueya.jpg" alt="">')   
    }else if(mokeponLangostelvis.checked){
        eleccionJugador = 'Langostelvis'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/langostelvis.jpg" alt="">')   
    }else if(mokeponTucapalma.checked){
        eleccionJugador = 'Tucapalma' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/tucapalma.jpg" alt="">')  
    }else if(mokeponPydos.checked){
        eleccionJugador = 'Pydos'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/pydos.jpg" alt="">')   
    }else{
        alert ('No seleccionaste a un Mokepon')
    }
    spanMascotaJugador.innerHTML = eleccionJugador
    if(eleccionJugador!=''){
        seleccionarMascotaEnemigo()
    }

    
}

//funci贸n para saber que mokepon elige la computadora
function seleccionarMascotaEnemigo(){
//mostramos la seccion ataque
    sectionSeleccionarAtaque.style.display = 'flex'
//ocultamos la seccion mascota
    let sectionSeleccionarMascota = document.getElementById('seleccionar-mascota')
        sectionSeleccionarMascota.style.display = 'none'
//la computadora elige un mokemon aleatorio con un numero de 1 a 6
    let eleccionEnemigo = aleatorio(1,6)
    let imagenMokeponCombate = document.getElementById('imagen-mokepon-enemigo')
    let spanMascotaEnemigo = document.getElementById('mascota-enemigo')
    if(eleccionEnemigo == 1){
        spanMascotaEnemigo.innerHTML = 'Hipodoge' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/hipodoge.jpg" alt="">')        
    }else if(eleccionEnemigo == 2){ 
        spanMascotaEnemigo.innerHTML = 'Capipepo' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/capipepo.jpg" alt="">')         
    }else if(eleccionEnemigo == 3){
        spanMascotaEnemigo.innerHTML = 'Ratigueya'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/ratigueya.jpg" alt="">')   
    }else if(eleccionEnemigo == 4){
        spanMascotaEnemigo.innerHTML = 'Langostelvis'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/langostelvis.jpg" alt="">')   
    }else if(eleccionEnemigo == 5){
        spanMascotaEnemigo.innerHTML = 'Tucapalma'
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/tucapalma.jpg" alt="">')   
    }else if(eleccionEnemigo == 6){
        spanMascotaEnemigo.innerHTML = 'Pydos' 
        imagenMokeponCombate.innerHTML = ('<img src="./imagenes/pydos.jpg" alt="">')  
    }        
    
}

// aca son las funciones de los 3 botones de ataque y se inicia la seleccion de ataque del enemigo
function ataqueFuego(){
    ataqueJugador = 'Fuego'
    fnAtaqueEnemigo()
}


function ataqueAgua(){
    ataqueJugador = 'Agua'
    fnAtaqueEnemigo()
}


function ataquePlanta(){
    ataqueJugador = 'Planta'
    fnAtaqueEnemigo()
}

//aca el enemigo genera un ataque aleatorio 1 es fuego 2 agua 3 planta
function fnAtaqueEnemigo(){
    let ataqueAleatorioEnemigo = aleatorio(1,3)
    if(ataqueAleatorioEnemigo == 1){
        ataqueEnemigo='Fuego'
    }else if(ataqueAleatorioEnemigo == 2){
        ataqueEnemigo='Agua'
    }else{
        ataqueEnemigo='Planta'
    } 
    combate()        
} 

//se inicia el combate y se da el mensaje del resultado, tambien se incia el contador de vidas 
function combate(){ 
    spanVidasJugador = document.getElementById('vida-jugador')
    spanVidasEnemigo = document.getElementById('vida-enemigo')
    if(ataqueJugador == ataqueEnemigo){
        crearMensaje('No hizo efecto')
    }else if(ataqueJugador == 'Fuego' && ataqueEnemigo == 'Planta'  ||  ataqueJugador == 'Agua' && ataqueEnemigo == 'Fuego'  ||  ataqueJugador == 'Planta' &&ataqueEnemigo == 'Agua'){
        crearMensaje('Fue: Muy eficaz')
        vidaEnemigo --
        spanVidasEnemigo.innerHTML=(vidaEnemigo)
    }else{
        crearMensaje('Fue: Poco eficaz')
        vidaJugador --
        spanVidasJugador.innerHTML=(vidaJugador)
    }
    revisarVidas()
}

//revisamos las vidas si algun jugador queda en 0 vidas se despliega la funcion mensaje final
function revisarVidas(){
    if (vidaJugador == 0 ){
        crearMensajeFinal('Perdiste')           
    }else if(vidaEnemigo == 0){
        crearMensajeFinal('Ganaste')
    }
}

 //aca creamos los mensajes del combate: ataque del jugador, enemigo y el resultado del mismo
 function crearMensaje(resultadoCombate){
    //creamos el parrafo y lo asignamos al id mensajes 
    let mensajeAtaqueJugador = document.getElementById('ataque-jugador')
    let mensajeAtaqueEnemigo = document.getElementById('ataque-enemigo')
    mensajeAtaqueJugador.innerHTML =(ataqueJugador)
    mensajeAtaqueEnemigo.innerHTML = (ataqueEnemigo)
    sectionMensajeCombate.innerHTML = (resultadoCombate)

}

//funci贸n mensaje final
function crearMensajeFinal(resultadoVidas){  
    //ocultamos el contenido del combate y mostramos el mensajes final en la misma ventana 
    sectionMensajeCombate.style.display = 'none'
    sectionMensajeFinal.style.display = 'flex'
    //mostramos boton reiniciar 
    btnReiniciar.style.display = 'flex'
    //creamos el parrafo y lo asignamos al id mensajes       
    let parrafoMensajeFinal = document.createElement('p')
    //enviamos el mensaje que se va a colocar en el parrafo creado anteriormente
    parrafoMensajeFinal.innerHTML = resultadoVidas
    sectionMensajeFinal.appendChild(parrafoMensajeFinal) 
    //deshabilitamos los botones de ataque
    botonAgua.disabled = true
    botonFuego.disabled = true
    botonPlanta.disabled = true
}

//funci贸n reinciar juego
function reiniciarJuego(){
    location.reload()
}

//funci贸n aleatorio
function aleatorio(min,max){
    return Math.floor(Math.random() * (max-min+1)+min)
}

鈥楶or qu茅 estos no las pusimes鈥, se oye al profesor en el minuto 16:35. Esa palabra no existe, es pusimos.

Esta fue mi solucion

const $ = (a)=> document.querySelector(a);

asi podemos seleccionar todos los elementos del html tanto por id como por clase

En muchas ocaciones, es importante diferenciar las variables globales de las locales, para ello se puede colocar una gv o una lv al inicio de la variable

Volviendo a repetir las clases 馃槬, tengo un error que no he logrado solucionar de clases m谩s avanzadas

Esto es lo que necesitaba para poder aportar a mi c贸digo sin romperme la cabeza, ahora se siente ordenado y f谩cil de leer, muchas gracias :3

Un truco para seleccionar la l铆nea mucho m谩s r谩pido dando tres click r谩pidos seleccionas toda la l铆nea, otro para borrar los espacios r谩pidamente al darle click en una l铆nea y luego mantienes la tecla alt y le das click en otra l铆nea vas a crear un nuevo cursor y luego que ya tengas todos los cursores en los espacios que deseas borrar solo debes de dar ctrl + x, y listo ya los espacios se han borrado

para optimizar este c贸digo(Cod1) lo solucione(Cod 2) de la siguiente forma

Cod1:

function crearMensajeEnemigo (){
  
  let parrafo = document.createElement('p')  
    parrafo.innerHTML = ataqueEnemigo
    mensajeEnemigo.appendChild(parrafo)
   }

function crearMensajeJugador (){

  let parrafo = document.createElement('p')
    parrafo.innerHTML = ataquejugador 
    mensajeJugador.appendChild(parrafo)
  }

Cod2

function crearMensaje (ataque,mensaje){
    let parrafo = document.createElement('p')  
    parrafo.innerHTML = ataque
    mensaje.appendChild(parrafo)
   }

En linux si quieren seleccionar diferentes partes del codigo presionen

Crtl+Shift+P

Despues busquen

Toggle Multi-Cursor Modifier

Presionen Enter y ya solo presionando Ctrl pueden seleccionar diferentes partes del codigo.

Fuente: https://stackoverflow.com/questions/60272595/vscode-multi-line-edit-select-on-linux-mint

Se siente la tenci贸n en el ambiente mientras el profe Diego, corta y pega el c贸digo previamente escrito鈥

Para leer mejor el c贸digo
En el men煤 View+Word Wrap
Mac Option+Z
Windows Alt+Z

Yo necesito un curso m谩s b谩sico que este =(

Muy 煤til lo de declarar variables al principio del c贸digo JS, lo que a mi entender quedar铆an como variables o constantes 鈥globales鈥, las cuales podremos utilizar dentro de cualquier funci贸n.
Algo importante es nombrarlas de manera clara para dar una idea de a qu茅 se refieren, as铆 cuando las utilicemos dentro de las funciones ser谩 m谩s f谩cil entender a qu茅 hacen referencia.

let: una cajita donde podes ir guardando diferentes cosas

const: una caja fuerte donde solo puedes guardar una sola cosa para siempre

```js let ataqueJugador let ataqueEnemigo let vidasJugador = 3 let vidasEnemigo = 3 let seccionAtaque = document.getElementById('selecciona-ataque') let seccionReiniciar = document.getElementById('reiniciar') let botonFuego = document.getElementById('boton-fuego') let botonAgua = document.getElementById('boton-agua') let botonTierra = document.getElementById('boton-tierra') let sectionMensaje = document.getElementById('resultado') function iniciarJuego() { // let seccionAtaque = document.getElementById('selecciona-ataque') seccionAtaque.style.display = 'none' // let seccionReiniciar = document.getElementById('reiniciar') seccionReiniciar.style.display = 'none' let botonMascotaJugador = document.getElementById('boton-mascota'); botonMascotaJugador.addEventListener('click', seleccionarMascotajugador); // let botonFuego = document.getElementById('boton-fuego') botonFuego.addEventListener('click', ataqueFuego); // let botonAgua = document.getElementById('boton-agua') botonAgua.addEventListener('click', ataqueAgua); // let botonTierra = document.getElementById('boton-tierra') botonTierra.addEventListener('click', ataqueTierra); let botonReiniciar = document.getElementById('boton-reiniciar') botonReiniciar.addEventListener('click', reiniciarJuego) } function seleccionarMascotajugador() { let hipodoge = document.getElementById('hipodoge'); let capipepo = document.getElementById('capipepo'); let ratigueya = document.getElementById('ratigueya'); let spanMascotaJugador = document.getElementById('mascota-jugador') if(hipodoge.checked) { spanMascotaJugador.innerHTML = 'Hipodoge' } else if(capipepo.checked) { spanMascotaJugador.innerHTML = 'Capipepo' } else if(ratigueya.checked === true) { spanMascotaJugador.innerHTML = 'Ratigueya' } else { alert('Debes seleccionar una mascota para jugar 馃暪锔') return } seleccionarMascotaEnemigo() let seccionMascota = document.getElementById('seleccionar-mascota') seccionMascota.style.display = 'none' // let seccionAtaque = document.getElementById('selecciona-ataque') seccionAtaque.style.display = 'flex' // let seccionReiniciar = document.getElementById('reiniciar') seccionReiniciar.style.display = 'none' } function seleccionarMascotaEnemigo() { let mascotaAleatoria = aleatorio(1,3) let spanMascotaEnemigo = document.getElementById('mascota-enemigo') if(mascotaAleatoria === 1) { spanMascotaEnemigo.innerHTML = 'Hipodoge'; } else if(mascotaAleatoria === 2) { spanMascotaEnemigo.innerHTML = 'Capipepo'; } else { spanMascotaEnemigo.innerHTML = 'Ratigueya'; } } function ataqueFuego() { ataqueJugador = 'FUEGO' ataqueAleatorioEnemigo() } function ataqueAgua() { ataqueJugador = 'AGUA' ataqueAleatorioEnemigo() } function ataqueTierra() { ataqueJugador = 'TIERRA' ataqueAleatorioEnemigo() } function ataqueAleatorioEnemigo() { let ataqueAleatorio = aleatorio(1,3) if(ataqueAleatorio === 1) { ataqueEnemigo = 'FUEGO'; } else if(ataqueAleatorio === 2) { ataqueEnemigo = 'AGUA'; } else { ataqueEnemigo = 'TIERRA'; } combate() } function combate() { let spanVidasJugador = document.getElementById('vidas-jugador') let spanVidasEnemigo = document.getElementById('vidas-enemigo') if (ataqueJugador == ataqueEnemigo) { 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() } function revisarVidas() { if(vidasJugador === 0) { crearMensajeFinal('Lo siento, perdiste 馃槪') } else if(vidasEnemigo === 0) { crearMensajeFinal('Felicitaciones, ganaste 馃弳') } } function crearMensaje(resultado) { // let sectionMensaje = document.getElementById('resultado') let ataqueDelJugador = document.getElementById('ataque-del-jugador') let ataqueDelEnemigo = document.getElementById('ataque-del-enemigo') let nuevoAtaqueDelJugador = document.createElement('p') let nuevoAtaqueDelEnemigo = document.createElement('p') sectionMensaje.innerHTML = resultado nuevoAtaqueDelJugador.innerHTML = ataqueJugador nuevoAtaqueDelEnemigo.innerHTML = ataqueEnemigo ataqueDelJugador.appendChild(nuevoAtaqueDelJugador) ataqueDelEnemigo.appendChild(nuevoAtaqueDelEnemigo) } function crearMensajeFinal(resultadoFinal) { // let sectionMensaje = document.getElementById('resultado') sectionMensaje.innerHTML = resultadoFinal // let botonFuego = document.getElementById('boton-fuego') botonFuego.disabled = true // let botonAgua = document.getElementById('boton-agua') botonAgua.disabled = true // let botonTierra = document.getElementById('boton-tierra') botonTierra.disabled = true // let seccionReiniciar = document.getElementById('reiniciar') seccionReiniciar.style.display = 'flex' } function reiniciarJuego() { location.reload(); } function aleatorio(min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } window.addEventListener('load', iniciarJuego); ```
Me da muy buena impresi贸n cuando en los recursos de la clase dejan contribuciones como la de *Kevin Fiorentino (Platzi Contributor)*. Esos res煤menes no son f谩ciles de hacer y puede pensarse que no hacen falta, pero en algunas clases y sobre todo al principio cambian por completo la experiencia porque siempre tienes el texto en el que apoyarte. As铆 que muchas gracias a Kevin y a todos que hacen este tipo de aportaciones para los cursos馃
Nuevo aprendizaje
cc
vayv
mi mundo
hola alguien por espa帽a, italia para hacer relaciones e intercambiar conocimiento, dejo mi perfil de instagram: <https://www.instagram.com/diego.martin.caballero/>
C贸digo JS: ```js let btnPetPlayer = document.getElementById("btn-select-pet"); let btnFire = document.getElementById("btn-fire-attack"); let btnWater = document.getElementById("btn-water-attack"); let btnEarth = document.getElementById("btn-earth-attack"); let btnReset = document.getElementById("btn-reset-game"); let inputHipodoge = document.getElementById("hipodoge"); let inputCapipepo = document.getElementById("capipepo"); let inputRatigueya = document.getElementById("ratigueya"); let petPlayer = document.getElementById("pet-player"); let petEnemy = document.getElementById("pet-enemy"); let spanLifesPlayer = document.getElementById("lifes-player"); let spanLifesEnemy = document.getElementById("lifes-enemy"); let attackPlayer; let attackEnemy; let lifesPlayer = 3; let lifesEnemy = 3; function typeAttack(value) { let attack = ""; switch (value) { case 1: { attack = "Fuego 馃敟"; break; } case 2: { attack = "Agua 馃挧"; break; } case 3: { attack = "Tierra 馃尡"; break; } default: { attack = "ATTACK NOT FOUND"; break; } } return attack; } function changeDisplay(label, status) { var element = document.getElementById(label); if (element) { element.style.display = status; } } function changeStatusVisible(label, status) { let element = document.getElementById(label); if (element) { element.disabled = status; } } function petSelected(numberPet) { let pet = ""; switch (numberPet) { case 1: { pet = "Hipodoge"; break; } case 2: { pet = "Capipepo"; break; } case 3: { pet = "Ratigueya"; break; } default: { pet = "PET NO ENCONTRADA"; break; } } return pet; } function random(min, max) { return Math.floor(Math.random() * (max - min + 1) + min); } function selectPetPlayer() { if ( inputHipodoge.checked || inputCapipepo.checked || inputRatigueya.checked ) { selectPetEnemy(); changeDisplay("select-attack", "flex"); changeDisplay("select-pet", "none"); } if (inputHipodoge.checked) { petPlayer.innerHTML = petSelected(1); } else if (inputCapipepo.checked) { petPlayer.innerHTML = petSelected(2); } else if (inputRatigueya.checked) { petPlayer.innerHTML = petSelected(3); } else { alert("Error: No seleccionaste a t煤 mascota."); } } function selectPetEnemy() { let petEnemySelected = petSelected(random(1, 3)); petEnemy.innerHTML = petEnemySelected; } function resultCombat() { console("console-player", attackPlayer); console("console-enemy", attackEnemy); if (lifesEnemy > 0 && lifesPlayer > 0) { if (attackEnemy == attackPlayer) { overwriteConsole("Empate! 馃し鈥嶁檪锔"); } else if (attackPlayer == "Fuego" && attackEnemy == "Tierra") { lifesEnemy--; overwriteConsole("Ganaste ronda 馃巿馃帀"); } else if (attackPlayer == "Agua" && attackEnemy == "Fuego") { lifesEnemy--; overwriteConsole("Ganaste ronda 馃巿馃帀"); } else if (attackPlayer == "Tierra" && attackEnemy == "Agua") { lifesEnemy--; overwriteConsole("Ganaste ronda 馃巿馃帀"); } else { lifesPlayer--; overwriteConsole("Perdiste ronda 馃槩"); } } else { changeStatusVisible("btn-fire-attack", true); changeStatusVisible("btn-water-attack", true); changeStatusVisible("btn-earth-attack", true); changeDisplay("reset-game", "flex"); if (lifesEnemy == 0) { overwriteConsole( "隆Ganaste la partida! 馃巿馃帀
- - - Juego finalizado - - -" ); } else if (lifesPlayer == 0) { overwriteConsole( "隆Perdiste la partida! 馃槶
- - - Juego finalizado - - -" ); } } spanLifesEnemy.innerHTML = lifesEnemy + " 馃挀"; spanLifesPlayer.innerHTML = lifesPlayer + " 馃挀"; } function console(label, msg) { let console = document.getElementById(label); let paragraph = document.createElement("p"); paragraph.innerHTML = msg; console.appendChild(paragraph); } function overwriteConsole(msg) { let console = document.getElementById("console"); console.innerHTML = msg; } function innitGame() { changeDisplay("select-attack", "none"); changeDisplay("reset-game", "none"); btnPetPlayer.addEventListener("click", selectPetPlayer); btnFire.addEventListener("click", () => { attackPlayer = typeAttack(1); attackEnemy = typeAttack(random(1, 3)); resultCombat(); }); btnWater.addEventListener("click", () => { attackPlayer = typeAttack(2); attackEnemy = typeAttack(random(1, 3)); resultCombat(); }); btnEarth.addEventListener("click", () => { attackPlayer = typeAttack(3); attackEnemy = typeAttack(random(1, 3)); resultCombat(); }); btnReset.addEventListener("click", () => { location.reload(); }); } window.addEventListener("load", innitGame); ```
Para eliminar espacios en blanco pongan Ctrl+F y en buscar "\n\n" y marcada la opci贸n ".\* " y en remplazar "\n "y dan en Remplazar todo ![](https://static.platzi.com/media/user_upload/2023-12-29_23h10_04-bdf19147-5bab-4772-a4dc-aae153301c62.jpg)
```js buenos dias Nelson opina : a fin de no perderme quem variables corresponden con que funciones he dejado en el script sus variables correspondientes- como se ve en el script que acabo de enviar gracias Atentamentre Nelson Alfonso Gutierrez ```

lo estaba haciendo en la marcha, y cuando me salio el error de doble variable me asuste ya que hasta se perdi贸 el centrado.

arriba! diego buena clase percibo que si eres un buen docente鈥

let playerAttack
let enemyAttack
let mascotaJugador
let mascotaEnemigo
let vidasJugador = 3
let vidasEnemigo = 3

function styleDisplay(htmlElementName, displayOption) {
    let variableSP = document.getElementById(htmlElementName)
    variableSP.style.display = displayOption
}

function eventListener(htmlElementName, event, functionName) {
    let variableAEL = document.getElementById(htmlElementName)
    variableAEL.addEventListener(event, functionName)
}

function inputChecked(htmlElementName) {
    let variableIC = document.getElementById(htmlElementName)
    if (variableIC.checked) {
        return true
    } else {
        return false
    }
}

function setDisabled(htmlElementName,state) {
    let variableSD = document.getElementById(htmlElementName)
    variableSD.disabled = state
}

function innerHTMLfunction(htmlElementName, text) {
    let variableIHTML = document.getElementById(htmlElementName)
    variableIHTML.innerHTML = text
}

function iniciarJuego() {
    styleDisplay('seleccionar-ataque', 'none')
    
    eventListener('boton-mascota', 'click', seleccionarMascotaJugador)

    eventListener('boton-fuego', 'click', ataqueFuego)
    eventListener('boton-agua', 'click', ataqueAgua)
    eventListener('boton-tierra', 'click', ataqueTierra)
    eventListener('boton-reiniciar', 'click', restartGame)
}

function ataqueFuego() {
    playerAttack = "馃敟"
    enemyRandomAttack()
}

function ataqueAgua() {
    playerAttack = "馃挧"
    enemyRandomAttack()
}

function ataqueTierra() {
    playerAttack = "馃尡"
    enemyRandomAttack()
}

function seleccionarMascotaJugador() {
    styleDisplay('reiniciar','none')

    if (inputChecked('hipodoge')) {
        innerHTMLfunction('mascota-jugador', 'Hipodoge')
        mascotaJugador = "Hipodoge"
        sectionsSwipe()
    } else if (inputChecked('capipepo')) {
        innerHTMLfunction('mascota-jugador', 'Capipepo')
        mascotaJugador = "Capipepo"
        sectionsSwipe()
    } else if (inputChecked('ratigueya')) {
        innerHTMLfunction('mascota-jugador', 'Ratig眉eya')
        mascotaJugador = "Ratig眉eya"
        sectionsSwipe()
    } else {
        alert("Seleccione su mascota")
    }

    seleccionarMascotaEnemiga()   
}

function seleccionarMascotaEnemiga() {
    let randNum = randomNumber(1,3)

    if (randNum == 1) {
        innerHTMLfunction('mascota-enemigo', 'Hipodoge')
        mascotaEnemigo = "Hipodoge"
    } else if (randNum == 2) {
        innerHTMLfunction('mascota-enemigo', 'Capipepo')
        mascotaEnemigo = "Capipepo"
    } else {
        innerHTMLfunction('mascota-enemigo', 'Ratig眉eya')
        mascotaEnemigo = "Ratig眉eya"
    }
}

function sectionsSwipe() {
    innerHTMLfunction('vidas-jugador', vidasJugador)
    innerHTMLfunction('vidas-enemigo', vidasEnemigo)
    styleDisplay('seleccionar-ataque','flex')
    styleDisplay('seleccionar-mascota','none')
}

function enemyRandomAttack() {
    let randomAttack = randomNumber(1,3)
    
    if (randomAttack == 1) {
        enemyAttack = "馃敟"
    } else if (randomAttack == 2) {
        enemyAttack = "馃挧"
    } else {
        enemyAttack = "馃尡"
    }
    combat()
}

function combat() {
    if (playerAttack == enemyAttack) {
        createMessage("隆EMPATE!")
    } else if (playerAttack == "馃敟" && enemyAttack == "馃尡") {
        createMessage("隆BATALLA GANADA!")
        vidasEnemigo--
        innerHTMLfunction('vidas-enemigo',vidasEnemigo)
    } else if (playerAttack == "馃挧" && enemyAttack == "馃敟") {
        createMessage("隆BATALLA GANADA!")
        vidasEnemigo--
        innerHTMLfunction('vidas-enemigo',vidasEnemigo)
    } else if (playerAttack == "馃尡" && enemyAttack == "馃挧") {
        createMessage("隆BATALLA GANADA!")
        vidasEnemigo--
        innerHTMLfunction('vidas-enemigo',vidasEnemigo)
    } else {
        createMessage("隆BATALLA PERDIDA!")
        vidasJugador--
        innerHTMLfunction('vidas-jugador',vidasJugador)
    }
    revisarVidas()
}

function revisarVidas() {
    if (vidasEnemigo == 0) {
        createFinalMessage("隆GANASTE LA GUERRA!")
        styleDisplay('reiniciar','block')
    } else if (vidasJugador == 0){
        createFinalMessage("隆PERDISTE LA GUERRA!")
        styleDisplay('reiniciar','block')
    }
}

function innerAndAppend(typeOfElement,text,HTMLelementName) {
    let variableIandA1 = document.createElement(typeOfElement)
    let variableIandA2 = document.getElementById(HTMLelementName)
    variableIandA1.innerHTML = text
    variableIandA2.appendChild(variableIandA1)
}

function createMessage(resultado) {
    innerHTMLfunction("resultado",resultado)
    innerAndAppend('p',playerAttack,"ataques-del-jugador")
    innerAndAppend('p',enemyAttack,"ataques-del-enemigo")
}

function createFinalMessage(finalResult) {
    innerHTMLfunction("resultado",finalResult)
    setDisabled('boton-fuego',true)
    setDisabled('boton-agua',true)
    setDisabled('boton-tierra',true)
}

function restartGame() {
    location.reload()
}

function randomNumber(min, max) {
    return Math.floor(Math.random() * (max-min + 1) + min)
}

window.addEventListener('load', iniciarJuego)

wow para mi es otro level

gracias por el comentario

Me encantan todos los profesores de Platzi, contagian la energia!

don鈥檛 repeat yourself (dry) --> no te repitas

const --> constante
let --> variable

隆Gracias por la clase! Estuve un poco confundido con ciertas cosas, pero logr茅 entenderlas. Este curso ha pasado de algo muy b谩sico a cosas complejas. La evoluci贸n es evidente, pero los profesores explican de maravilla y te motivan a seguir hasta el final.

DRY, a trasladar el c贸digo repetido arriba , antes iniciar las funciones y as铆 puede eliminar las repeticiones.

Yo lo hice as铆, remplac茅 todos los document.get.ElementById() por esta funci贸n.

function  returnElement(nameElement)
{
    let newElement = document.getElementById(nameElement)
    return newElement
}

Lo que yo hice fue crear m谩s funciones para no tener tantas variables globales, se me hace m谩s facil de leer y organizado.
Si se les ocurren mejoras avisen 馃槂

// Variables globales
let ataqueJugador = '';
let ataqueEnemigo = '';
let resultado = '';
let vidasJugador = 3;
let vidasEnemigo = 3;


function iniciarJuego() {
  ocultarElemento('container-juego');
  ocultarElemento('reiniciar');
  
  // Selecci贸n de mascota del jugador	
  evento('boton-mascota', 'click', seleccionarMascotaJugador);

  // Botones de ataque del jugador
  evento('boton-fuego', 'click', ataqueFuego);
  evento('boton-agua', 'click', ataqueAgua);
  evento('boton-tierra', 'click', ataqueTierra);

  // Reiniciar el juego
  evento('boton-reiniciar', 'click', reiniciarJuego);
}

// Funciones para la mascota del jugador
function seleccionarMascotaJugador() {
  let inputDragon = document.getElementById('dragon');
  let inputPerro = document.getElementById('perro');
  let inputPez = document.getElementById('pez');
  let spanMascotaJugador = document.getElementById('mascota-jugador');

  switch (true) {
    case inputDragon.checked:
      spanMascotaJugador.innerHTML = '馃悏 Dragoncito';
      break;
    case inputPerro.checked:
      spanMascotaJugador.innerHTML = '馃悤 Perrito';
      break;
    case inputPez.checked:
      spanMascotaJugador.innerHTML = '馃 Pececito';
      break;
    default:
      alert('selecciona una mascota');
  }

  mostrarElemento('container-juego', 'flex');
  ocultarElemento('container-mascota');

  seleccionarMascotaEnemigo();
}

function ataqueFuego() {
  ataqueJugador = '馃敟';
  elementoAtaqueEnemigo();
}
function ataqueAgua() {
  ataqueJugador = '馃挧';
  elementoAtaqueEnemigo();
}
function ataqueTierra() {
  ataqueJugador = '馃尡';
  elementoAtaqueEnemigo()
}

// Funciones para la mascota enemiga
function seleccionarMascotaEnemigo() {
  let mascotaAleatoria = aleatorio(1, 3);
  let spanMascotaEnemigo = document.getElementById('mascota-enemigo');

  switch (mascotaAleatoria) {
    case 1:
      spanMascotaEnemigo.innerHTML = '馃悏 Dragoncito';
      break;
    case 2:
      spanMascotaEnemigo.innerHTML = '馃悤 Perrito';
      break;
    default:
      spanMascotaEnemigo.innerHTML = '馃 Pececito';
      break;
  }
}

function elementoAtaqueEnemigo() {
  let ataqueAleatorio = aleatorio(1, 3);

  switch (ataqueAleatorio) {
    case 1:
      ataqueEnemigo = '馃敟';
      break;
    case 2:
      ataqueEnemigo = '馃挧';
      break;
    default:
      ataqueEnemigo = '馃尡';
      break;
  }
  
  combate();
}

// Combate
function combate() {
  switch (ataqueJugador, ataqueEnemigo) {
    case ataqueEnemigo, ataqueJugador:
      resultado = 'Empataste';
      break;
    case '馃尡', '馃挧' || '馃挧', '馃敟' || '馃敟', '馃尡':
      resultado = 'Ganaste';
      vidasEnemigo--;
      break;
    default:
      resultado = 'Perdiste';
      vidasJugador--;
      break;
  }

  actualizarVidas(vidasJugador, vidasEnemigo);

  crearMensaje(ataqueJugador, 'ataque-jugador');
  crearMensaje(ataqueEnemigo, 'ataque-enemigo');
  crearMensaje(resultado, 'resultado-ronda');

  if (revisarVidas() !== '') crearMensajeGanador(revisarVidas());
}

// Actualizar vidas
function actualizarVidas(vidasJugador, vidasEnemigo) {
  modificarMensaje(vidasJugador, 'vidas-jugador');
  modificarMensaje(vidasEnemigo, 'vidas-enemigo');
}

// document.getElementById(id).innerHTML = mensaje;
function crearMensajeGanador(ganador) {
  crearMensaje(`馃弳 El ganador es ${ganador} 馃弳`, 'resultado');

  // Desactivar botones para evitar ataques despu茅s de terminado el juego
  desactivarBotones('boton-fuego');
  desactivarBotones('boton-agua');
  desactivarBotones('boton-tierra');

  // Mostrar bot贸n de reinicio
  mostrarElemento('reiniciar', 'flex');
}

function desactivarBotones(id) {
  document.getElementById(id).disabled = true;
}

function revisarVidas() {
  let ganador = '';
  switch (true) {
    case vidasJugador === 0:
      ganador = '馃が Enemigo';
      break;
    case vidasEnemigo === 0:
      ganador = '馃槀 Jugador';
      break;
  }
  return ganador;
}

function reiniciarJuego() {
  location.reload();
}

// Funciones auxiliares
function evento(id, evento, funcion) {
  document.getElementById(id).addEventListener(evento, funcion);
}

function ocultarElemento(id) {
  document.getElementById(id).style.display = 'none';
}

function mostrarElemento(id, display) {
  document.getElementById(id).style.display = display;
}

function crearMensaje(mensaje, id) {
  let parrafo = document.createElement('p');
  parrafo.innerHTML = mensaje;
  document.getElementById(id).appendChild(parrafo);
  document.getElementById(id).scrollTop = document.getElementById(id).scrollHeight;
}

function modificarMensaje(mensaje, id) {
  document.getElementById(id).innerHTML = mensaje;
}

function aleatorio(min, max) { 
  return Math.floor(Math.random() * (max - min + 1) + min) ;
}
window.addEventListener('load', iniciarJuego);

Buenos d铆as: hice a si;
let botonFuego = document.getElementById(鈥榖oton-fuego鈥,鈥榖oton-agua鈥,鈥榖oton-tierra鈥)
botonFuego.disabled = true
let spanVidasJugador = document.getElementById(鈥榲idas-jugador鈥,鈥榲idas-enemigo鈥)

EL resto no me atrev铆 a tocarlo 馃槓

(DRY)

<code> function crearMensajeFinal(resultadoFinal) {
    
    let sectionMensajes = document.getElementById('resultado')

    sectionMensajes.innerHTML = resultadoFinal

    var buttonPoderes = ['boton-fuego', 'boton-flechas', 'boton-esqueletos']

    buttonPoderes.forEach(function(ataques){
       var botones= document.getElementById(ataques);
       botones.disabled = true;
    })

    let sectionReiniciar = document.getElementoById('reiniciar')
    sectionReiniciar.style.display = 'block'
}

En vez del ataque me aparece [HTMLDIVELEMENT] ?

Llevo atrapado en esta parte bastante tiempo y la verdad no se como solucionar. mil gracias

Nunca hab铆a sentido tanto placer por el orden y la no repetici贸n. :v

Los docentes de platzi son muy bien seleccionados. Son carism谩ticos; saben transpolar su conocimiento, que es mucho, para que uno como estudiante pueda entender. Adem谩s, generan mucha emoci贸n al expresar sus ideas.

Felicito en gran medida a su equipo de trabajo.

Yo crear铆a variables globales o funciones que me permitan acceder a variables que se deban usar una y otra vez.

lo primero que se me vino a la cabeza fue esto

function crearMensaje(resultado, ataqueJugador, ataqueEnemigo) {
    const sectionMensajes = document.getElementById('resultado');
    sectionMensajes.innerHTML = resultado;

Otra manera muy sencilla y r谩pida de seleccionar una l铆nea entera es haciendo 3 clicks r谩pidos sobre la l铆nea en cualquier punto.

Sirve tambi茅n para seleccionar varias l铆neas a la vez con mantener presionada la tecla Alt as铆 como hace el profesor Diego.

Entonces JDC nos creco un monton de variables repetidas鈥 tocara hablar seriamente con 茅l.

Espero poder ayudarle a quien tenga alguna duda con el reto del profesor.

En el c贸digo se repet铆an demasiados鈥

document.getElementById();.

En la primera funci贸n que corre cuando el html ha cargado por completo ten铆a algunas secciones configuradas para que no se muestren, como un ejemplo tenemos:

let seccion2 = document.getElementById("seccionElegirAtaque");
seccion2.style.display = "none";

//Este c贸digo se repet铆a algunas otras veces m谩s junto con m谩s secciones en el resto del c贸digo//
.
Lo que hice para optimizar y no volver a repetir el mismo c贸digo fue hacer la siguiente funci贸n:

function seccion2(x) {
let seccion2 = document.getElementById("seccionElegirAtaque");
seccion2.style.display = x;
}

Y listo, ahora en la primera funci贸n que corre en el script, a la cual yo reconozco como la principal tengo el siguiente c贸digo:

//Para ocultar la seccion...
seccion2("none"); 

//Para mostrar la seccion con el display tipo flex...
seccion2("flex");

A partir de aqu铆 remplaz茅 esta misma funci贸n por las partes de mi c贸digo donde se repet铆a todo el c贸digo.

Espero les haya ayudado compa帽eros 馃槂

Con "CTRL + F " pueden abrir el buscador de palabras del visual studio, as铆 pueden identificar m谩s r谩pido esas variables repetidas.

Ya me parec铆a raro tantas variables iguales dentro de funciones, yo en un inicio pensaba dejarlas afuera y no lo hice por el tema que los profes no lo hac铆an.

Que increible es Diego, de verdad que da una seguridad escucharlo, y mostrar como es que programa, increible.

Desde el inicio no s茅 porqu茅 pero no segu铆 el c贸digo y estas dos 煤ltimas clases no tuve que editarlo, lo tengo como al final de esta clase 馃榿

VAR vs LET vs CONST

la variable const quiere decir que no se puede volver a reasignar, cuando el valor de una variable const es un array o object estos si pueden ser mutables

Un consejo鈥a que a partir de ac谩 se va a modificar el c贸digo inicial de JavaScript鈥reen otro archivo .js, copien todo a ese nuevo archivo y en el HTML llaman a ese nuevo archivo en script鈥e esta manera tendr谩n el c贸digo mejorado y lo podr谩n comparar con el anterior.

馃挭 Evita repetir el MISMO c贸digo varias veces, esto para tener un c贸digo limpio y f谩cil de escalar.

Aprend铆 que:

  • Let para variables que pueden modificar su valor varias veces
  • Const para variables que cuando reciban su valor se quede fijo.

Es interesante el proceso de depuraci贸n que sucede ya en esta etapa. Es importante ir paso a paso, declarar las variables que vamos a ir utilizando y siempre luego si revisar nuestro c贸digo para saber como optimizarlo sin que falle.

Lo que veo es que el Profe Diego es de muy cortar y pegar para hacer optimizaciones. En este punto ya me hace mucha falta entender del control de versi贸n en GitHub, por ahora tuve que crear una carpeta aparte con una copia del proyecto anterior.
Solo hago esto porque no se como llevar el control de versiones ahora mismo y siento que en cualquier momento voy a romper el c贸digo.

Es interesante la forma en que se usaron todas las variables 鈥淚D鈥 como una declaracion de variables globales. Sabia de estos, pero nunca como usarlos en las practicas. Ahora si me quedo claro el como se deben aplicar. Espero seguir aprendiendo mas sobre esto.

Que pedazo de crack que es el profe diego. Lo banco a muerte en 2 clases me demostr贸 que es un monstro!

buena practicas aplicadas

Me vol贸 la cabeza esta clase, al momento de estar siguiendo las clases no me hab铆a percatado de nada de lo que vimos aqu铆, Gracias.

ATAJO PARA SUSTITUIR TEXTO (en Mac):

command + option + F

Hay videos en Platzi y en el curso de Prework con las mejores extensiones para el VisualStudioCode, les recomiendo instalarlas, hay par que te coloreen el c贸digo, te muestren los errores, te acomoden el c贸digo, el de LiveServer que es para que el proyecto se recargue autom谩ticamente en el navegador cuando hacemos cambios y m谩s, recomendados porque nos hacen el trabajo m谩s eficiente.

Creo que tambien debe de haber una manera para optimizar la funcion: aleatorio( min, max )

return Math.floor ( Math.random () * (max-min + 1) + min )

Si quieren entender c贸mo se comporta const en comparaci贸n con let, a modo de prueba podr铆an modificar las variables:

let vidasJugador = 3
let vidasEnemigo = 3

por:

const vidasJugador = 3
const vidasEnemigo = 3

Recarguen el juego y tras seleccionar algunos ataques, ver谩n que los valores de las vidas no cambiar谩n, nunca se restar谩n y esto es debido al cambio de la varible let (que permite cambios en su valor) hacia const (que siempre es constante). Este simple cambio romper谩 el juego siendo que nunca terminar谩, ya que ning煤n jugador llegar谩 a cero vidas y esto evitar谩 que aparezca el bot贸n de reiniciar.