#!/usr/local/bin/ruby -w #REK_TITLE: class Bowling #FILENAME: Bowling.rb =begin BowlliardsまたはBowlingのスコアシートをsvgに変換するためのクラスを定義 したファイルです。 Bowling::Result クラス 倒したピンの数の配列を引数にとります。スプリットの場合は+10して下さい。 ストライクは10、ガターやミスは0とします。配列の要素はすべて整数値です。 ファールは扱えません。 得点の計算とsvg出力のための準備をします。 Bowling::ScoreSheet クラス svgで出力するためのクラスです。 使い方は...そのうち何か書くかもしれません。 =end module Bowling class Result attr_reader :pts, :name, :namesize, :cont, :split_frame def initialize(_ary, param={}) @split_frame = [] @name = param.fetch("name",'') @namesize = param.fetch("namesize", 50) @namesize = 0 if @name == '' @name = '' if @namesize == 0 ary = _ary.dup @pts = 0 @cont = [] (1..10).each do |fnum| if ary[0] > 10 @split_frame << fnum ary[0] -= 10 end if fnum == 10 (1..2).each do |i| next if ary[i] == nil if ary[i] > 10 @split_frame << ( fnum + i ) ary[i] -= 10 end end end @pts += ary[0] if ary[0] == 10 @pts = @pts + ary[1] + ary[2] @cont << [nil, "X", @pts] elsif ary[0] + ary[1] == 10 @pts = @pts + ary[1] + ary[2] ary[0] = "G" if ary[0] == 0 @cont << [ary[0], "/", @pts] else @pts += ary[1] ary[0] = "G" if ary[0] == 0 ary[1] = "-" if ary[1] == 0 @cont << [ary[0], ary[1], @pts] end ary.shift if ary[0] != 10 ary.shift end ## 残っているということは、マークがあるということ 1 or 2 if ary.size == 2 ary[0] = "X" if ary[0] == 10 ary[1] = "X" if ary[1] == 10 if !ary.index("X") && ary[0] + ary[1] == 10 ary[1] = "/" end @cont[-1] = [@cont[-1][1], ary[0], @cont[-1][2], ary[1]] elsif ary.size == 1 if ary[0] == 10 ary[0] = "X" elsif @cont[-1][-2].kind_of?(Numeric) && ary[0] + @cont[-1][-2] == 10 ary[0] = "/" end @cont[-1] += ary end end end ## class Result TEMPLATE=<<"END" ]> {{ var name=svg_defs}} {{ var name=scoresheet}} END class ScoreSheet def initialize @results = [] end def add(bwres) @results << bwres end def svg_def_frame(fx, fy) hx = fx * .5; hy = fy * .5 pdata = ["M", hx, 0, "l",0,hy, "l",hx,0, "l",0,-hy, "l", -fx, 0, "l",0,fy, "l",fx,0, "l",0,-hy] s = [%Q!!] s << %Q! ! s << %Q!! return s end def svg_def_frame10(fx, fy) hx = fx * .5; hy = fy * .5 pdata = ["M", hx ,0, "l",0,hy, "l",hx,0, "l",0,-hy, "l", -fx, 0, "l",0,fy, "l",hx * 3,0, "l",0,-fy, "l",-hx,0, "l",0,hy, "l",hx,0]; s = [%Q!!] s << %Q! ! s << %Q!! return s end def svg_def_strike(fx,fy) hx = fx * .5; qx = fx * .25 hy = fy * .5; qy = fy * .25 s = [%Q!!] s << %Q! ! s << %Q!! return s end def svg_def_spare(fx,fy) hx = fx * .5; qx = fx * .25 hy = fy * .5; qy = fy * .25 s = [%Q!!] s << %Q! ! s << %Q!! return s end def svg_def_split(r) s = [%Q!!] s << %Q! ! s << %Q!! return s end def addobj(obj, x, y) s = [%Q! !] case obj when "X" s << %Q! ! when "/" s << %Q! ! else s << %Q! #{obj}! end s << %Q! ! return s end def to_svg(param = {}, template = '') if template == '' template = TEMPLATE.dup end fx = param.fetch('fx',30).to_i fy = param.fetch('fy',30).to_i hx = fx * .5; qx = fx * .25 hy = fy * .5; qy = fy * .25 svg_x = param.fetch('svg_x',0).to_i svg_y = param.fetch('svg_y',0).to_i if svg_y == 0 svg_y = fy + 10 svg_y += (@results.size - 1) * (fy + 5) end if svg_x == 0 svg_x = 10 + fx * 10.5 svg_x = svg_x + @results[-1].namesize end param["svg_x"] = svg_x param["svg_y"] = svg_y svg_defs = [] svg_defs << svg_def_frame(fx, fy) svg_defs << svg_def_frame10(fx, fy) svg_defs << svg_def_strike(fx,fy) svg_defs << svg_def_spare(fx,fy) svg_defs << svg_def_split((qx > qy ? qy : qx) * .9) param["svg_defs"] = svg_defs.join("\n") ## scoresheet svg_sheet = [] @results.each_with_index do |bw,idx| svg_sheet << %Q!! svg_sheet << %Q!! svg_sheet << %Q!#{bw.name}! svg_sheet << %Q!! ## normal frames (1..9).each do |fnum| a = bw.cont[fnum - 1] svg_sheet << %Q!! svg_sheet << %Q! ! [[qx, qy],[qx * 3, qy],[hx , qy * 3]].each_with_index do |xy,i| next if a[i] == nil svg_sheet << addobj(a[i], *xy) end if bw.split_frame.index(fnum) svg_sheet << %Q! ! svg_sheet << %Q! ! svg_sheet << %Q! ! end svg_sheet << %Q!! end ### 10th frame [10].each do |fnum| a = bw.cont[fnum - 1] svg_sheet << %Q!! svg_sheet << %Q! ! [[qx,qy],[qx * 3, qy],[qx * 3, qy * 3]].each_with_index do |xy,i| svg_sheet << addobj(a[i], *xy) end if a.size == 4 ## upper right svg_sheet << addobj(a[3], qx * 5, qy) end (10..12).each do |i| if bw.split_frame.index(i) j = (i - 10) * 2 + 1 svg_sheet << %Q! ! svg_sheet << %Q! ! svg_sheet << %Q! ! end end svg_sheet << %Q!! end ## [10].each do |fnum| svg_sheet << %Q!! end param["scoresheet"] = svg_sheet.join("\n") svgtempl = template.dup template.scan(/(\{\{ *?var name=(.*?) *?\}\})/).each do |ss| svgtempl.sub!(Regexp.escape(ss[0]), param.fetch(ss[1],'UNDEF').to_s) end return svgtempl end end ## class ScoreSheet end if __FILE__ == $0 ary = [10,10,8,2,10,18,0,10,9,1,9,1,10,17,3,13] ## with split ary = [10,10,10,10,10,10,10,10,10,10,10,10] ## perfect #ary = [10,10,8,2,10,8,0,10,9,1,9,1,10,10,10,6] sheet = Bowling::ScoreSheet.new template = DATA.read param = {} #param["svg_x"] = "375" #param["svg_y"] = "40" #param["fx"] = "30" #param["fy"] = "30" param["name"] = "Rekry" #param["namesize"] = 45 res = Bowling::Result.new(ary,param) sheet.add(res) param["name"] = "R" #param["namesize"] = 0 ary = [10,10,8,2,10,8,0,10,9,1,9,1,10,5,4] res = Bowling::Result.new(ary,param) sheet.add(res) puts sheet.to_svg(param,template) end ## if __FILE__ == $0 __END__ ]> {{ var name=svg_defs}} {{ var name=scoresheet}}