Class: Mjai::YmatsuxShantenAnalysis

Inherits:
Object
  • Object
show all
Defined in:
lib/mjai/ymatsux_shanten_analysis.rb

Constant Summary collapse

NUM_PIDS =
9 * 3 + 7
TYPES =
["m", "p", "s", "t"]
TYPE_TO_TYPE_ID =
{"m" => 0, "p" => 1, "s" => 2, "t" => 3}
MENTSUS =
create_mentsus()

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pais) ⇒ YmatsuxShantenAnalysis

Returns a new instance of YmatsuxShantenAnalysis.



29
30
31
32
33
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 29

def initialize(pais)
  @pais = pais
  count_vector = YmatsuxShantenAnalysis.pais_to_count_vector(pais)
  @shanten = YmatsuxShantenAnalysis.calculate_shantensu_internal(count_vector, [0] * NUM_PIDS, 4, 0, 1.0/0.0)
end

Instance Attribute Details

#paisObject (readonly)

Returns the value of attribute pais.



35
36
37
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 35

def pais
  @pais
end

#shantenObject (readonly)

Returns the value of attribute shanten.



35
36
37
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 35

def shanten
  @shanten
end

Class Method Details

.add_mentsu(target_vector, mentsu_id) ⇒ Object



91
92
93
94
95
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 91

def self.add_mentsu(target_vector, mentsu_id)
  for pid in MENTSUS[mentsu_id]
    target_vector[pid] += 1
  end
end

.calculate_shantensu_internal(current_vector, target_vector, left_mentsu, min_mentsu_id, found_min_shantensu) ⇒ Object



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 53

def self.calculate_shantensu_internal(
    current_vector, target_vector, left_mentsu, min_mentsu_id, found_min_shantensu)
  min_shantensu = found_min_shantensu
  if left_mentsu == 0
    for pid in 0...NUM_PIDS
      target_vector[pid] += 2
      if valid_target_vector?(target_vector)
        shantensu = calculate_shantensu_lowerbound(current_vector, target_vector)
        min_shantensu = [shantensu, min_shantensu].min
      end
      target_vector[pid] -= 2
    end
  else
    for mentsu_id in min_mentsu_id...MENTSUS.size
      add_mentsu(target_vector, mentsu_id)
      lower_bound = calculate_shantensu_lowerbound(current_vector, target_vector)
      if valid_target_vector?(target_vector) && lower_bound < found_min_shantensu
        shantensu = calculate_shantensu_internal(
            current_vector, target_vector, left_mentsu - 1, mentsu_id, min_shantensu)
        min_shantensu = [shantensu, min_shantensu].min
      end
      remove_mentsu(target_vector, mentsu_id)
    end
  end
  return min_shantensu
end

.calculate_shantensu_lowerbound(current_vector, target_vector) ⇒ Object



80
81
82
83
84
85
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 80

def self.calculate_shantensu_lowerbound(current_vector, target_vector)
  count = (0...NUM_PIDS).inject(0) do |c, pid|
    c + (target_vector[pid] > current_vector[pid] ? target_vector[pid] - current_vector[pid] : 0)
  end
  return count - 1
end

.create_mentsusObject



13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 13

def self.create_mentsus()
  mentsus = []
  for i in 0...NUM_PIDS
    mentsus.push([i] * 3)
  end
  for t in 0...3
    for n in 0...7
      pid = t * 9 + n
      mentsus.push([pid, pid + 1, pid + 2])
    end
  end
  return mentsus
end

.pai_to_pid(pai) ⇒ Object



45
46
47
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 45

def self.pai_to_pid(pai)
  return TYPE_TO_TYPE_ID[pai.type] * 9 + (pai.number - 1)
end

.pais_to_count_vector(pais) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 37

def self.pais_to_count_vector(pais)
  count_vector = [0] * NUM_PIDS
  for pai in pais
    count_vector[pai_to_pid(pai)] += 1
  end
  return count_vector
end

.pid_to_pai(pid) ⇒ Object



49
50
51
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 49

def self.pid_to_pai(pid)
  return Pai.new(TYPES[pid / 9], pid % 9 + 1)
end

.remove_mentsu(target_vector, mentsu_id) ⇒ Object



97
98
99
100
101
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 97

def self.remove_mentsu(target_vector, mentsu_id)
  for pid in MENTSUS[mentsu_id]
    target_vector[pid] -= 1
  end
end

.valid_target_vector?(target_vector) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/mjai/ymatsux_shanten_analysis.rb', line 87

def self.valid_target_vector?(target_vector)
  return target_vector.all?(){ |c| c <= 4 }
end