Introducción al curso

1

¡Alto! Tenemos una nueva versión de este curso para ti

2

Bienvenidos al Curso de Fundamentos de JavaScript

3

Repositorio de este curso de fundamentos de JS

Primeros pasos en JavaScript

4

Variables

5

Variables: Strings

6

Variables: Números

7

Funciones

8

El alcance de las funciones

9

Objetos

10

Desestructurar objetos

11

Parámetros como referencia o como valor

12

Comparaciones en JavaScript

Estructuras de Control y Funciones

13

Condicionales

14

Funciones que retornan valores

15

Arrow functions

16

Estructuras repetitivas: for

17

Estructuras repetitivas: while

18

Estructuras repetitivas: do-while

19

Condicional múltiple: switch

Arrays

20

Introducción a arrays

21

Filtrar un array

22

Transformar un array

23

Reducir un array a un valor

Programación Orientada a Objetos en JavaScript

24

Cómo funcionan las clases en JavaScript

25

Modificando un prototipo

26

El contexto de las funciones: quién es this

27

La verdad oculta sobre las clases en JavaScript

28

Clases en JavaScript

Asincronismo

29

Funciones como parámetros

30

Cómo funciona el asincronismo en JavaScript

31

Cómo funciona el tiempo en JavaScript

32

¿Qué pasó con swapi.co?

33

Callbacks

34

Haciendo múltiples requests

35

Manejando el Orden y el Asincronismo en JavaScript

36

Manejo de errores con callbacks

37

Promesas

38

Promesas Encadenadas

39

Múltiples promesas en paralelo

40

Async-await: lo último en asincronismo

Juego de HTML

41

Comenzando el juego

42

Generando una secuencia de números

43

Iluminando la secuencia de colores

44

Obteniendo el input del usuario

45

Agregando la verificación del color elegido

46

Agregando los estados finales del juego

47

Conclusiones del curso

Complementos

48

Diferencias entre var, let y const

49

Memoización: ahorrando cómputo

50

¿Hace cuántos días naciste?

51

Funciones recursivas

52

Entiende los closures de JavaScript

53

Estructuras de datos inmutables

54

Cambiando de contexto al llamar a una función

55

¿Cuándo hace falta poner el punto y coma al final de la línea?

No tienes acceso a esta clase

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

Agregando los estados finales del juego

46/55
Recursos

Incluiremos una librería de mensajes con estilos mucho más agradables que el mensaje básico de javascript para mostrar los estados finales del juego al usuario.

Aportes 285

Preguntas 59

Ordenar por:

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

Hola, agregué unas leves mejoras al juego y este ha sido el resultado:
Link juego
Saludos y espero manito arriba 😄

Lo integre al proyecto y temática que use en el curso de frontend developer, le agregue sonido y estados al botón.
Dejo el link para compartir: https://sergiovg91.github.io/common/juego_secuencia.html
Lo probé en mi celular y me va genial, me gusto mucho el curso así que a continuar trabajando para mejorar el proyecto :3

Juego Maki Secuncia

Hola compañeros así quedo mi versión ¿qué les parece?
Demo: https://giovannihm.github.io/Thanos-Says/
Repositorio: https://github.com/GiovanniHM/Thanos-Says

Tu explicas bien pero creo que en la parte de este proyecto no explicaste bien. Todo muy bien explicado, tema a tema. Pero ya en el proyecto salieron temas que no se vieron en el curso y que no les dedicaste lo suficiente para explicar. Ibas usando un montón de cosas que no explicaste. Tienes que tener en cuenta que no todos los que nos metimos al curso somos ingenieros. Hice todo el proyecto y me funcionó pero muchas cosas no las entendí. De todas maneras gracias por todo.

Genial, solo vine a refrescar conocimientos para inciarme de lleno a NodeJS.
Javascript es de los lenguajes de programacion mejores pagados hoy en dia chicxs, aprendan nodejs y una que otra librería de frontend, Angular4/5(framework) o React. Van a obtener superpoderes literales de la mano de JS.

Hola a todos, así quedó el mío, agregandole varias cosas. Por si quieren checarlo
Juego: https://albertodaniel-castillo.github.io/Simon-dice/
Repositorio https://github.com/AlbertoDaniel-Castillo/Simon-dice

código JS final juego SIMON DICE

const celeste = document.getElementById('celeste')
      const violeta = document.getElementById('violeta')
      const naranja = document.getElementById('naranja')
      const verde = document.getElementById('verde')
      const btnEmpezar = document.getElementById('btnEmpezar')
      const ULTIMO_NIVEL = 10
      

      

      class Juego {
        constructor() {
            this.inicializar = this.inicializar.bind(this)
          this.inicializar()
          this.generarSecuencia()

          setTimeout(this.siguienteNivel(),500)
          
        }
        inicializar() {
            this.elegirColor= this.elegirColor.bind(this)
            this.siguienteNivel = this.siguienteNivel.bind(this)
            this.toggleBtnEmpezar()
             this.nivel= 1
             this.colores= {
            celeste,
            violeta,
            naranja,
            verde
          }
        }

        toggleBtnEmpezar(){
            if(btnEmpezar.classList.contains('hide')){
                btnEmpezar.classList.remove('hide')
            }else{
                btnEmpezar.classList.add('hide')
            }
        }

        generarSecuencia(){
        this.secuencia= new Array(ULTIMO_NIVEL).fill(0).map(n=> Math.floor(Math.random()*4))
       }

       siguienteNivel(){
           this.subnivel = 0
           this.iluminarSecuencia()
           this.agregarEventosClick()
       }

       transformarNumeroAColor(numero)
       {

        switch(numero){

            case 0:
            return 'celeste'
            case 1:
            return 'violeta'
            case 2:
            return 'naranja'
            case 3:
            return 'verde'

        }

       }

       transformarColorANumero(color)
       {

        switch(color){

            case 'celeste':
            return 0
            case 'violeta':
            return 1
            case 'naranja':
            return 2
            case 'verde':
            return 3

        }

       }


       iluminarSecuencia(){

        for(let  i=0; i <  this.nivel; i++)
        {
            let color =this.transformarNumeroAColor(this.secuencia[i])
            
           setTimeout(() => {
            console.log(color)
            this.iluminarColor(color)
        },  1000 * i ) 
       
           
            }
       }
       
       iluminarColor(color){

        this.colores[color].classList.add('light')
        setTimeout(() => this.apagarColor(color),350)

       }

       apagarColor(color) {
           this.colores[color].classList.remove('light')
       }

       agregarEventosClick(){
           this.colores.celeste.addEventListener('click',this.elegirColor)
           this.colores.verde.addEventListener('click',this.elegirColor)
           this.colores.violeta.addEventListener('click',this.elegirColor)
           this.colores.naranja.addEventListener('click',this.elegirColor)
        }

        eliminarEventosClick(){
            this.colores.celeste.removeEventListener('click',this.elegirColor)
           this.colores.verde.removeEventListener('click',this.elegirColor)
           this.colores.violeta.removeEventListener('click',this.elegirColor)
           this.colores.naranja.removeEventListener('click',this.elegirColor)
      
        }

        elegirColor(ev){
           const nombreColor = ev.target.dataset.color
           const numeroColor = this.transformarColorANumero(nombreColor)
            
           this.iluminarColor(nombreColor)
           if(numeroColor === this.secuencia[this.subnivel]){

            this.subnivel++
            if(this.subnivel==this.nivel){
                this.nivel++
                this.eliminarEventosClick()
                if(this.nivel ==(ULTIMO_NIVEL + 1)){
                    this.ganoElJuego()
                }else{
                    setTimeout(this.siguienteNivel,1500)
                }
            }

           }else{
               this.perdioElJuego()
           }
        }

        ganoElJuego(){
            swal('Platzi','Felicitaciones,Ganaste el JUEGO perro','success')
            .then(this.inicializar)
        }

        perdioElJuego(){
            swal('Platzi','Lo lamentamos ,PERDISTEEE','error')
            .then(() =>{
                    this.eliminarEventosClick()
                this.inicializar()
                })
        }
    
    }
      function empezarJuego() {
        window.juego = new Juego()
      
    }

