class FourPillarsLogic

Constants

GOGYO
JIKKAN
JIKKAN_IN
JYUNISHI
JYUNISHI_IN
JYUNIUNSEI
JYUNIUNSEI_ENERGY
KANSHI_ARRAY
KANSHI_HASH
KUUBOU
SETSUIRI_LIST
SHUGOSHIN
TSUHENSEI

Attributes

birth_dt[R]

生年月日時間, 性別(大運の向きに使用)

gender[R]

生年月日時間, 性別(大運の向きに使用)

Public Class Methods

jikkan_in() click to toggle source

陰干通表

# File lib/four-pillars.rb, line 46
def self.jikkan_in
  j = [nil] * 10
  [0,2,4,6,8].each do |i|
    j[i] = JIKKAN[i+1]
    j[i+1] = JIKKAN[i]
  end
  return j
end
jyuniunsei(j_day,j_src) click to toggle source
# File lib/four-pillars.rb, line 100
def self.jyuniunsei(j_day,j_src) # 日柱の十干, 十二支
  j = JIKKAN.index(j_day)
  if j % 2 == 0 # 陽
    jyunishi = JYUNISHI
  else # 陰
    jyunishi = JYUNISHI_IN
  end
  offset = [1,7,10,10,10,10,7,1,4,4][j] # 十二運表より求めたオフセット
  ji = jyunishi.index(j_src)
  JYUNIUNSEI[(ji + offset) % 12]
end
jyuniunsei_energy() click to toggle source

十二運星エネルギー

# File lib/four-pillars.rb, line 58
def self.jyuniunsei_energy
  h = {}
  energies = [9,7,10,11,12,8,4,2,5,1,3,6]
  12.times do |i|
    h[JYUNIUNSEI[i]] = energies[i]
  end
  return h
end
kanshi_array() click to toggle source

60干支表

# File lib/four-pillars.rb, line 24
def self.kanshi_array
  a = []
  60.times do |i|
    j1 = FourPillarsLogic::JIKKAN[i%10]
    j2 = FourPillarsLogic::JYUNISHI[i%12]
    a += [j1+j2]
  end
  return a
end
kanshi_hash() click to toggle source

60干支表

# File lib/four-pillars.rb, line 36
def self.kanshi_hash
  h = {}
  kanshi_array.each_with_index do |v,i|
    h[v] = i+1
  end
  return h
end
load_setsuiri() click to toggle source

年月の節入り日時 (注:時 = 時間 x 60 + 分)

# File lib/four-pillars.rb, line 69
def self.load_setsuiri
  l = []
  h = {}
  open(__dir__+"/four-pillars-setsuiri.txt").each do |line|
    next if line.strip.empty? || line.start_with?("#")
    vs = line.split(",")
    if vs.count != 5 || vs[0].empty?
      puts "Invalid row: #{line}"
      next
    end
    vs.map! { |v| v.to_i }
    h[vs[0]*100+vs[1]] = [vs[2],vs[3]*60+vs[4]]
    l += [vs]
  end
  return h, l
end
new(birth_dt,gender) click to toggle source
# File lib/four-pillars.rb, line 117
def initialize(birth_dt,gender)
  @birth_dt = birth_dt.map {|v| v.to_i }
  @gender = gender
  raise "Incorrect birth date: #{birth_dt}" if @birth_dt.count != 5
  raise "Gender must be m,f or o(other): #{gender}" unless ['o','m','f'].include? @gender
  raise "Year must be larger than 1863" if @birth_dt[0] < 1864
end
tsuhensei(j_day,j_src) click to toggle source

通変星

# File lib/four-pillars.rb, line 88
def self.tsuhensei(j_day,j_src) # 日柱の十干、月柱または年柱の十干
  j = JIKKAN.index(j_day)
  if j % 2 == 0 # 陽
    jikkan = JIKKAN
  else # 陰
    jikkan = JIKKAN_IN
  end
  t = jikkan.index(j_src) - jikkan.index(j_day)
  t += 10 if t < 0
  TSUHENSEI[t]
end

Public Instance Methods

days_of_current_month() click to toggle source

今月の日数

# File lib/four-pillars.rb, line 146
def days_of_current_month
  y,m,d,h,i = @birth_dt
  Date.new(y,m,1).next_month.prev_day.day
end
days_of_previous_month() click to toggle source

前月の日数

# File lib/four-pillars.rb, line 140
def days_of_previous_month
  y,m,d,h,i = @birth_dt
  (Date.new(y,m,1) - 1).day
end
equivalent_kanshi(only_jikkan=false) click to toggle source
# File lib/four-pillars.rb, line 369
def equivalent_kanshi(only_jikkan=false)
  if only_jikkan
    k = kanshi.map {|v| v[0] } # 日,月,年柱の十干
  else
    k = kanshi
  end
  if k[0] == k[1] && k[1] == k[2]
    return [[0,1],[0,2],[1,2]]
  elsif k[0] == k[1]
    return [[0,1]]
  elsif k[0] == k[2]
    return [[0,2]]
  elsif k[1] == k[2]
    return [[1,2]]
  else
    return []
  end
end
gogyo_jikkan() click to toggle source

五行(十干)

# File lib/four-pillars.rb, line 320
def gogyo_jikkan
  arr = []
  3.times do |i|
    j = JIKKAN.index(kanshi[i][0])
    arr += [(j % 2 == 0 ? "+" : "-") + GOGYO[j / 2]]
  end
  return arr
end
gogyo_jyunishi() click to toggle source

五行(十二支)

# File lib/four-pillars.rb, line 330
def gogyo_jyunishi
  arr = []
  gogyo_j = ["水","土","木","木","土","火","火","土","金","金","土","水"]
  3.times do |i|
    j = JYUNISHI.index(kanshi[i][1])
    arr += [(j % 2 == 0 ? "+" : "-") + gogyo_j[j]]
  end
  return arr
end
input() click to toggle source

生年月日と性別

# File lib/four-pillars.rb, line 126
def input
  y,m,d,h,i = @birth_dt
  case @gender
  when 'm' then
    g = "男性"
  when 'f' then
    g = "女性"
  else
    g = ""
  end
  "#{y}年#{m}月#{d}日#{h}時#{i}分生 #{g}"
end
jyuniunsei() click to toggle source

十二運星

# File lib/four-pillars.rb, line 288
def jyuniunsei
  d = FourPillarsLogic::jyuniunsei(kanshi[0][0],kanshi[0][1])
  m = FourPillarsLogic::jyuniunsei(kanshi[0][0],kanshi[1][1])
  y = FourPillarsLogic::jyuniunsei(kanshi[0][0],kanshi[2][1])
  [d,m,y]
end
jyuniunsei_energy() click to toggle source
# File lib/four-pillars.rb, line 295
def jyuniunsei_energy
  jyuniunsei.map {|v| JYUNIUNSEI_ENERGY[v] }
end
kanshi() click to toggle source

干支(日,月,年)

# File lib/four-pillars.rb, line 196
def kanshi
  y,m,d,h,i = @birth_dt
  sd, st = setsuiri
  yd = y - 1864 # (till 1865.02.0?) = 甲子
  yd -= 1 if m < 2 || (m == 2 && d < sd) || (m == 2 && d == sd && h*60+i < st)
  md = (y - 1863) * 12 + (m - 12) # (till 1864.01.05) = 甲子
  md -= 1 if d < sd || (d == sd && h*60+i < st)
  dd = Date.new(y,m,d) - Date.new(1863,12,31) # 1923.10.18 = 甲子

  return [KANSHI_ARRAY[dd % 60],KANSHI_ARRAY[md % 60],KANSHI_ARRAY[yd % 60]]
end
kanshi_as_number() click to toggle source

干支(数字)

# File lib/four-pillars.rb, line 209
def kanshi_as_number
  kanshi.map {|v| KANSHI_HASH[v] }
end
know_setsuiri?() click to toggle source

生年月に対する節入日時を知っているか? このメソッドがfalseを返す場合、干支、蔵干が仮の節入日で計算されています。

# File lib/four-pillars.rb, line 177
def know_setsuiri?
  y,m,d,h,i = @birth_dt
  SETSUIRI_HASH.include? y*100+m
end
kuubou() click to toggle source

空亡 = 天中殺

# File lib/four-pillars.rb, line 300
def kuubou
  k_day = (kanshi_as_number[0] - 1) / 10
  k_year = (kanshi_as_number[2] - 1) / 10
  [KUUBOU[k_day],KUUBOU[k_year]]
end
nacchin() click to toggle source

納音

# File lib/four-pillars.rb, line 400
def nacchin
  # 十干が同じで十二支が 沖 の関係にある
  v = []
  eq = equivalent_kanshi(true)
  eq.each do |e|
    k0 = kanshi[e[0]][1]
    k1 = kanshi[e[1]][1]
    v += [e] if on_distance?(k0,k1,6)
  end
  return v
end
on_distance?(j1,j2,d=6) click to toggle source
# File lib/four-pillars.rb, line 388
def on_distance?(j1,j2,d=6)
  i = JYUNISHI.index(j1)
  return j2 == JYUNISHI[(i+d) % 12]
end
ricchin() click to toggle source

律音

# File lib/four-pillars.rb, line 394
def ricchin
  # 干支(十干・十二支)が同じ
  equivalent_kanshi(false)
end
setsuiri() click to toggle source

生年月に対応する節入り日時 ファイルに登録がない場合は、4日12時を返す

# File lib/four-pillars.rb, line 183
def setsuiri
  y,m,d,h,i = @birth_dt
  SETSUIRI_HASH[y*100+m] || [4,12*60]
end
setsuiri?() click to toggle source

生まれた日が節入日にあたる場合、true

# File lib/four-pillars.rb, line 189
def setsuiri?
  return false unless know_setsuiri?
  y,m,d,h,i = @birth_dt
  setsuiri[0] == d
end
setsuiri_of_next_month() click to toggle source

翌月の節入日

# File lib/four-pillars.rb, line 164
def setsuiri_of_next_month
  y,m,d,h,i = @birth_dt
  if m == 12
    y += 1
    m = 1
  else
    m += 1
  end
  SETSUIRI_HASH[y*100+m] || [0,0]
end
setsuiri_of_previous_month() click to toggle source

前月の節入日

# File lib/four-pillars.rb, line 152
def setsuiri_of_previous_month
  y,m,d,h,i = @birth_dt
  if m == 1
    y -= 1
    m = 12
  else
    m -= 1
  end
  SETSUIRI_HASH[y*100+m] || [0,0]
end
shugoshin() click to toggle source

守護神

# File lib/four-pillars.rb, line 341
def shugoshin
  # 日柱の十干と月柱の十二支
  x = JIKKAN.index(kanshi[0][0])
  y = JYUNISHI.index(kanshi[1][1])
  SHUGOSHIN[y][x].split("")
end
shukumei() click to toggle source

宿命中殺

# File lib/four-pillars.rb, line 349
def shukumei
  s = []
  t = kuubou # 天中殺 0:上段, 1:下段
  k = kanshi.map {|v| v[1] } # 日,月,年柱の干支
  if t[0].include? k[2]
    s += ["生年中殺"]
  end
  if t[0].include? k[1]
    s += ["生月中殺"]
  end
  if t[1].include? k[0]
    s += ["生日中殺"]
  end
  f = false
  f = true if kanshi_as_number.include? 11 #甲戌
  f = true if kanshi_as_number.include? 12 #乙亥
  s += ["日座中殺"] if f
  return s
end
shukumei_daihankai() click to toggle source

宿命大半会

# File lib/four-pillars.rb, line 413
def shukumei_daihankai
  # 十干が同じで十二支が三合会局の関係にある
  v = []
  eq = equivalent_kanshi(true)
  eq.each do |e|
    k0 = kanshi[e[0]][1]
    k1 = kanshi[e[1]][1]
    v += [e] if on_distance?(k0,k1,4)
  end
  eq.each do |e|
    k0 = kanshi[e[0]][1]
    k1 = kanshi[e[1]][1]
    v += [e] if on_distance?(k0,k1,8)
  end
  return v
end
taiun() click to toggle source

大運 [順行 or 逆行, year] or [nil,nil](if gender is not male nor female)

# File lib/four-pillars.rb, line 431
def taiun
  return [nil,nil] unless ['m','f'].include? @gender
  k = gogyo_jikkan[2][0]
  t = @birth_dt[3] * 60 + @birth_dt[4] # 生まれた時間
  if (@gender == 'm' && k == "+") || (@gender == 'f' && k == '-')
    order = "順行"
    d = setsuiri[0] - birth_dt[2]
    if d > 0 # A 生まれた日が節入り前の場合 (節入り日―誕生日+1)÷3
      year = ((d + 1) / 3.0).round
    elsif d == 0 # 節入り日
      #〈順行〉節入時間「前」=1年  「後」=10年
      if t <= setsuiri[1]
        year = 1
      else
        year = 10
      end
    else # B 生まれた日が節入り後の場合  (誕生月の日数―誕生日+1+翌月の節入り日)÷3
      s = days_of_current_month - birth_dt[2] + 1 + setsuiri_of_next_month[0]
      year = (s / 3.0).round
    end
  else
    order = "逆行"
    if setsuiri?
      #〈逆行〉節入時間「前」=10年 「後」=1年
      if t < setsuiri[1]
        year = 10
      else
        year = 1
      end
    else
      year = (zokan_number / 3.0).round
    end
  end
  return [order,year]
