hp12c
07 June 2012

Rubyであみだくじ

巷ではRubyで「あみだくじ」を書くのが流行っているのですね。僕も便乗します。但し、無制限一本勝負で^ ^; Cursesを使ってみました。

[フレーム]
require "curses"
class Amida
 include Curses
 def initialize(opt={})
 opt = opt_check(opt)
 n = opt[:member]
 @members = ('A'..'Z').take(n)
 @margin = opt[:margin]
 @height = opt[:length]
 @width = n + @margin*(n-1)
 @ladders = set_ladders(n)
 @wins = set_win(n, (opt[:win]))
 end
 def draw
 draw_with_curses do |bx, by|
 draw_headline(bx, by, 0.1)
 draw_vlines(bx, by, 0.05)
 draw_win(bx, by, 0.2)
 draw_ladders(bx, by, 0.05)
 end
 end
 private
 def opt_check(opt)
 m = opt[:member] || 5
 init_screen
 h = { member: [26,5],
 margin: [cols/m,3],
 length: [lines-5,5],
 win: [m,1] }
 h.each do |key, (max, defo)|
 val = opt[key]
 raise "#{key} value `#{val}` is out of range(max: #{max})." if val && val > max
 opt.update({key => (val || defo)})
 end
 opt
 end
 def set_ladders(n)
 ladders = Array.new(@height) { Array.new(n-1, false) }
 is_true_pair = ->l{ l.each_cons(2).any? { |pair| pair.all? } }
 ladders.map! do |line|
 while line.none? || is_true_pair[line]
 line = line.map { |lad| rand <= 0.6 }
 end
 line
 end
 end
 def set_win(n, wins)
 [*0...n].shuffle.pop(wins)
 end
 def draw_with_curses(bx=nil, by=nil)
 init_screen
 start_color
 init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK)
 init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK)
 init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK)
 yield (bx || cols/2-@width/2), (by || lines/2-@height/2)
 setpos(0,0)
 getch
 ensure
 close_screen
 end
 def draw_headline(x, y, sp)
 @members.each do |m|
 sleep(sp)
 setpos(y, x)
 attron(color_pair(COLOR_GREEN)|A_BOLD) {
 addstr(m.to_s)
 }
 refresh
 x += @margin+1
 end
 end
 def draw_vlines(x, y, sp)
 @members.each do
 pos_y = y + 1
 @height.times do |i|
 sleep(sp)
 setpos(pos_y+i, x)
 addch('|')
 refresh
 end
 x += @margin+1
 end
 end
 def draw_ladders(x, y, sp)
 pos_y = y + 1
 @ladders.each_with_index do |line, i|
 pos_x = x + 1
 line.each do |lad|
 sleep(sp)
 setpos(pos_y+i, pos_x)
 addstr('-'*@margin) if lad
 refresh
 pos_x += @margin + 1
 end
 end
 end
 def draw_win(x, y, sp)
 pos_y = y + @height + 1
 @wins.each_with_index do |win, i|
 sleep(sp)
 pos_x = x + win * (@margin+1)
 setpos(pos_y, pos_x)
 attron(color_pair COLOR_RED) {
 addstr("#{i+1}")
 }
 refresh
 end
 end
end
args = ARGV.map(&:to_i)
args = Array.new(3).map { args.shift }
opt = Hash[ [:member, :win, :length].zip(args) ]
am = Amida.new(opt)
am.draw


Please enable JavaScript to view the comments powered by Disqus. blog comments powered by Disqus
ruby_pack8

100円〜で好評発売中!
M'ELBORNE BOOKS



AltStyle によって変換されたページ (->オリジナル) /