Les comparto mi version de Simon Dice:
https://jorgevels.github.io/SimonDice/

Comparto mi mejora del proyecto 😃

https://boogst.github.io/Simon-dice/

comparto la mi versión del juego.

juego: simon dice
repositorio: simon dice

Se que no es la gran cosa, pero se siente increíble haber podido terminar el reto y haber cumplido con mis propias metas, me siento satisfecho por dentro.
Les comparto mi simón.
https://github.com/darkOwlWood/SimonChallange

![](

Hola!
comparto mi versión del juego ¡Simon Dice!, al cual le agregue cieratas característica para hacerlo mas entretenido. ¿Qué les parece?.
Demo: https://mesajoao91.github.io/simondice/
Repositorio: https://github.com/mesajoao91/simondice/

aca dejo mi juego le cambie la ui!

Así quedó mí versión.

Hola gente, les dejo mi Simon aca.
Le agregué los sonidos del viejo aparato y una opción de cambiar de niveles a demás de unos estilos bien chulos 😉 .

Listo! 😄
Por si quieren jugar
Y el repositorio
Me dicen qué tal!

Hola, les comparto mi versión del Juego llamado Afina tu Memoria.
Le coloqué mi toque personal, espero les guste y, estoy abierto a recibir feedback. Salu2.

👉 Afina Tu Memoria

Le agregue un efecto de confeti cuando ganas
https://simon-dice.aomine1745.now.sh/

Y asi quedo el juego, le añadi los niveles y algunas animaciones al botón.

Lo que le agregué al juego fue audio a los botones y que el jugador pudiera elegir un nivel de dificultad (basado ene l número máximo de niveles). Les comparto el código.
PD. los audios lo baje de http://www.sonidosmp3gratis.com/bip

const celeste = document.getElementById("celeste");
const violeta = document.getElementById("violeta");
const naranja = document.getElementById("naranja");
const verde = document.getElementById("verde");
const btnEmpezar = document.getElementById("btnEmpezar");

class Juego {
  constructor(dificultad) { 
    this.ULTIMO_NIVEL = dificultad;
    this.inicializar = this.inicializar.bind(this);
    this.inicializar();
    this.generarSecuencia();
    setTimeout(this.siguienteNivel, 600);
  }

  inicializar() {
    this.elegirColor = this.elegirColor.bind(this);
    this.siguienteNivel = this.siguienteNivel.bind(this);
    this.toogleBtnInicializar();
    
    this.nivel = 1
    this.colores = {
      celeste,
      violeta,
      naranja,
      verde
    }
  }

  toogleBtnInicializar(){
    if(btnEmpezar.classList.contains("hide")){
      btnEmpezar.classList.remove('hide');
    }else{
      btnEmpezar.classList.add('hide');
    }
  }

  generarSecuencia(){
    this.secuencia = new Array(this.ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
  }

  siguienteNivel(){
    this.subNivel = 0;
    this.iluminarSecuencia();
    this.agregarEventosClic();
  }

  numeroAColor(numero){
    switch(numero){
      case 0:
        return "celeste"
      case 1:
        return "violeta"
      case 2:
        return "naranja"
      case 3:
        return "verde"
    }
  }

  colorANumero(color){
    switch(color){
      case "celeste":
        return 0
      case "violeta":
        return 1
      case "naranja":
        return 2
      case "verde":
        return 3
    }
  }

  agregarEventosClic(){
    this.colores.celeste.addEventListener("click",this.elegirColor)
    this.colores.verde.addEventListener("click",this.elegirColor)
    this.colores.violeta.addEventListener("click",this.elegirColor)
    this.colores.naranja.addEventListener("click",this.elegirColor)
  }

  eliminarEventosClick(){
    this.colores.celeste.removeEventListener("click",this.elegirColor)
    this.colores.verde.removeEventListener("click",this.elegirColor)
    this.colores.violeta.removeEventListener("click",this.elegirColor)
    this.colores.naranja.removeEventListener("click",this.elegirColor)
  }

  sonidoColor(color){
    var audio_url = `resources/${color}.mp3`
    var audio = new Audio(audio_url);
    audio.play();
  }

  elegirColor(ev){
    const nombreColor = ev.target.dataset.color;
    const numeroColor = this.colorANumero(nombreColor);
    this.iluminarColor(nombreColor);
    this.sonidoColor(nombreColor);
    if (numeroColor === this.secuencia[this.subNivel]){
      this.subNivel++;
      if (this.subNivel === this.nivel){
        this.nivel++;
        this.eliminarEventosClick()
        if (this.nivel === (this.ULTIMO_NIVEL + 1)){
          this.ganoJuego();
        } else {
          setTimeout(this.siguienteNivel,1400);
        }
      } 
      } else {
        this.perdioJuego();
    }
  }

  iluminarColor(color){
    this.colores[color].classList.add("light");
    this.sonidoColor(color);
    setTimeout(() => this.apagarColor(color), 400)
  }

  apagarColor(color){
    this.colores[color].classList.remove("light");
  }

  iluminarSecuencia() {
    for (let i = 0; i < this.nivel; i++){
        const color = this.numeroAColor(this.secuencia[i]);
        setTimeout(() => this.iluminarColor(color), 700 * i);
    }
  }

  ganoJuego(){
    swal("¡Buen trabajo!", "Ganaste el juego", "success")
    .then(this.inicializar)
  }

  perdioJuego(){
    swal("Perdiste", "inténtalo de nuevo", "info")
    .then(() => {
      this.eliminarEventosClick();
      this.inicializar();
    })
  }
}

function empezarJuego() {
  var dificultad;
  swal("Selecciona un nivel", {
    buttons: {
      Principiante: {
        text: "Principiante",
        value:"Principiante"
      },
      Intermedio: {
        text: "Intermedio",
        value:"Intermedio"
      },
      Experto: {
        text: "Experto",
        value:"Experto"
      }
    }
  }).then((value) =>{
    switch(value){
      case "Principiante":
        dificultad = 5;
        break;
      case "Intermedio":
        dificultad = 10;
        break;
      case "Experto":
        dificultad = 15;
        break;
      default:
        dificultad = 5;
    }
    window.juego = new Juego(dificultad)
  })
}

Hola amigos !
Aquí comparto mi versión del juego :
githubPages:
https://drew-santana.github.io/Simon-Dice/
repo:
https://github.com/drew-santana/Simon-Dice/

Excelentes clases hasta el momento !

Comparto mi Simón Dice terminado, rehíce la mayoría desde 0 😄

Este es el repo por si alguno desea revisarlo o darme algo de feedback
https://github.com/JoseGarcia2001/Simon_Says

Le implementé una cuenta regresiva para iniciar el juego, un contador del nivel actual, un puntaje final y no activa los eventos de click hasta que se acabe de mostrar la secuencia.
Simón Dice

creo que me volvere a hacer el curso, aun no entiendoo, y eso que ya hice el de js basico

Para ver mi version mejorada y jugar un poquito https://jan888adams.github.io/simon-says-game/simon-says-game/index.html

Para entender realmente todo se debe repetir este último módulo Juego HTML varias veces y…

while(1) {
console.log('Practicar')
}

Agrego mi avance con algunos agregados como timer y sonido.
(https://moonbe77.github.io/simonPlatziProyect/)
Github:
Por favor comenten que mas le harian y si quieren pueden hacer pull sobre este repo para ir modificandolo entre todos.
TODO: cambiar la velocidad de la secuencia al avanzar en los niveles.

Les comparto un grado de complejidad que adicione al juego:
A medida que avanzan los niveles el tiempo de iluminación de cada color es menor y la velocidad en la que se ilumina la secuencia es mayor.

La lógica esta en el método de iluminarSecuencia, de tal forma que la velocidad aumente en proporción al nivel y también en el método de apagarColor para que este tiempo disminuya en proporción al nivel.

 iluminarSecuencia() {
        let tiempoEntreColores = 1000 - (this.nivel*(1000*0.05))
        for (let i = 0; i < this.nivel; i++) {
            let color = this.transformarNumeroAColor(this.secuencia[i])
            setTimeout(() => {
                this.iluminarColor(color, MAQUINA)
                console.log(`Ilumino el color ${color}`)
            }, tiempoEntreColores * i);
        }
    }```

apagarColor(color, origen) {
        let tiempoDeIluminacion = 0;
        if(origen === USUARIO){
            tiempoDeIluminacion = 300 
        }else if(origen === MAQUINA){
            tiempoDeIluminacion = 350 - (this.nivel*(350*0.03))
        }

        setTimeout(() => {
            this.colores[color].classList.remove('light')
        }, tiempoDeIluminacion);
    }

Agregué un fondo, cambié el botón y agregué un puntaje. Que les parece?

Yo hice la mia basandome en un diseño de lo genial que vino este mes en 2020!! aun nose como agregarle puntaje pero me divertire desucbriendolo!! muchas gracias por el excelente curso

const celeste = document.getElementById('celeste');
const violeta = document.getElementById('violeta');
const naranja = document.getElementById('naranja');
const verde = document.getElementById('verde');
const btnEmpezar = document.getElementById('btnEmpezar');
const ULTIMO_NIVEL = 2;

class Juego {
  constructor() 
  {
    this.inicializar();
    this.generarSecuencia();
    this.siguienteNivel();
  }

  inicializar() 
  {
    this.siguienteNivel = this.siguienteNivel.bind(this);
    this.elegirColor = this.elegirColor.bind(this);
    this.toggleBtnEmpezar();
    this.nivel = 1;
    this.colores = {
      celeste,
      violeta,
      naranja,
      verde
    }
  }

  toggleBtnEmpezar()
  {
    if(btnEmpezar.classList.contains('hide'))
    {
      btnEmpezar.classList.remove('hide');
    }
    else
    {
      btnEmpezar.classList.add('hide');
    }
  }

  generarSecuencia()
  {
    this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4));
  }

  siguienteNivel()
  {
    this.subnivel = 0;
    this.iluminarSecuencia();
    this.agregarEventosClick();
  }

  transformarNumeroAColor(num)
  {
    switch (num) {
      case 0:
        return 'celeste'
      case 1:
        return 'violeta'
      case 2:
        return 'naranja'
      case 3:
        return 'verde'
    }
  }

  transformarColorANumero(num)
  {
    switch (num) {
      case 'celeste':
        return 0;
      case 'violeta':
        return 1;
      case 'naranja':
        return 2;
      case 'verde':
        return 3
    }
  }

  iluminarSecuencia()
  {
    for(let i = 0; i < this.nivel; i++)
    {
      const color = this.transformarNumeroAColor(this.secuencia[i]);
      setTimeout(() => this.iluminarColor(color), 1000 * i);
    }
  }

  iluminarColor(color)
  {
    this.colores[color].classList.add('light');
    setTimeout(() => this.apagarColor(color), 350);
  }

  apagarColor(color)
  {
    this.colores[color].classList.remove('light');
  }

  agregarEventosClick()
  {
    this.colores.celeste.addEventListener('click', this.elegirColor);
    this.colores.violeta.addEventListener('click', this.elegirColor);
    this.colores.naranja.addEventListener('click', this.elegirColor);
    this.colores.verde.addEventListener('click', this.elegirColor);
  }

  eliminarEventosClick()
  {
    this.colores.celeste.removeEventListener('click', this.elegirColor);
    this.colores.violeta.removeEventListener('click', this.elegirColor);
    this.colores.naranja.removeEventListener('click', this.elegirColor);
    this.colores.verde.removeEventListener('click', this.elegirColor);
  }

  elegirColor(ev)
  {
    const nombreColor = ev.target.dataset.color;
    const numeroColor = this.transformarColorANumero(nombreColor);
    this.iluminarColor(nombreColor);
    if(numeroColor === this.secuencia[this.subnivel])
    {

      this.subnivel++;
      if(this.subnivel === this.nivel)
      {
        this.nivel++;
        this.eliminarEventosClick();
        if(this.nivel === (ULTIMO_NIVEL + 1))
        {
          // gano!
          this.ganoElJuego();
          this.toggleBtnEmpezar();
        }
        else 
        {
          setTimeout(this.siguienteNivel.bind(this), 1500);
        }
      }
    }
    else 
    {
      // perdio
      this.perdioElJuego();
      this.toggleBtnEmpezar();
    }
  }

  ganoElJuego()
  {
    Swal.fire({
      type: 'success',
      title: 'Ganaste!',
      showConfirmButton: false,
      timer: 1500
    })
  }

  perdioElJuego()
  {
    Swal.fire({
      type: 'error',
      title: 'Perdiste!',
      showConfirmButton: false,
      timer: 1500
    })
  }
}






function empezarJuego() 
{
  window.juego = new Juego();
}

btnEmpezar.addEventListener('click', empezarJuego);```

La función de toggleBtn no es necesaria, tampoco realizar una comprobación. Existe un método llamado toggle(), el cual, si no tiene algo, lo añade, y si lo tiene, lo elimina, en este caso las clases.
de la siguiente manera:
btnEmpezar.classList.toggle(‘hide’)

Felicitaciones a todos compañeros por sus proyectos. Están todos cool.

Les comparto como quedo mi juego, le agregue una clase aparte que gestiona los mensajes, inicio de juego, siguiente nivel, game over. y la clase del juego extiende de esta, ademas de usar funciones asyncronas, espero que les guste.
Proyecto en github
Demo

Este es mi juego final
Gracias a los repositorios de estos compañeros me pude basar en ellos para mejroar mi juego.

Imagenes, colores y sonido:
https://github.com/pablojorgeandres/simonSays/blob/master/index.html
https://pablojorgeandres.github.io/simonSays/

Interfas, sombras y diseño
https://github.com/matias4205/Platzi/blob/master/index.html
https://matias4205.github.io/Platzi/

Haciendo esta pequeña modificación en el css, podemos hacer que al pasar el raton por encima de los colores, el cursor cambie a una mano dando la sensación de que este es un elemento al que se le puede dar clic… no es el super truco pero pienso que mejora la experiencia de usuario.

.color {
width: 50%;
height: 50%;
display: inline-block;
** cursor: pointer;**
}

Mis cambios fueron subirle la dificultad conforme se sube de nivel al acortar los tiempos de iluminacion y apagado de colores, poner efectos de sonido cuando se pulsa un boton y poner efectos de sonido cuando el usuario gana o pierde. Tambien genere mensajes aleatorios cada vez que el usuario pulsa de manera correcta el color correspondiente.

Asi mismo, utilice materialize de google para ostrar los mensajes como Toasts.

Apliqué los conocimientos de este curso para hacer un juego de navegador de piedra, papel o tijera.
Piedra, Papel o Tijera

Antes de iniciar el proyecto, yo intente hacerlo por mi cuenta y este fue el resultado, sin embargo tuve complicaciones en la cuestión de remover los eventos y con el curso lo pude solucionar con el bind() https://codepen.io/luisamalaver/pen/mddpjKz?editors=1010

My versión del juego.

El ver aqui
códigocode

Excelente curso, abajo como deje el juego:

CodePen

Les dejo mi versión del Juego, espero les guste, en la app encontraran el link del repo.

¿soy el único que ahora después del curso leo los comentarios con acento argentino? sos re troll vite
Ahora en serio, me gustó mucho el curso, sufrí armando el juego porque se guía a cómo hacer el juego pero no se explica por qué se están haciendo las cosas, pero esto me incentivó a averiguar más por mi cuenta, lo que conlleva a aprender más 😁 ¡mil gracias Sacha! ¿Ahora cómo me quito lo de leer los comentario con acento argentino? ¡Jajaja!

https://gregoryinnovo.github.io/game1.html agregando un poco de animación para “darle” más dificultad.

Les comparto mi proyecto:

http://www.aryrosvall.com/SimonSays/SimonSays.html

Agregué animación, sweet alert 2 para elegir los niveles y aceleré las secuencias conforme pasan los niveles para que se vuelva más difícil. Aún le falta mucho estilo pero me sigo con el curso de frontend para ver qué más implemento.

Saludos

Aqui les dejo mi proyecto

Proyecto ----> https://matias4205.github.io/Platzi/
Codigo fuente ----> https://github.com/matias4205/Platzi

Aparte de la puntuación agregue una penalización si decides repetir la secuencia de colores donde si aciertas ganaras menos puntos.
Link

Les comparto mi avance
https://github.com/Alver23/simon-dice-game y el repositorio por si quiere verlo https://github.com/Alver23/simon-dice-game

El método:

toggleBtnEmpezar() {
	if(btnEmpezar.classList.contains('hide')) {
		btnEmpezar.classList.remove('hide')
	} else {
		btnEmpezar.classList.add('hide')
	}
}

Se puede sustituir por:

btnEmpezar.classList.toggle('hide')

He aprendido mucho, y creo que esto debe ser constante porque entre más se aprende, más uno se da cuenta cuánto no sabe… 😄

Hola, dejo a disposición mi repositorio con el Juego de simón, además aquí podrán encontrar el código fuente. Le agregue cosas como la cantidad de vidas. el tiempo de juego, el nombre del jugador y algunos cambios en la interfaz, espero a alguien le sea de utilidad.

Excelente lo de .bind(this) muy útil!! Algunos puntos que no se tocaron durante las clases anteriores pero fueron muy importantes para el proyecto (como el bind). Bien explicado.

class Juego {
        constructor() {
          this.inicializar = this.inicializar.bind(this)
          this.inicializar()
          this.generarSecuencia()
          setTimeout(this.siguienteNivel(), 500)
        }

        //Esos se conocen como “método de la clase”. 
        //Un método de una clase no es más que una función que se encarga de ejecutar un comportamiento propio de la misma clase

        inicializar() {
          // Se ata el this 
          this.elegirColor = this.elegirColor.bind(this)
          this.siguienteNivel = this.siguienteNivel.bind(this)
          //Esconde el boton al iniciar el juego por medio de agregar la clase 'hide'
          this.toggleBtnEmpezar()
          // Contador de nivel
          this.nivel = 1
          // Se definen los colores en un objeto
          this.colores = {
            //Lo mismo que decir celeste = celeste,
            celeste,
            violeta,
            naranja,
            verde
          }
        }

        toggleBtnEmpezar(){
          if (btnEmpezar.classList.contains('hide')){
            btnEmpezar.classList.remove('hide')
          } else {
            btnEmpezar.classList.add('hide')
          }
        }

        // Generar de forma aleatoria la secuencia en un array
        generarSecuencia(){
          this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
          // Se crea el array segun el nivel, con el fill(se inicializa en 0)
          // con el map se modifica los valores del array Y se obtiene un numero aleatorio entre el 0 y 3
        }

          // Metodo que se encargara de activar la iluminacion de los colores
        siguienteNivel(){
          // Estructura para agregar atributo -> this.nombreAtributo = 'valor'
          this.numeroDeAciertos = 0
          this.iluminarSecuencia()
          this.agregarEventosClick()
          //Va a detectar que oprime el usuario, el input
        }

        transformarNumeroAColor(numero){
        switch(numero){
         case 0:
          return 'celeste'
        case 1:
          return 'violeta'
        case 2:
          return 'naranja'
        case 3:
          return 'verde'
          }
        }

        transformarColorANumero(color){
        switch(color){
         case 'celeste':
          return 0
        case 'violeta':
          return 1
        case 'naranja':
          return 2
        case 'verde':
          return 3
          }
        }

        // se arma un curso que se encargara de iluminar los colores segun el nivel
        // es decir, si el nivel 1, entonces solo se recorrera una sola vez y solo encedera un color, si es nivel 2
        // seran 2 colores los que se encenderan.

        iluminarSecuencia(){
          for (let i = 0;  i< this.nivel; i++){
            const color = this.transformarNumeroAColor(this.secuencia[i])
            //Se declara const y let para evitar que se pise el codigo y no permita editar el color
            //this.secuencia[i] porque es un array propio
            setTimeout(() => this.iluminarColor(color), 1000 * i)
            //Se establece un setTimeout para evitar que se muestre todo muy rapido
          }
        }

        iluminarColor(color){
          this.colores[color].classList.add('light')
          setTimeout(() => this.apagarcolor(color), 350)
        }

        apagarcolor(color){
          this.colores[color].classList.remove('light')
        }
        agregarEventosClick(){
          
          this.colores.celeste.addEventListener('click', this.elegirColor)
          this.colores.verde.addEventListener('click', this.elegirColor)
          this.colores.violeta.addEventListener('click', this.elegirColor)
          this.colores.naranja.addEventListener('click', this.elegirColor)        
        }

        eliminarEventosClick(){
          this.colores.celeste.removeEventListener('click', this.elegirColor)
          this.colores.verde.removeEventListener('click', this.elegirColor)
          this.colores.violeta.removeEventListener('click', this.elegirColor)
          this.colores.naranja.removeEventListener('click', this.elegirColor)        
        }

        elegirColor(ev){

         //Aqui obtenemos el color eligio el usuario
         // el target.dataset.color lo que hace es traer el valor que se encuentra en el data del xml,

          const nombreColor = ev.target.dataset.color

          // En vez de crear otro metodo que traide de string el id, la logica
          // del juego es que siempre validaremos que el usuario acierte los colores
          // segun el orden presentado, por lo que ese orden ya lo tenemos asi que lo que
          // haremos es obtener el nombre de la secuencia y compararlo con el presionado
          // por el jugador y si es igual, aunmentar de nivel y resetear
    
          const numeroColor = this.transformarColorANumero(nombreColor)
          this.iluminarColor(nombreColor)
          //Secuencia segun el subnivel en el que vaya en el Array
          if (numeroColor === this.secuencia[this.numeroDeAciertos]){
            this.numeroDeAciertos++
            if (this.numeroDeAciertos === this.nivel){
              this.nivel++
              this.eliminarEventosClick()
              if (this.nivel === (ULTIMO_NIVEL + 1)){
                //Ganó
                this.ganoElJuego()
              } else {
                //No se debe invocar la funcion, se hace referencia unicamente
                setTimeout(this.siguienteNivel, 1500)
              }
            }
          } else {
            //Perdió
            this.perdioElJuego()
          }
        }
        ganoElJuego(){
          swal('Platzi', 'Felicitaciones, ganaste el juego!','success')
          .then(() => {
            this.inicializar()
          })
        }
        perdioElJuego(){
          swal('Platzi', '¡Lo siento, Perdiste!','error')
          .then(() => {
            this.eliminarEventosClick()
            this.inicializar()
          })
        }
      }

      function empezarJuego() {
        window.juego = new Juego()
      }

Dejo el link para que prueben para jugar un rato:
Simon Game
Si quieren hostear sus juego se puede con GitHub aca les dejo como hacerlo:
https://guides.github.com/features/pages/

Genial! Aún siento que me falta camino por recorrer en el mundo del desarrollo, pero poco a poco es que se va dando todo, me gustó el proceso, solo que necesito reforzar los conocimientos adquiridos en este curso con la práctica.

A nadie le pasó que cuando comienzan un nuevo juego luego de perder o ganar, apretando el botón de empezar sin refrescar la página ese juego falla? Tocas el primer boton iluminado y dice que perdiste, creo que no genera una nueva secuencia o no se actualiza la funcion de iluminar.

Link para el sweet alert:
https://cdnjs.com/libraries/sweetalert

Hola, les dejo mi resultado
Saludos!
https://prueba.carlosarturomt.com/fundamentosJS/index

https://nazarenoalt.github.io/simon-dice/
Esta es una version mejorada con CSS, proximamente voy a expandirla para cambiar su formato 8)

El juego tiene un bug y es que puedes ir clicando los botones a medida que la computadora los va encendiendo para que los recuerdes jaja, pero para fines prácticos está bien:D!


Hice lo que dijo primero: agregué la librería y luego el swal, solo eso y ya no me ejecuta el programa, me da ese error. Me ayudan? Gracias!!

Quise codear todo desde cero implementando mi propia logica. 😃

  • Le agregue un contador.
  • Seccion de mensaje.
  • Mostrador de nivel.

https://7german7.github.io/simon_says/

El juego tiene un bug y es que puedes ir clicando los botones a medida que la computadora los va encendiendo para que los recuerdes jaja, pero para fines prácticos está bien:D!

muy bueno el proyecto, genial para ver como se aplican tantossssss conceptos, sigo sin asimilarlo, pero lo vere varias veces mientras lo hago, estoy trabajando en adaptarlo para mis hijos y que sean animalitos por ejemplo con sonidos cuando se clicke, cuando lo tenga lo comparto aca, muchas gracias profesor

https://erickleaopm.github.io/simonsays/

Modifique los colores del juego, así como su visualización en diferentes dispositivos, agregue el nivel actual del juego y un poco de animaciones para darle más vida.

Que genial curso! aunque tengo que repasarlo porque varias cosas me quedaron con duda

Les comparto el pen de este proyecto en mi perfil de CodePen. Gracias Sasha y Platzi por tan excelente curso.

Creo que le falto agregar una funcion para que el usuario no pueda interactuar con la pagina con hasta que la la funcion y libreria externa no cargue, vivo en vzla y la latencia del internet es notable. Si interactuo con la pagina antes de que todo este cargado me encuntro con errores.
Aqui un buen tutorial para agregar loading screens
https://www.youtube.com/watch?v=EA27xM71m0g

Un aporte pequeño. classList tiene un metodo toggle nativo

ganoElJuego() {
        Swal.fire(
            'Platzi',
            'Felicidades, ganaste el juego',
            'success'
        ).then(() => {
            // Volver a inicializar nuevamente el juego (mostrando el boton de jugar)
            btnEmpezar.classList.toggle('hide')
        })
    }
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Simon Dice</title>
  <style>
    body {
      margin: 0;
      background: #F8F8F8;
      display: flex;
      align-items: center;
      height: 100vh;
    }

    .gameboard {
      height: 100vh;
      width: 100vh;
      border: 2px solid rgba(10, 10, 10, 0.178);
      border-radius: 50%;
      overflow: hidden;
      margin: 0 auto;
      max-height: 60vh;
      max-width: 60vh;
    }

    .color {
      width: 50%;
      height: 50%;
      display: inline-block;
    }

    .left {
      float: left;
    }

    .right {
      float: left;
    }

    .celeste {
      background: #2FB9B6;
    }

    .celeste.light {
      background: rgb(120, 231, 229);
    }

    .violeta {
      background: #F84A6A;
    }

    .violeta.light {
      background: rgb(236, 152, 167);
    }

    .naranja {
      background: #FCB262;
    }

    .naranja.light {
      background: rgb(243, 214, 184);
    }

    .verde {
      background: #09B02B;
    }

    .verde.light {
      background: rgb(84, 235, 114);
    }

    .btn-start {
      width: 300px;
      height: 50px;
      border: 1px solid black;
      background: #ecf0f1;
      color: #2c3e50;
      font-size: 1.2rem;
      position: absolute;
      top: calc(50% - 50px);
      left: calc(50% - 90px);
    }

    .hide {
      display: none;
    }

    * {
      font-family: Arial, Helvetica, sans-serif;
    }

    .puntaje {
      margin-left: 5px;
      font-weight: bold;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }

</style>
</head>

<body cz-shortcut-listen="true">
  <div id="puntaje" class="puntaje">Puntaje Actual: 0</div>
  <div class="gameboard">
    <div id="celeste" class="color celeste left" data-color="celeste"></div>
    <div id="violeta" class="color violeta right" data-color="violeta"></div>
    <div id="naranja" class="color naranja left" data-color="naranja"></div>
    <div id="verde" class="color verde right" data-color="verde"></div>
    <button id="btnEmpezar" class="btn-start" onclick="empezarJuego()">Empezar a jugar!</button>
    <button id="btnReglas" class="btn-start" style='margin-top: 50px' onclick="showRules()">Reglas del Juego</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js"></script>
  <script>
    const celeste = document.getElementById('celeste');
    const violeta = document.getElementById('violeta');
    const naranja = document.getElementById('naranja');
    const verde = document.getElementById('verde');
    const btnEmpezar = document.getElementById('btnEmpezar');
    const btnReglas = document.getElementById('btnReglas');
    const contador = document.getElementById('puntaje');
    const ULTIMO_NIVEL = 10;

    class Juego {
      constructor() {
        this.inicializar = this.inicializar.bind(this);
        this.inicializar();
        this.generarSecuencia();
        setTimeout(this.siguienteNivel, 500);
      }

      inicializar() {
        this.siguienteNivel = this.siguienteNivel.bind(this);
        this.elegirColor = this.elegirColor.bind(this);
        this.toggleBtnEmpezar();
        this.nivel = 1;
        contador.innerHTML = `Puntaje Actual: 0`;
        this.colores = {
          celeste,
          violeta,
          naranja,
          verde
        };
      }

      toggleBtnEmpezar() {
        if (btnEmpezar.classList.contains('hide')) {
          btnEmpezar.classList.remove('hide');
          btnReglas.classList.remove('hide');
        } else {
          btnEmpezar.classList.add('hide');
          btnReglas.classList.add('hide');
        }
      }

      generarSecuencia() {
        this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4));
        console.table(`La secuencia generada es: ${this.secuencia}`);
      }

      siguienteNivel() {
        this.subnivel = 0;
        this.iluminarSecuencia();
        this.agregarEventosClick();
      }

      transformarNumeroAColor(numero) {
        switch (numero) {
          case 0:
            return 'celeste'
          case 1:
            return 'violeta'
          case 2:
            return 'naranja'
          case 3:
            return 'verde'
        }
      }

      transformarColorANumero(color) {
        switch (color) {
          case 'celeste':
            return 0
          case 'violeta':
            return 1
          case 'naranja':
            return 2
          case 'verde':
            return 3
        }
      }

      iluminarSecuencia() {
        for (let i = 0; i < this.nivel; i++) {
          const color = this.transformarNumeroAColor(this.secuencia[i]);
          setTimeout(() => this.iluminarColor(color), 1000 * i);
        }
      }

      iluminarColor(color) {
        this.colores[color].classList.add('light');
        setTimeout(() => this.apagarColor(color), 350);
      }

      apagarColor(color) {
        this.colores[color].classList.remove('light');
      }

      agregarEventosClick() {
        this.colores.celeste.addEventListener('click', this.elegirColor);
        this.colores.verde.addEventListener('click', this.elegirColor);
        this.colores.violeta.addEventListener('click', this.elegirColor);
        this.colores.naranja.addEventListener('click', this.elegirColor);
      }

      eliminarEventosClick() {
        this.colores.celeste.removeEventListener('click', this.elegirColor);
        this.colores.verde.removeEventListener('click', this.elegirColor);
        this.colores.violeta.removeEventListener('click', this.elegirColor);
        this.colores.naranja.removeEventListener('click', this.elegirColor);
      }

      elegirColor(ev) {
        const nombreColor = ev.target.dataset.color;
        const numeroColor = this.transformarColorANumero(nombreColor);
        this.iluminarColor(nombreColor);
        if (numeroColor === this.secuencia[this.subnivel]) {
          this.subnivel++;
          contador.innerHTML = `Puntaje Actual: ${this.subnivel * 1000}`;
          if (this.subnivel === this.nivel) {
            this.nivel++;
            contador.innerHTML = `Puntaje Actual: ${this.subnivel * 1000}`;
            this.eliminarEventosClick();
            if (this.nivel === (ULTIMO_NIVEL + 1)) {
              this.ganoElJuego();
            } else {
              setTimeout(this.siguienteNivel, 1500);
            }
          }
        } else {
          this.perdioElJuego();
        }
      }

      ganoElJuego() {
        swal('Ganaste!', 'Felicitaciones, ganaste el juego!', 'success')
          .then(this.inicializar);
      }

      perdioElJuego() {
        swal('Perdiste!', 'Oops, esta vez te tocó perder. Intentalo nuevamente!', 'error')
          .then(() => {
            this.eliminarEventosClick();
            this.inicializar();
          })
      }

    }

    function empezarJuego() {
      window.juego = new Juego();
    }

    function showRules() {
      swal({
        title: 'Reglas del juego',
        text: 'Cada color se iluminará siguiendo una secuencia generada al azar. Haz click en cada color en el orden correcto y completa la secuencia en su totalidad para ganar. \n \n Ojo! si tocas el color incorrecto deberas comenzar de cero.',
        icon: 'info',
        button: {
          text: 'Entendido',
          closeModal: true,
        }
      });
    }
  </script>

</body>

</html>

Hola, Gracias Sacha.
Aquí Mi Proyecto:

Excelente curso, les dejo el link de mi PenCode donde subí una versión que muestra el nivel además de reproducir un sonido cada vez que se ilumina un botón.

CodePen - Simon dice

Hola, me aparece el siguiente mensaje de error en la consola:

Uncaught TypeError: this.iluminarSecuencia is not a function
    at siguienteNivel (clase42 - comenzando el juego.html:144)

Y realmente no sé por qué; según entiendo el mensaje de error me dice que this.iluminarSecuencia no es una función en siguienteNivel; entonces agregue un console.log(this) en la función siguienteNivel y la consola me muestra que this es window en esa función, entonces supongo que como allí this es window, cuando se manda llamar this.iluminarSecuencia busca esa función en el objeto window (lo cual es correcto que no existe); sin embargo, trato de “atar” el this al objeto juego agregando la siguiente línea de código al constructor o a la función inicializar y en ninguno de los casos funciona, la línea que agrego es:

this.iluminarSecuencia = this.iluminarSecuencia.bind(this)

Mi código completo es este:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Simon Dice</title>
    <style>
      body {
        margin: 0;
        background: #dedede;
        display: flex;
        align-items: center;
        height: 100vh;
      }

      .gameboard {
        height: 100vh;
        width: 100vh;
        border-radius: 50%;
        overflow: hidden;
        margin: 0 auto;
        max-height: 60vh;
        max-width: 60vh;
      }

      .color {
        width: 50%;
        height: 50%;
        display: inline-block;
      }

      .left {
        float: left;
      }

      .right {
        float: left;
      }

      .celeste {
        background: #22a6b3;
      }

      .celeste.light {
        background: #7ed6df;
      }

      .violeta {
        background: #be2edd;
      }

      .violeta.light {
        background: #e056fd;
      }

      .naranja {
        background: #f0932b;
      }

      .naranja.light {
        background: #ffbe76;
      }

      .verde {
        background: #6ab04c;
      }

      .verde.light {
        background: #badc58;
      }

      .btn-start {
        width: 400px;
        height: 100px;
        background: #ecf0f1;
        color: #2c3e50;
        font-size: 2.5rem;
        position: absolute;
        top: calc(50% - 50px);
        left: calc(50% - 200px);
      }

      .hide {
        display: none;
      }

      * {
        font-family: Arial, Helvetica, sans-serif;
      }
    </style>
  </head>
  <body>
    <div class="gameboard">
      <div id="celeste" class="color celeste left" data-color="celeste"></div>
      <div id="violeta" class="color violeta right" data-color="violeta"></div>
      <div id="naranja" class="color naranja left" data-color="naranja"></div>
      <div id="verde" class="color verde right" data-color="verde"></div>
      <button id="btnEmpezar" class="btn-start" onclick="empezarJuego()">Empezar a jugar!</button>
    </div>
    <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
    <script>
      const celeste = document.getElementById('celeste')
      const violeta = document.getElementById('violeta')
      const naranja = document.getElementById('naranja')
      const verde = document.getElementById('verde')
      const btnEmpezar = document.getElementById('btnEmpezar')
      const ULTIMO_NIVEL = 10

      class Juego {
        
        constructor() {
          this.inicializar = this.inicializar.bind(this)
          this.inicializar()
          this.generarSecuencia()
          setTimeout(this.siguienteNivel, 500)
        }

        inicializar() {
          this.siguientenivel = this.siguienteNivel.bind(this)
          this.elegirColor = this.elegirColor.bind(this)
          this.toogleBtnEmpezar()
          this.nivel = 1
          this.colores = {
            celeste,
            violeta,
            naranja,
            verde
          }
        }
        
        toogleBtnEmpezar() {
          if(btnEmpezar.classList.contains('hide')) {
            btnEmpezar.classList.remove('hide')
          } else {
            btnEmpezar.classList.add('hide')
          }
        }
        
        generarSecuencia() {
          this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
        }
        
        siguienteNivel() {
          console.log(this)
          this.subnivel = 0
          this.iluminarSecuencia()
          this.agregarEventosClick()
        }
        
        transformarNumeroAColor(numero) {
          switch(numero) {
            case 0:
              return 'celeste'
            case 1:
              return 'violeta'
            case 2:
              return 'naranja'
            case 3:
              return 'verde'
          }
        }
        
        transformarColorANumero(color) {
          switch(color) {
            case 'celeste':
              return 0
            case 'violeta':
              return 1
            case 'naranja':
              return 2
            case 'verde':
              return 3
          }
        }
        
        iluminarSecuencia() {
          for(let i = 0; i < this.nivel; i++) {
            const color = this.transformarNumeroAColor(this.secuencia[i])
            setTimeout(() => this.iluminarColor(color), 1000 * i)
          }
        }
       
        iluminarColor(color) {
          this.colores[color].classList.add('light')
          setTimeout(() => this.apagarColor(color), 350)
        }
        
        apagarColor(color) {
          this.colores[color].classList.remove('light')
        }
        
        agregarEventosClick() {
          this.colores.celeste.addEventListener('click', this.elegirColor)
          this.colores.violeta.addEventListener('click', this.elegirColor)
          this.colores.naranja.addEventListener('click', this.elegirColor)
          this.colores.verde.addEventListener('click', this.elegirColor)
        }
        
        eliminarEventosClick() {
          this.colores.celeste.removeEventListener('click', this.elegirColor)
          this.colores.violeta.removeEventListener('click', this.elegirColor)
          this.colores.naranja.removeEventListener('click', this.elegirColor)
          this.colores.verde.removeEventListener('click', this.elegirColor)
        }
        
        elegirColor(ev) {
          const nombreColor = ev.target.dataset.color
          const numeroColor = this.transformarColorANumero(nombreColor)
          this.iluminarColor(nombreColor)
          if(numeroColor === this.secuencia[this.subnivel]) {
            this.subnivel++
            if(this.subnivel === this.nivel) {
              this.nivel++
              this.eliminarEventosClick()
              if(this.nivel === (ULTIMO_NIVEL + 1)) {
                this.ganoElJuego()
              } else {
                setTimeout(this.siguienteNivel, 1500)
              }
            }
          } else {
            this.perdioElJuego()
          }
        }
        
        ganoElJuego() {
          swal('Platzi', 'Felicitaciones, ganaste el juego!', 'success')
            .then(this.inicializar)
        }
        
        perdioElJuego() {
          swal('Platzi', 'Lo lamentamos, perdiste :(', 'error')
            .then(() => {
              this.eliminarEventosClick()
              this.inicializar()
            })
        }
      
      }

      function empezarJuego() {
        window.juego = new Juego()
      }
    
    </script>
  </body>
</html>

A alguien le paso que después del primer nivel el juego, cuando uno selecciona el color sale el mensaje de que perdió? Haciendo el debug me dice que las funciones no están definidas. Creo que es porque pierde el this, pero ya lo tengo con bind. No se como hacer! He validado vs los códigos que han publicado y no veo nada diferente!

Muy interesante, la verdad que tengo que estudiar mucho… me es todo nuevo pero la practica hace al maestro

JavaScript ya contiene una clase toggle por default:
ejemplo

var element = document.getElementById(“myDIV”);
element.classList.toggle(“mystyle”);

Mucas gracias, aprendi demasiado con el desarrollo del juego!!!1
Hya temas que falta reforzar pero se que mi comprensión mejoro bastante.!!!

https://github.com/FapCod/simondicegame
ese el codigo para que lo descarguen y lo jueguen en mi github

Para los que quieran el juego online, aqui les dejo el link, ignoren el nombre xd https://symphony701.github.io/Juego_del_chinfony/

Estoy super contento con lo que se realizo en el curso un juego que aunque se ve sencillo es bastante divertido y aprendí mucho 😄

https://sweetalert2.github.io/#download

<script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>

Uso:

        swal.fire('SimonDice','Felicitaciones, ganaste el juego!', 'success')
            .then(this.inicializar)
