Skip to content

Instantly share code, notes, and snippets.

@shiftyp
Last active December 14, 2024 15:48
Show Gist options
  • Save shiftyp/c2a298ce712d8d9c97b3b7d8c9ff20d5 to your computer and use it in GitHub Desktop.
Save shiftyp/c2a298ce712d8d9c97b3b7d8c9ff20d5 to your computer and use it in GitHub Desktop.
holidayconifer.ts
import { Console } from "node:console";
const BALL = '⏺'
const COLOR = {
'blue': '\\033[94m',
'yellow': '\\033[93m',
'cyan': '\\033[96m',
'green': '\\033[92m',
'magenta': '\\033[95m',
'white': '\\033[97m',
'red': '\\033[91m'
}
const STAR = '★'
const getRandomIndexes = (string: string, count: number) => {
const indexes: Record<number, true> = {};
let length = 0
while (length < count) {
const randomIndex = Math.floor(Math.random() * string.length);
if (!indexes[randomIndex]) {
indexes[randomIndex] = true;
}
}
return Object.keys(indexes);
}
const randomChangeChar = (string, count) => {
const indexes = getRandomIndexes(string, count)
const arr = string.split('')
for (const idx in indexes) {
if (arr[idx] === '_') {
arr[idx] = BALL
}
}
return arr.join('')
}
const tree = (height: number = 13, screenWidth: number = 80) => {
const star = [STAR, STAR, STAR, STAR]
if (height % 2 !== 0) {
height += 1
}
const body = ['/_\\', '/_\_\\']
const trunk = '[___]'
const begin = '/'
const end = '\\'
const pattern = '_/'
let j = 5
for (let i = 7; i < height + 1; i += 2) {
let middle = pattern
for (let k = 0; k < i - j; k++) {
middle += pattern
}
let line = [begin, middle.slice(-1), end].join('')
body.push(line)
middle = middle.replace('/', '\\')
line = [begin, middle.slice(-1), end].join('')
body.push(line)
j += 1
}
const ret: string[] = []
for (const line in [...star, ...body, trunk]) {
// center the tree based on screen width
const spaces = ' '.repeat((screenWidth - line.length) / 2)
ret.push(spaces + line)
}
return ret
}
const balls = (tree: string[]) => {
for (let idx = 0; idx < tree.length - 3; idx++) {
tree[idx] = randomChangeChar(tree[idx], tree[idx].length)
}
return tree
}
const coloredStarsBalls = (tree: string[]) => {
for (const idx in tree) {
const string = tree[idx].split('')
for (const pos in string) {
if (string[pos] === STAR) {
string[pos] = [COLOR['yellow'], STAR, '\\033[0m'].join('')
}
else if (string[pos] === BALL) {
string[pos] = [Object.values(COLOR)[Math.random() * Object.values(COLOR).length], BALL, '\\033[0m'].join('')
}
}
tree[idx] = string.join('')
}
return tree
}
const cli = () => {
const {columns, rows} = Deno.consoleSize(Deno.stdout.rid)
const height = rows - 2
const console = new Console(Deno.stdout)
setInterval(() => {
console.clear()
console.log(coloredStarsBalls(balls(tree(height, columns))).join('\n'))
}, 1000)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment