#!/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"
]>
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__
]>