El mejor calendario para seguir la F1 2022

https://www.marca.com/motor/formula1/calendario.html

Próximas carreras:

GP Australia: 10-04-2022
VIERNES 8
Libres 1: 05:00 Libres 2: 08:00
SÁBADO 9
Libres 3: 05:00 Parrilla: 08:00
DOMINGO 10
Carrera: 07:00

Perico Delgado, Miguel Indurain, Fernando Alonso y Carlos Sainz

Miguel Indurain Tour 1994

Entre 1989 y 1991 toda España tenía esperanzas en que el veterano Perico Delgado ganase su segundo Tour, mientras un joven Miguel Indurain poco a poco iba mejorando sus actuaciones hasta que llegó 1991. Ese año ambos empezaron siendo colíderes de su equipo, el Reynolds pero finalmente Miguel Indurain consiguió su primer Tour de Francia y Perico acabó 9º.

Durante esos años la mayoría se resistía en creer en las posibilidades de ese joven aspirante con un nulo tirón popular, introvertido, y que creció en un segundo plano a la sombra de Perico Delgado. Indurain tuvo que ganar su primer Tour y pasar al primer plano y convertirse en el mejor ciclista español de todos los tiempos.

Fernando Alonso no es Perico Delgado, y Carlos Sainz jr no es Miguel Indurain, pero yo estoy viviendo una sensación parecida a la que viví como niño entre 1989 y 1991, cuando el anhelo por rememorar las celebraciones por los mundiales ganados por Fernando Alonso, puede más que la frialdad de la superioridad de los resultados de Carlos Sainz.

Trail Cabo Huertas

Me gusta el trail running, porque combina el running con la naturaleza. Una de mis rutas preferidas es la del Cabo de las Huertas de Alicante.

Relacionado: La importancia del contacto con la naturaleza

Real artists ship

Real artists ship. Frase de Steve Jobs.

En este blog ya tengo una buena lista de borradores pendientes de completar, y hoy me he acordado de una frase de Steve Jobs: “Real artist ship!”, cuya traducción literal podría ser: “Los artistas de verdad entregan”. Con esta frase Jobs se refiere a la necesidad de llevar a cabo las ideas y transformarlas en productos terminados y listos para enviar, entregar, publicar o vender.

Parece ser que Steve Jobs esta frase cuando quería motivar a sus ingenieros y diseñadores en Apple, y cumplir con las fechas de entrega.

Y es que a veces, es muy fácil irse por las ramas, y no focalizar el trabajo importante. Por eso fijarnos fechas límites (milestones), ayudan a terminar, a cerrar, aquello en lo que estamos trabajando.

Morning pages

blank paper with pen and coffee cup on wood table
Photo by Kaboompics .com on Pexels.com

Morning Pages are three pages of longhand, stream of consciousness writing, done first thing in the morning. *There is no wrong way to do Morning Pages* they are not high art. They are not even “writing.” They are about anything and everything that crosses your mind– and they are for your eyes only. Morning Pages provoke, clarify, comfort, cajole, prioritize and synchronize the day at hand. Do not over-think Morning Pages: just put three pages of anything on the page…and then do three more pages tomorrow.

Julia Cameron

Tal y como lo define Julia Cameron, creadora de esta técnica: Morning Pages o Páginas de la mañana, son tres páginas escritas a mano, un flujo de escritura consciente, hechas al levantarte de la cama. No hay una forma incorrecta de hacerlas, no son arte de alturas. Ni siquiera es “redacción”. Son sobre cualquier cosa o sobre todo lo que se te pase por la mente – y son solo para tus ojos. Morning Pages provoca, clarifica, conforta, camela, prioriza y sincroniza el día a mano. No pienses demasiado Morning Pages: tan solo pon tres páginas de cualquier cosa en la página… y entonces haz tres páginas más mañana.

Personalmente, llevo practicando Morning Pages durante los últimos seis meses, aunque, ni escribo a diario ni escribo tres páginas como indica Julia Cameron. Más bien, escribo cuando puedo, cuando me apetece y lo que me apetece. De alguna forma me ayuda en lo personal, a conectar conmigo mismo, con mis objetivos, con mis inquietudes, problemas y con las cosas buenas que a veces no valoro como se merecen.

También me ayuda a mejorar mi fluidez escritora. Lo cierto, es que en las últimas semanas lo he practicado más a menudo y seguramente me ha ayudado a retomar este blog. Te recomiendo que veas el vídeo de Julia Cameron donde explica ella misma lo que es Morning Pages y que lo pruebes.

Aprende JavaScript con 7 juegos 2/7 – Memory Game

Esta entrada pertenece a la serie ‘Aprende Javascript con 7 juegos‘.

Vamos a implementar un juego de memoria, en el que tenemos que emparejar cartas.

Imágenes

Las imágenes de las cartas las guardamos en una carpeta llamada ‘images’

Ficheros y carpetas

HTML

Creamos el ficher index.html en la carpeta raíz


<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Memory Game</title>
    <link rel="stylesheet" href="style.css"></link>
    <script src="app.js" charset="utf-8"></script>
  </head>
  <body>

    <h3>Score: <span id="result"></span></h3>

    <div class="grid">

    </div>


  </body>
</html>

CSS

Creamos el fichero style.css

.grid {
  width: 400px;
  height: 300px;
  display: flex;
  flex-wrap: wrap;
}

JavaScript

Creamos el fichero app.js

Creamos el fichero app.js con Evento DomContentLoaded

document.addEventListener('DOMContentLoaded', () => {

// pondremos aquí todo nuestro código
  
})

Array de cartas: cardArray

Cada elemento del array tendrá un nombre y la ruta de una imagen

document.addEventListener('DOMContentLoaded', () => {

//card options
  const cardArray = [
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    },
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    }
  ]

})

Ordenamos el array de forma aleatoria

//card options
  const cardArray = [
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    },
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    }
  ]

  // ordenamos el array de forma aleatoria
  cardArray.sort(() => 0.5 - Math.random())

})

Referencias html y arrays

Creamos una referencia al elemento HTML que contiene la cuadrícula donde visualizaremos las cartas, y otra al resultado que visualiza las parejas descubiertas. Además, creamos tres arrays:

  • cardsChosen y cardsChosenId : para almacenar las dos cartas que hemos elegido en cada intento y sus correspondientes identificadores
  • cardsWon : para almacenar las cartas que hemos conseguido emparejar
document.addEventListener('DOMContentLoaded', () => {
  //card options
  const cardArray = [
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    },
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    }
  ]

  cardArray.sort(() => 0.5 - Math.random())

  const grid = document.querySelector('.grid')
  const resultDisplay = document.querySelector('#result')
  let cardsChosen = []
  let cardsChosenId = []
  let cardsWon = []

})

Función para crear el tablero

La función contiene un bucle que añadirá a cada carta:

  • su imagen correspondiente
  • un identificador numérico que corresponde con su posición en el array
  • un ‘Event Listener’ que llamará a una función llamada flipCard
  • la añadirá a la cuadrícula
//create your board
  function createBoard() {
    for (let i = 0; i < cardArray.length; i++) {
      const card = document.createElement('img')
      card.setAttribute('src', 'images/blank.png')
      card.setAttribute('data-id', i)
      card.addEventListener('click', flipCard)
      grid.appendChild(card)
    }
  }

Función para darle la vuelta a una carta

La función flipCard será llamada al hacer click en una de las cartas, por lo que pertenece a la propia carta y podemos utilizar ‘this’ para referirnos a la carta que ha sido clicada y obtener su identificador (cardId) que también indica su posición en el array de cartas.

Añadimos utilizando la función ‘push()’ el nombre y el identificador de la carta elegida en cardsChosen y cardsChosenId. Además, actualizamos el atributo ‘src’ con la imagen de la carta para visualizar la carta elegida.

Por último, si es la segunda carta elegida llamamos a la función checkForMatch que comprobará si las cartas elegidas con pareja. La función setTimeout añade un retardo de 500 milisegundos.

//flip your card
  function flipCard() {
    let cardId = this.getAttribute('data-id')
    cardsChosen.push(cardArray[cardId].name)
    cardsChosenId.push(cardId)
    this.setAttribute('src', cardArray[cardId].img)
    if (cardsChosen.length ===2) {
      setTimeout(checkForMatch, 500)
    }
  }

Función para comprobar una pareja

Primero obtenemos una referencia de todas las cartas del tablero (cards), y para la primera y segunda carta (optionOneId y optionTwoId). Después evaluamos todas las posibilidades:

  • la misma carta seleccionada dos veces (==)
  • pareja de cartas encontrada (===)
  • pareja de cartas no encontrada

En este caso, el operador == devuelve true cuando se compara el mismo objeto, en cambio, === devuelve true cuando los valores de dos objetos diferentes son iguales.

//check for matches
  function checkForMatch() {
    const cards = document.querySelectorAll('img')
    const optionOneId = cardsChosenId[0]
    const optionTwoId = cardsChosenId[1]

    if(optionOneId == optionTwoId) {
      cards[optionOneId].setAttribute('src', 'images/blank.png')
      cards[optionTwoId].setAttribute('src', 'images/blank.png')
      alert('You have clicked the same image!')
    }
    else if (cardsChosen[0] === cardsChosen[1]) {
      alert('You found a match')
      cards[optionOneId].setAttribute('src', 'images/white.png')
      cards[optionTwoId].setAttribute('src', 'images/white.png')
      cards[optionOneId].removeEventListener('click', flipCard)
      cards[optionTwoId].removeEventListener('click', flipCard)
      cardsWon.push(cardsChosen)
    } else {
      cards[optionOneId].setAttribute('src', 'images/blank.png')
      cards[optionTwoId].setAttribute('src', 'images/blank.png')
      alert('Sorry, try again')
    }
    cardsChosen = []
    cardsChosenId = []
    resultDisplay.textContent = cardsWon.length
    if  (cardsWon.length === cardArray.length/2) {
      resultDisplay.textContent = 'Congratulations! You found them all!'
    }
  }

Llamada a la función createBoard

createBoard()

Programa completo

document.addEventListener('DOMContentLoaded', () => {
  //card options
  const cardArray = [
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    },
    {
      name: 'fries',
      img: 'images/fries.png'
    },
    {
      name: 'cheeseburger',
      img: 'images/cheeseburger.png'
    },
    {
      name: 'ice-cream',
      img: 'images/ice-cream.png'
    },
    {
      name: 'pizza',
      img: 'images/pizza.png'
    },
    {
      name: 'milkshake',
      img: 'images/milkshake.png'
    },
    {
      name: 'hotdog',
      img: 'images/hotdog.png'
    }
  ]

  cardArray.sort(() => 0.5 - Math.random())

  const grid = document.querySelector('.grid')
  const resultDisplay = document.querySelector('#result')
  let cardsChosen = []
  let cardsChosenId = []
  let cardsWon = []

  //create your board
  function createBoard() {
    for (let i = 0; i < cardArray.length; i++) {
      const card = document.createElement('img')
      card.setAttribute('src', 'images/blank.png')
      card.setAttribute('data-id', i)
      card.addEventListener('click', flipCard)
      grid.appendChild(card)
    }
  }

  //check for matches
  function checkForMatch() {
    const cards = document.querySelectorAll('img')
    const optionOneId = cardsChosenId[0]
    const optionTwoId = cardsChosenId[1]

    if(optionOneId == optionTwoId) {
      cards[optionOneId].setAttribute('src', 'images/blank.png')
      cards[optionTwoId].setAttribute('src', 'images/blank.png')
      alert('You have clicked the same image!')
    }
    else if (cardsChosen[0] === cardsChosen[1]) {
      alert('You found a match')
      cards[optionOneId].setAttribute('src', 'images/white.png')
      cards[optionTwoId].setAttribute('src', 'images/white.png')
      cards[optionOneId].removeEventListener('click', flipCard)
      cards[optionTwoId].removeEventListener('click', flipCard)
      cardsWon.push(cardsChosen)
    } else {
      cards[optionOneId].setAttribute('src', 'images/blank.png')
      cards[optionTwoId].setAttribute('src', 'images/blank.png')
      alert('Sorry, try again')
    }
    cardsChosen = []
    cardsChosenId = []
    resultDisplay.textContent = cardsWon.length
    if  (cardsWon.length === cardArray.length/2) {
      resultDisplay.textContent = 'Congratulations! You found them all!'
    }
  }

  //flip your card
  function flipCard() {
    let cardId = this.getAttribute('data-id')
    cardsChosen.push(cardArray[cardId].name)
    cardsChosenId.push(cardId)
    this.setAttribute('src', cardArray[cardId].img)
    if (cardsChosen.length ===2) {
      setTimeout(checkForMatch, 500)
    }
  }

  createBoard()
})
A %d blogueros les gusta esto: