Last active
August 9, 2023 16:07
-
-
Save meltingice/1365c9a469a877b05121d81b0cc4d446 to your computer and use it in GitHub Desktop.
Grail #14
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Utility function for shuffling an array | |
const shuffle = a => a.sort(() => Math.random() - 0.5) | |
// The current day of the week (0 = Sunday, 1 = Monday, etc.) | |
const cId = new Date().getDay() | |
// The set of symbols used for each day of the week | |
const cs = [ | |
['๐ณ', '๐ฆ', '๐ฒ', '๐ฅ'], // Sunday | |
['โฌ๏ธ', '๐น', '๐ฟ', '๐ท'], // Monday | |
['ใฐ๏ธ', '๐', 'โญ๏ธ', '๐ค'], // Tuesday | |
['๐', '๐', '๐', '๐'], // Wednesday | |
['โฌ๏ธ', '๐', '๐ฏ', '๐ญ'], // Thursday | |
['๐', '๐คข', '๐', '๐คฎ'], // Friday | |
['๐ซฅ', '๐', '๐', '๐ฅฐ'], // Saturday | |
] | |
// The set of symbols used for today | |
const c = cs[cId] | |
// The set of possible x/y movements | |
const s = [[0, 1], [0, -1], [1, 0], [-1, 0]] | |
// Grid dimensions and snake length | |
const w = 54, h = 36, l = 24 | |
// Initial position | |
let x = w/2, y = h/2 | |
// The set of coordinates that comprise the snake | |
let p = [[x, y]] | |
// Array of indices into s | |
let d = [0, 1, 2, 3] | |
// Our update function that renders a new iteration of the snake | |
const update = () => { | |
// The x/y movement we will perform | |
let a = [0, 0] | |
// Shuffle the possible movements randomly (roughly 1/3 of the updates) | |
if (Math.random() < 0.318) d = shuffle(d) | |
// For each possible movement | |
for (let i = 0; i < d.length; i++) { | |
// The next x/y positions | |
let tx = x + s[d[i]][0] | |
let ty = y + s[d[i]][1] | |
// Flag for whether the next x/y position is already occupied | |
let u = 0 | |
// For each piece of the snake... | |
for (let j = 0; j < p.length; j++) { | |
// If the next x/y position is already occupied, set the flag | |
if (p[j][0] == tx && p[j][1] == ty) u = 1 | |
} | |
// If the next x/y position is not already occupied, set the next movement | |
if (!u) a = s[d[i]] | |
} | |
// Perform the movement. If u = 1 then this will be [0, 0] and no movement will occur | |
x += a[0] | |
y += a[1] | |
// Wrap around the grid in all directions | |
if (x < 0) x = w-1 | |
if (x >= w) x = 0 | |
if (y < 0) y = h-1 | |
if (y >= h) y = 0 | |
// Add the new position to the snake | |
p.push([x, y]) | |
// If the snake has reached its max length, remove the last position | |
if (p.length > l) p.shift() | |
// The output string | |
let o = '' | |
// For each y position in the grid... | |
for (let j = 0; j < h; j++) { | |
// For each x position in the grid... | |
for (let i = 0; i < w; i++) { | |
// If the current x/y position is the snake's head... | |
if (x == i && y == j) { | |
// If there is no movement in this update, then output the last emoji | |
// in the list, otherwise output the 2nd emoji. | |
o += a[0] == 0 && a[1] == 0 ? c[3] : c[1] | |
} else { | |
// Check if the current x/y position is part of the snake (but not the head) | |
let f = p.find(e => e[0] == i && e[1] == j) | |
// If it is, then output the 3rd emoji, otherwise output the 1st emoji | |
o += f ? c[2] : c[0] | |
} | |
} | |
// Add a newline after each row to create the grid | |
o += '\n' | |
} | |
// Output the grid to the console | |
console.log(o) | |
// Update the page title with the current order of the 4 emojis for today | |
document.title = `${c[d[0]]}${c[d[1]]}${c[d[2]]}${c[d[3]]}` | |
} | |
// Write today's snake emoji's to the page | |
document.getElementById('s').innerText = `${c[1]}${c[2]}` | |
// Create a favicon with today's snake emoji's | |
var link = document.querySelector("link[rel*='icon']") || document.createElement('link'); | |
link.rel = 'icon' | |
link.href = `data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>${c[1]}</text></svg>` | |
document.getElementsByTagName('head')[0].appendChild(link) | |
// Update the snake every 40ms | |
setInterval(update, 40) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment