Kawasaki.rb #3でmrubyの簡単な紹介をしてきた。
ものすごく時間が立ってしまいましたが、8/28のKawasaki.rb*1でmrubyの簡単な紹介と、そのちょっとしたサンプルとして、webrubyを使って作った抽選スクリプトの紹介をしてきました。
その資料を置いておきます。
webruby & enchant.jsを使って作ったスクリプトの実物は下記にあります。
http://silentworlds.info/webruby/
ソースコードはこんな感じ
# -*- coding: utf-8 -*- class Candidates def parse ret = 'user01,abcd,0 user02,efgh,1 user03,ijkl,0 '.strip.split("\n").map{|line| line.strip.split(",")} ret.each {|d| d.map!{|e| e.strip } } return ret end def initialize @list = parse() end def name(i) @list[i][0] end def angle(i) w = @list[i][1] hashno = w.hash>=0 ? w.hash : w.hash*-1 hashstr = sprintf("%04d",hashno%10000).to_s hashstr[0..1].to_i end def velocity(i) w = @list[i][1] hashno = w.hash>=0 ? w.hash : w.hash*-1 hashstr = sprintf("%04d",hashno%10000).to_s v = hashstr[2..3].to_i v = v*2 if @list[i][2]=="1" v end def flag(i) @list[i][2] end def max @list.size end end #================================= class Enchant def initialize @root=MrubyJs.get_root_object @stage_x = 640 @stage_y = 320 end def set_position(name,x,y) @root.call(name,x,y) end def stop_loop @root.call('stopTimerLoop') end def update_ranking(text) @root.call('updateRanking',text) end def update_mbox(text) @root.call('updateMbox',text) end def update_sub(text) @root.call('updateSub',text) end def invisible @root.call('invisibleKuma') end attr_accessor :stage_x, :stage_y end #================================= class Log def put(msg) root = MrubyJs.get_root_object box = root.call('$', '#container') box.call('append', "<p>"+msg+"</p>") end end #================================= class Target def initialize(a,v) @angle = (20.0+60.0*a/100.0) * Math::PI / 180.0 @velocity = 12.0* 100.0*((v/100.0)**(0.3))/100.0 @x = 0.0 @ground = 400.0 @y = @ground @root = MrubyJs.get_root_object @flag=false @enchant = Enchant.new end def update(count) t = count g = 0.3 @x = 1.0 * @velocity * Math::cos(@angle) * t @y = @ground - (@velocity * Math::sin(@angle)*t - 0.5*g*t*t) #@x=0 if @x>@enchant.stage_x if @y>@ground @y=@ground @flag=true end #Log.new.put("count="+count.to_s+" x="+x.to_s) @enchant.set_position(:setKuma,x,y) end def finish? @flag end attr_accessor :angle, :velocity, :x, :y end #================================= class RankingList def initialize @max = 2 #**** max LT talker number **** @list={} end def add(name,record) @list.store(name,record) end def sort @list.to_a.sort{|a, b| (b[1] <=> a[1]) * 2 + (a[0] <=> b[0]) } end def get_top(n) sorted = sort() return sorted[n] end def to_s text="[Ranking]<br>" length = @max > @list.length ? @list.length : @max (1..length).each{|n| r = get_top(n-1) text = text + "No."+n.to_s+" : "+r[0]+" さん / "+r[1].round.to_s+"m<br>" } text end def rank(name) sorted = sort() (1..sorted.length).each{|n| return n if sorted[n-1][0] == name } end attr_reader :max end #================================= class EventState def initialize @state = :init @l=Log.new @count = 0 @js_state @change_flag=true @changed_count = -1 @enchant = Enchant.new @ranking = RankingList.new @candidates = Candidates.new #-------------- @target_no=0 end def act(c,js) @count = c @js_state = js if(@state==:init) do_init elsif(@state==:throwing_start) do_throwing_start elsif(@state==:throwing) do_throwing elsif(@state==:throwing_end) do_throwing_end elsif(@state==:finish_choosing) do_finish_choosing else end @change_flag=false if @change_flag==true && @changed_count!=@count end def change(n) @l.put("change state : "+@state.to_s+" -> "+n.to_s) @state=n @change_flag=true @changed_count = @count end def check(n) @state==n end def do_init @enchant.update_mbox('Lets start Chusen<br>atari = '+RankingList.new.max.to_s+"<br>Press Enter") if @js_state == 1 change(:throwing_start) end end #------- def do_throwing_start if(@change_flag) @enchant.update_mbox("") @enchant.update_sub(@candidates.name(@target_no)+"さん") @init_count=@count end change(:throwing) if @count-@init_count>40 end #------ def do_throwing if(@change_flag) @l.put("init") no = @target_no @l.put(@candidates.name(no)) @l.put(@candidates.angle(no).to_s) @l.put(@candidates.velocity(no).to_s) d1=@candidates.angle(no) d2=@candidates.velocity(no) @init_count=@count @target = Target.new(d1,d2) end change(:throwing_end) if @target.finish? @target.update(@count-@init_count) end #------- def do_throwing_end if(@change_flag) @ranking.add(@candidates.name(@target_no),@target.x) @l.put @ranking.to_s @enchant.update_ranking(@ranking.to_s) @enchant.update_mbox( "Rank=>"+@ranking.rank(@candidates.name(@target_no)).to_s) @init_count=@count end # @enchant.update_sub("") if @count-@init_count<60 return end candidates = Candidates.new @target_no += 1 if @target_no >= candidates.max change(:finish_choosing) else change(:throwing_start) end end #-------- def do_finish_choosing @l.put("do_finish_choosing") @enchant.invisible @enchant.stop_loop @enchant.update_mbox("") @enchant.update_sub("") @enchant.update_ranking("") @enchant.update_mbox("Result "+@ranking.to_s) end end #========================== class CoreProcess def run(root) l=Log.new count=0.0 state = EventState.new prc = Proc.new {|js_state| state.act(count,js_state) count+=1.0 } root.call(:setEnterframeListener, prc) root.call(:timerloop) end end root = MrubyJs.get_root_object core = CoreProcess.new core.run(root)