[Node.js] ターミナルで回転する寿司を作る [Linux]

[Node.js] ターミナルで回転する寿司を作る [Linux]

2022-12-1822 min read

目次

  1. 概要
  2. ターミナルで寿司を降らす
  3. ターミナルで果物を降らす
  4. ターミナルで回転寿司
  5. 参考にさせていただいたサイト

概要

Linuxのターミナル上で回転する寿司を作りました。

発生プログラムターミナル上でフルーツが落下するコードも作りました。

ターミナルで寿司を降らす

元ネタはこちらです。↓

Macのターミナルに寿司を降らせる

rubyで書かれた寿司が落下するコードがありました。 こちらをNode.jsで実装してみます。

const readline = require('readline');
const stdout = process.stdout;

const clear = () => stdout.write('\033[2J');
const print = (s) => stdout.write(s);
const sleep = (m) => new Promise((resolve) => setTimeout(resolve, m));

const sushi = String.fromCodePoint(0x1F363);

const main = async () => {
  const [w, h] = [stdout.columns, stdout.rows];
  const rand = (m) => Math.floor(Math.random() * m);
  const d = h * 3;
  const map = new Map();
  clear();
  while (true) {
    map.set(rand(w), 1);
    clear();
    for (const [x, y] of map) {
      if (y > d) {
        map.delete(x);
        continue;
      }
      map.set(x, y + 1);
      readline.cursorTo(stdout, x, y > h ? h : y);
      print(sushi);
    }
    readline.cursorTo(stdout, w, h);
    await sleep(100);
  }
};

main();

説明

まず、node.jsのreadlineモジュールとstdoutを読み込みます。 readlineモジュールは、ターミナルからの入力を受け付けるためのモジュールです。 stdoutは、ターミナル上に出力を行うためのものです。

clear関数、print関数、sleep関数について、 clear関数は、ターミナルの画面をクリアするための関数です。 print関数は、指定した文字列をターミナル上に出力するための関数です。 sleep関数は、指定した時間だけプログラムを一時停止するための関数です。

次に、const sushi = String.fromCodePoint(0x1F363); について sushiという変数を定義しています。 この変数は、寿司マークを表す文字です。

最後に、main関数が定義されています。 この関数は、非同期処理を行うためにasyncを使っています。 main関数内では、ターミナルの画面サイズを取得し、whileループを使って、寿司マークを落下させる処理を繰り返します。

ターミナルで果物を降らす

上記の寿司を降らすコードをベースに果物を降らすコードを実装しました。

const readline = require('readline');
const stdout = process.stdout;

const clear = () => stdout.write('\033[2J');
const print = (s) => stdout.write(s);
const sleep = (m) => new Promise((resolve) => setTimeout(resolve, m));

const emoji = [
  0x1f347,
  0x1f348,
  0x1f349,
  0x1f34a,
  0x1f34e,
  0x1f34c,
  0x1f351,
  0x1f352,
  0x1f353,
  0x1fad0,
];

const main = async () => {
  const [w, h] = [stdout.columns, stdout.rows];
  const rand = (m) => Math.floor(Math.random() * m);
  const d = h * 3;
  const map = new Map();

  clear();
  while (true) {
    const q = [1, emoji[rand(emoji.length)]];
    map.set(rand(w), q);
    clear();
    for (const [x, [y, c]] of map) {
      if (y > d) {
        map.delete(x);
        continue;
      }
      map.set(x, [y + 1, c]);
      readline.cursorTo(stdout, x, y > h ? h : y);
      print(String.fromCodePoint(c));
    }
    readline.cursorTo(stdout, w, h);
    await sleep(100);
  }
};

main();

ターミナルで回転寿司

ターミナル上で円周上を移動するように回転する寿司を描画するコードを実装してみました。

まずは寿司が1つだけ回転するコードです。

const readline = require('readline');
const stdout = process.stdout;

const clear = () => stdout.write('\033[2J');
const print = (s) => stdout.write(s);
const sleep = (m) => new Promise((resolve) => setTimeout(resolve, m));

const sushi = String.fromCodePoint(0x1f363);

const main = async () => {
  const [w, h] = [stdout.columns, stdout.rows];
  const centerX = w / 2;
  const centerY = h / 2;
  let x = 0;
  let y = 0;
  let a = centerX * 0.95;
  let b = centerY * 0.95;
  let t = 0;
  while (true) {
    clear();
    x = Math.round((centerX + a * Math.cos(t)) % w);
    y = Math.round((centerY + b * Math.sin(t)) % h);
    readline.cursorTo(stdout, x, y);
    print(sushi);
    readline.cursorTo(stdout, w, h);
    await sleep(20);
    t += 0.05;
  }
};

これをベースに複数の寿司が回転するように、以下のように調整します。

const readline = require('readline');
const stdout = process.stdout;

const clear = () => stdout.write('\033[2J');
const print = (s) => stdout.write(s);
const sleep = (m) => new Promise((resolve) => setTimeout(resolve, m));

const sushi = String.fromCodePoint(0x1f363);
const main = async () => {
  const [w, h] = [stdout.columns, stdout.rows];
  const centerX = w / 2;
  const centerY = h / 2;
  const k = 0.95;
  let s = Array.from(Array(64), (v, k) => k);
  let a = centerX * k;
  let b = centerY * k;
  while (true) {
    clear();
    for (let i in s) {
      let p = s[i];
      let x = Math.round((centerX + a * Math.cos(p)) % w);
      let y = Math.round((centerY + b * Math.sin(p)) % h);
      readline.cursorTo(stdout, x, y);
      s[i] += 0.05;
      print(sushi);
    }
    readline.cursorTo(stdout, w, h);
    await sleep(120);
  }
};

参考にさせていただいたサイト

Tags
javascript(109)
linux(54)
node.js(53)
amazon%20aws(47)
typescript(44)
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0(36)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86(30)
html5(29)
php(24)
centos(24)
python(22)
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0(21)
mac(21)
mysql(20)
canvas(19)
opencv(17)
%E9%9B%91%E8%AB%87(16)
docker(16)
wordpress(15)
atcoder(14)
apache(12)
%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92(12)
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9(12)
amazon%20s3(12)
red%20hat(12)
prisma(12)
ubuntu(11)
github(10)
git(10)
vue.js(10)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF(10)
mariadb(10)
react(9)
aws%20cdk(9)
css3(8)
%E5%8F%AF%E8%A6%96%E5%8C%96(8)
%E5%B0%8F%E3%83%8D%E3%82%BF(8)
nestjs(8)
amazon%20lightsail(7)
next.js(7)
%E3%83%96%E3%83%AD%E3%82%B0(6)
cms(6)
oracle(6)
perl(6)
gitlab(6)
iam(5)
amazon%20ec2(5)
%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93(5)
aws%20amplify(5)
curl(4)
Author
githubzennqiita
ただの備忘録です。

※外部送信に関する公表事項