https://cdnjs.cloudflare.com/ajax/libs/sweetalert/2.1.2/sweetalert.min.js
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Simon Dice - Agregando los estados finales del juego</title>
    <style>
      body {
        margin: 0;
        background: #dedede;
        display: flex;
        align-items: center;
        height: 100vh;
      }

      .gameboard {
        height: 100vh;
        width: 100vh;
        border-radius: 50%;
        overflow: hidden;
        margin: 0 auto;
        max-height: 60vh;
        max-width: 60vh;
      }

      .color {
        width: 50%;
        height: 50%;
        display: inline-block;
      }

      .left {
        float: left;
      }

      .right {
        float: left;
      }

      .celeste {
        background: #22a6b3;
      }

      .celeste.light {
        background: #7ed6df;
      }

      .violeta {
        background: #be2edd;
      }

      .violeta.light {
        background: #e056fd;
      }

      .naranja {
        background: #f0932b;
      }

      .naranja.light {
        background: #ffbe76;
      }

      .verde {
        background: #6ab04c;
      }

      .verde.light {
        background: #badc58;
      }

      .btn-start {
        width: 400px;
        height: 100px;
        background: #ecf0f1;
        color: #2c3e50;
        font-size: 2.5rem;
        position: absolute;
        top: calc(50% - 50px);
        left: calc(50% - 200px);
      }

      .hide {
        display: none;
      }

      * {
          font-family: 'Arial';
      }
    </style>
  </head>
  <body>
    <div class="gameboard">
      <div id="celeste" class="color celeste left" data-color="celeste"></div>
      <div id="violeta" class="color violeta right" data-color="violeta"></div>
      <div id="naranja" class="color naranja left" data-color="naranja"></div>
      <div id="verde" class="color verde right" data-color="verde"></div>
      <button id="btnEmpezar" class="btn-start" onclick="empezarJuego()">Empezar a jugar!</button>
    </div>
    <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
    <script>
        const celeste = document.getElementById('celeste')
        const violeta = document.getElementById('violeta')
        const naranja = document.getElementById('naranja')
        const verde = document.getElementById('verde')
        const btnEmpezar = document.getElementById('btnEmpezar')
        const ULTIMO_NIVEL = 10

        class Juego {
            constructor() {
                this.inicializar = this.inicializar.bind(this)
                this.inicializar()
                this.generarSecuencia()
                setTimeout(this.siguienteNivel, 500)
                
            }

            inicializar() {
                this.siguienteNivel = this.siguienteNivel.bind(this)
                this.elegirColor = this.elegirColor.bind(this)
                this.toggleBtnEmpezar()
                this.nivel = 1
                this.colores = {
                    celeste,
                    violeta,
                    naranja,
                    verde
                }
            }

            toggleBtnEmpezar() {
                if (btnEmpezar.classList.contains('hide')) {
                    btnEmpezar.classList.remove('hide')
                } else {
                    btnEmpezar.classList.add('hide')
                }
            }

            generarSecuencia() {
                this.secuencia = new Array(ULTIMO_NIVEL).fill(0).map(n => Math.floor(Math.random() * 4))
            }

            siguienteNivel() {
                this.subnivel = 0
                this.iluminarSecuencia()
                this.agregarEventosClick()
            }

            transformarNumeroAColor(numero) {
                switch (numero) {
                    case 0:
                        return 'celeste'
                    case 1:
                        return 'violeta'
                    case 2:
                        return 'naranja'
                    case 3:
                        return 'verde'
                }
            }

            transformarColorANumero(color) {
                switch (color) {
                    case 'celeste':
                        return 0
                    case 'violeta':
                        return 1
                    case 'naranja':
                        return 2
                    case 'verde':
                        return 3
                }
            }

            iluminarSecuencia() {
                for (let i = 0; i < this.nivel; i++) {
                    const color = this.transformarNumeroAColor(this.secuencia[i])
                    setTimeout(() => this.iluminarColor(color), 1000 * i)
                }
            }

            iluminarColor(color) {
                this.colores[color].classList.add('light')
                setTimeout(() => this.apagarColor(color), 350)
            }

            apagarColor(color) {
                this.colores[color].classList.remove('light')
            }

            agregarEventosClick() {
                this.colores.celeste.addEventListener('click', this.elegirColor)
                this.colores.violeta.addEventListener('click', this.elegirColor)
                this.colores.naranja.addEventListener('click', this.elegirColor)
                this.colores.verde.addEventListener('click', this.elegirColor)
            }

            eliminarEventosClick() {
                this.colores.celeste.removeEventListener('click', this.elegirColor)
                this.colores.violeta.removeEventListener('click', this.elegirColor)
                this.colores.naranja.removeEventListener('click', this.elegirColor)
                this.colores.verde.removeEventListener('click', this.elegirColor)
            }

            elegirColor(ev) {
                const nombreColor = ev.target.dataset.color
                const numeroColor = this.transformarColorANumero(nombreColor)
                this.iluminarColor(nombreColor)
                if (numeroColor === this.secuencia[this.subnivel]) {
                    this.subnivel++
                    if (this.subnivel === this.nivel) {
                        this.nivel++
                        this.eliminarEventosClick()
                        if (this.nivel === (ULTIMO_NIVEL + 1)) {
                            this.ganoElJuego()
                        } else {
                            setTimeout(this.siguienteNivel, 1500) 
                        }
                    }
                } else {
                    this.perdioElJuego()
                }
            }

            ganoElJuego() {
                swal(`Ganaste! tu nivel es ${this.nivel}`, 'Dale click en el boton OK', 'success')
                    .then(this.inicializar)
            }

            perdioElJuego() {
                swal(`Perdiste! llegaste hasta el nivel ${this.nivel}`, 'Dale click en el boton OK', 'error')
                    .then(() => {
                        this.eliminarEventosClick()
                        this.inicializar()
                    })
            }

        }

      function empezarJuego() {
        var juego = new Juego()
      }
    </script>
  </body>
</html>

Les comparto mi versión del juego:
https://github.com/CristMorAr/SimonDice.git

Agradecería que me dijerán que mejorarían. Gracias!.

tambien se puede hacer así
btn.classList.toggle(‘hide’);

Les dejo link para los que no finalizaron el juego
Los invito a hacer un fork del proyecto y mejorar lo que deseen
https://github.com/JuanManuelOyarzunDev/Fundamentos-JS.git