end
taiun_table() click to toggle source
# File lib/four-pillars.rb, line 467
def taiun_table
  order,year = taiun
  return [] if order.nil?
  d = order == '順行' ? 1 : -1
  j_day = kanshi[0][0] # 日柱の十干
  k = kanshi_as_number[1] - 1 # 月柱の干支番号
  rows = []
  # [0,1,"癸亥","偏印","死",2]
  y1, y2 = 0, year
  8.times do |i|
    k_month = KANSHI_ARRAY[k] # 月柱の干支
    t = FourPillarsLogic::tsuhensei(j_day,k_month[0])
    j = FourPillarsLogic::jyuniunsei(j_day,k_month[1])
    je = JYUNIUNSEI_ENERGY[j]
    rows += [[y1,y2,k_month,t,j,je]]
    if y1 == 0
      y1 = year
    else
      y1 += 10
    end
    y2 += 10
    k += d
    k = 59 if k < 0
    k = 0 if k > 59
  end
  return rows
end
tell() click to toggle source

テーブル表示用に配列にして返す (デバッグ用) 0:干支, 1:干支数字, 2:蔵干, 3:通変星, 4:蔵干通変星, 5:十二運星 五行、天中殺、十二運星エネルギーは別途

# File lib/four-pillars.rb, line 309
def tell
  m = [kanshi]
  m += [kanshi_as_number]
  m += [zokan]
  m += [tsuhensei]
  m += [zokan_tsuhensei]
  m += [jyuniunsei]
  m += [jyuniunsei_energy]
end
tsuhensei() click to toggle source

通変星(nil,月,年)

# File lib/four-pillars.rb, line 260
def tsuhensei
  m = FourPillarsLogic::tsuhensei(kanshi[0][0],kanshi[1][0])
  y = FourPillarsLogic::tsuhensei(kanshi[0][0],kanshi[2][0])
  [nil,m,y]
end
zokan() click to toggle source
# File lib/four-pillars.rb, line 226
def zokan
  zokan_hash1 = {"子" => "癸","卯" => "乙","酉" => "辛"}
  zokan_hash2 = {"午" => ["己",19,"丁"],"亥" => ["甲",12,"壬"]}
  zokan_hash3 = {"丑" => ["癸",9,"辛",12,"己"],"寅" => ["戊",7,"丙",14,"甲"],
    "辰" => ["乙",9,"癸",12,"戊"],"巳" => ["戊",5,"庚",14,"丙"],"未" => ["丁",9,"乙",12,"己"],
    "申" => ["戊",10,"壬",13,"庚"],"戌" => ["辛",9,"丁",13,"戊"]}
  zn = zokan_number
  z = []
  kanshi.each do |k|
    j = k[1] # 十二支
    if zokan_hash1.keys.include? j
      z += [zokan_hash1[j]]
    elsif zokan_hash2.keys.include? j
      arr = zokan_hash2[j]
      if zn <= arr[1]
        z += [arr[0]]
      else
        z += [arr[2]]
      end
    elsif zokan_hash3.keys.include? j
      arr = zokan_hash3[j]
      if zn <= arr[1]
        z += [arr[0]]
      elsif zn <= arr[3]
        z += [arr[2]]
      else
        z += [arr[4]]
      end
    end
  end
  return z
end
zokan_number() click to toggle source

蔵干数字

# File lib/four-pillars.rb, line 214
def zokan_number
  y,m,d,h,i = @birth_dt
  sd, st = setsuiri
  if d < sd || (d == sd && h*60+i < st)
    # 誕生日 + (前月の日数 - 前月の節入日) + 1
    return d + (days_of_previous_month - setsuiri_of_previous_month[0]) + 1
  else
    # 誕生日 - 節入日 + 1
    return d - sd + 1
  end
end
zokan_tsuhensei() click to toggle source

蔵干通変星

# File lib/four-pillars.rb, line 267
def zokan_tsuhensei
  j = JIKKAN.index(kanshi[0][0])
  if j % 2 == 0 # 陽
    jikkan = JIKKAN
  else # 陰
    jikkan = JIKKAN_IN
  end
  j = jikkan.index(kanshi[0][0])
  j_day = jikkan.index(zokan[0])
  j_month = jikkan.index(zokan[1])
  j_year = jikkan.index(zokan[2])
  t_day = j_day - j
  t_day += 10 if t_day < 0
  t_month = j_month - j
  t_month += 10 if t_month < 0
  t_year = j_year - j
  t_year += 10 if t_year < 0
  [TSUHENSEI[t_day],TSUHENSEI[t_month],TSUHENSEI[t_year]]
end