Help us understand the problem. What is going on with this article?

ターミナルに Matrix が降ってくる Hack

1. ターミナルに雪を降らせるスクリプトというのがあるそうで

shell
ruby -e 'C=`stty size`.scan(/\d+/)[1].to_i;S=["2743".to_i(16)].pack("U*");a={};puts "\033[2J";loop{a[rand(C)]=0;a.each{|x,o|;a[x]+=1;print "\033[#{o};#{x}H \033[#{a[x]};#{x}H#{S} \033[0;0H"};$stdout.flush;sleep 0.1}'

2. 実行したらこうなるよ

snow.gif

※ ネタ元は ここの コメント欄らしいです

3. ruby の部分を取り出して、読みやすくリファクタしてみました

ruby
width = `stty size`.split(' ').last.to_i
positions = {}
puts "\033[2J" # clear screen
loop do
  positions[rand(width)] = 0
  positions.each { |column, row|
    print "\033[#{row};#{column}H " # erase snow
    positions[column] += 1
    print "\033[#{positions[column]};#{column}H❃" # draw snow
  }
  sleep 0.1
end

4. で、改造したくなりました

ruby
width = `stty size`.split(' ').last.to_i
positions = {}
print "\033[40m\033[32m" # black and green
puts "\033[2J" # clear screen
loop do
  positions[rand(width)] = 0
  positions.each { |column, row|
    positions[column] += 1
    print "\033[#{positions[column]};#{column}H#{[*' '..'z', *'ヲ'..'ン'].sample}"
  }
  sleep 0.1
end

5. ワンラインに戻すよ

shell
ruby -e 'w=`stty size`.split(" ").last.to_i;p={};print"\033[40m\033[32m\033[2J";loop{;p[rand(w)]=0;p.each{|c,r|;p[c]+=1;s=[*" ".."z",*"ヲ".."ン"].sample;print"\033[#{p[c]};#{c}H#{s}";};sleep 0.1}'

6. 実行したらこうなるよ

matrix.gif

7. まとめ

タイトルはわざと頭悪そうにしてみました。釣りです 😐

8. おまけ

雪を多重スクロール化してみました。ターミナルをフルスクリーンにしてから実行してみてね :hatched_chick:

shell
ruby -e 'puts "\033[2J";Y,X=`stty size`.split(" ").map(&:to_i);z={"."=>1,"*"=>2,"❃"=>3};a=[];loop{a<<[rand(X),0,z.keys.sample];a.map{|b|;print "\033[#{b[1]};#{b[0]}H ";b[0]+=rand(3)-1;b[1]+=z[b[2]];print "\033[#{b[1]};#{b[0]}H#{b[2]}";b};a.reject!{|b|b[1]>Y};$stdout.flush;sleep 0.1}'

実行するとこう

snow2.gif

コードはこう

ruby
height, width = `stty size`.split(' ').map(&:to_i)
z = { '.' => 1, '*' => 2, '❃' => 3 }
positions = []
puts "\033[2J" # clear screen
loop do
  positions << { x: rand(width), y: 0, z: z.keys.sample, i: 0 }
  positions.map { |position|
    print "\033[#{position[:y]};#{position[:x]}H " # erase snow
    position[:x] += rand(3) - 1
    position[:y] += z[position[:z]]
    print "\033[#{position[:y]};#{position[:x]}H#{position[:z]}" # draw snow
    position
  }
  positions.reject! { |snow| snow[:y] > height }
  sleep 0.1
end
m-kubo
ruby-dev
Ruby開発はRuby on Railsをコア技術とし、Web系から基幹系まで多様な開発に携わっています。
https://www.ruby-dev.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away