Class: Mjai::Manue::DangerEstimator::Scene
- Inherits:
-
Object
- Object
- Mjai::Manue::DangerEstimator::Scene
- Defined in:
- lib/mjai/manue/danger_estimator.rb
Constant Summary collapse
- @@feature_names =
[]
Instance Attribute Summary collapse
-
#candidates ⇒ Object
readonly
Returns the value of attribute candidates.
Class Method Summary collapse
Instance Method Summary collapse
- #anpai?(pai) ⇒ Boolean
- #fanpai_fansu(pai) ⇒ Object
-
#feature_vector(pai) ⇒ Object
pai is without red.
-
#get_possible_sujis(pai) ⇒ Object
Uses the first pai to represent the suji.
- #get_suji_numbers(pai) ⇒ Object
-
#initialize(params) ⇒ Scene
constructor
A new instance of Scene.
- #matagisuji_of(pai, target_pai_set) ⇒ Object
- #n_chance_or_less(pai, n) ⇒ Object
- #n_or_more_of_neighbors_in_prereach_sutehais(pai, n, neighbor_distance) ⇒ Object
- #n_outer_prereach_sutehai(pai, n) ⇒ Object
- #num_n_or_inner(pai, n) ⇒ Object
- #outer(pai, target_pai_set) ⇒ Object
- #senkisuji_of(pai, target_pai_set) ⇒ Object
- #suji_of(pai, target_pai_set) ⇒ Object
- #to_pai_set(pais) ⇒ Object
- #urasuji_of(pai, target_pai_set) ⇒ Object
- #visible_n_or_more(pai, n) ⇒ Object
- #weak_suji_of(pai, target_pai_set) ⇒ Object
Constructor Details
#initialize(params) ⇒ Scene
Returns a new instance of Scene.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/mjai/manue/danger_estimator.rb', line 31 def initialize(params) if params[:game] params = params.dup() # Adds params[:dapai] because the game object points to the scene after the dapai. params[:tehais] = params[:me].tehais + (params[:dapai] ? [params[:dapai]] : []) params[:anpais] = params[:reacher].anpais params[:doras] = params[:game].doras params[:bakaze] = params[:game].bakaze params[:reacher_kaze] = params[:reacher].jikaze params[:visible] = [] params[:visible] += params[:game].dora_markers params[:visible] += params[:me].tehais for player in params[:game].players params[:visible] += player.ho + player.furos.map(){ |f| f.pais }.flatten() end end prereach_sutehais = params[:prereach_sutehais] @tehai_set = to_pai_set(params[:tehais]) @anpai_set = to_pai_set(params[:anpais]) @visible_set = to_pai_set(params[:visible]) @dora_set = to_pai_set(params[:doras]) @bakaze = params[:bakaze] @reacher_kaze = params[:reacher_kaze] @prereach_sutehai_set = to_pai_set(prereach_sutehais) @early_sutehai_set = to_pai_set(prereach_sutehais[0...(prereach_sutehais.size / 2)]) @late_sutehai_set = to_pai_set(prereach_sutehais[(prereach_sutehais.size / 2)..-1]) # prereach_sutehais can be empty in unit tests. @reach_pai = prereach_sutehais[-1] ? prereach_sutehais[-1].remove_red() : nil @candidates = @tehai_set.keys.select(){ |pai| !@anpai_set.has_key?(pai) } end |
Instance Attribute Details
#candidates ⇒ Object (readonly)
Returns the value of attribute candidates.
67 68 69 |
# File 'lib/mjai/manue/danger_estimator.rb', line 67 def candidates @candidates end |
Class Method Details
.define_feature(name, &block) ⇒ Object
22 23 24 25 |
# File 'lib/mjai/manue/danger_estimator.rb', line 22 def self.define_feature(name, &block) define_method(name, &block) @@feature_names.push(name) end |
.feature_names ⇒ Object
27 28 29 |
# File 'lib/mjai/manue/danger_estimator.rb', line 27 def self.feature_names return @@feature_names end |
Instance Method Details
#anpai?(pai) ⇒ Boolean
84 85 86 |
# File 'lib/mjai/manue/danger_estimator.rb', line 84 def anpai?(pai) return @anpai_set.has_key?(pai.remove_red()) end |
#fanpai_fansu(pai) ⇒ Object
407 408 409 410 411 412 413 |
# File 'lib/mjai/manue/danger_estimator.rb', line 407 def fanpai_fansu(pai) if pai.type == "t" && pai.number >= 5 return 1 else return (pai == @bakaze ? 1 : 0) + (pai == @reacher_kaze ? 1 : 0) end end |
#feature_vector(pai) ⇒ Object
pai is without red. Use bit vector to make match? faster.
79 80 81 82 |
# File 'lib/mjai/manue/danger_estimator.rb', line 79 def feature_vector(pai) return DangerEstimator.bool_array_to_bit_vector( @@feature_names.map(){ |s| __send__(s, pai) }) end |
#get_possible_sujis(pai) ⇒ Object
Uses the first pai to represent the suji. e.g. 1p for 14p suji
341 342 343 344 345 346 347 348 349 350 |
# File 'lib/mjai/manue/danger_estimator.rb', line 341 def get_possible_sujis(pai) if pai.type == "t" return [] else ns = [pai.number - 3, pai.number].select() do |n| [n, n + 3].all?(){ |m| (1..9).include?(m) && !@anpai_set.include?(Pai.new(pai.type, m)) } end return ns.map(){ |n| Pai.new(pai.type, n) } end end |
#get_suji_numbers(pai) ⇒ Object
336 337 338 |
# File 'lib/mjai/manue/danger_estimator.rb', line 336 def get_suji_numbers(pai) return [pai.number - 3, pai.number + 3].select(){ |n| (1..9).include?(n) } end |
#matagisuji_of(pai, target_pai_set) ⇒ Object
389 390 391 392 393 394 395 396 |
# File 'lib/mjai/manue/danger_estimator.rb', line 389 def matagisuji_of(pai, target_pai_set) if pai.type == "t" return false else sujis = get_possible_sujis(pai) return sujis.any?(){ |s| target_pai_set.has_key?(s.next(1)) || target_pai_set.has_key?(s.next(2)) } end end |
#n_chance_or_less(pai, n) ⇒ Object
352 353 354 355 356 357 358 359 360 361 |
# File 'lib/mjai/manue/danger_estimator.rb', line 352 def n_chance_or_less(pai, n) if pai.type == "t" || (4..6).include?(pai.number) return false else return (1..2).any?() do |i| kabe_pai = Pai.new(pai.type, pai.number + (pai.number < 5 ? i : -i)) @visible_set[kabe_pai] >= 4 - n end end end |
#n_or_more_of_neighbors_in_prereach_sutehais(pai, n, neighbor_distance) ⇒ Object
308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/mjai/manue/danger_estimator.rb', line 308 def n_or_more_of_neighbors_in_prereach_sutehais(pai, n, neighbor_distance) if pai.type == "t" return false else num_neighbors = ((pai.number - neighbor_distance)..(pai.number + neighbor_distance)). select(){ |n| @prereach_sutehai_set.has_key?(Pai.new(pai.type, n)) }. size return num_neighbors >= n end end |
#n_outer_prereach_sutehai(pai, n) ⇒ Object
297 298 299 300 301 302 303 304 305 306 |
# File 'lib/mjai/manue/danger_estimator.rb', line 297 def n_outer_prereach_sutehai(pai, n) if pai.type == "t" return false elsif pai.number < 6 - n || pai.number > 4 + n n_inner_pai = Pai.new(pai.type, pai.number < 5 ? pai.number + n : pai.number - n) return @prereach_sutehai_set.include?(n_inner_pai) else return false end end |
#num_n_or_inner(pai, n) ⇒ Object
363 364 365 |
# File 'lib/mjai/manue/danger_estimator.rb', line 363 def num_n_or_inner(pai, n) return pai.type != "t" && pai.number >= n && pai.number <= 10 - n end |
#outer(pai, target_pai_set) ⇒ Object
398 399 400 401 402 403 404 405 |
# File 'lib/mjai/manue/danger_estimator.rb', line 398 def outer(pai, target_pai_set) if pai.type == "t" || pai.number == 5 return false else inner_numbers = pai.number < 5 ? ((pai.number + 1)..5) : (5..(pai.number - 1)) return inner_numbers.any?(){ |n| target_pai_set.has_key?(Pai.new(pai.type, n)) } end end |
#senkisuji_of(pai, target_pai_set) ⇒ Object
380 381 382 383 384 385 386 387 |
# File 'lib/mjai/manue/danger_estimator.rb', line 380 def senkisuji_of(pai, target_pai_set) if pai.type == "t" return false else sujis = get_possible_sujis(pai) return sujis.any?(){ |s| target_pai_set.has_key?(s.next(-2)) || target_pai_set.has_key?(s.next(5)) } end end |
#suji_of(pai, target_pai_set) ⇒ Object
320 321 322 323 324 325 326 |
# File 'lib/mjai/manue/danger_estimator.rb', line 320 def suji_of(pai, target_pai_set) if pai.type == "t" return false else return get_suji_numbers(pai).all?(){ |n| target_pai_set.has_key?(Pai.new(pai.type, n)) } end end |
#to_pai_set(pais) ⇒ Object
69 70 71 72 73 74 75 |
# File 'lib/mjai/manue/danger_estimator.rb', line 69 def to_pai_set(pais) pai_set = Hash.new(0) for pai in pais pai_set[pai.remove_red()] += 1 end return pai_set end |
#urasuji_of(pai, target_pai_set) ⇒ Object
371 372 373 374 375 376 377 378 |
# File 'lib/mjai/manue/danger_estimator.rb', line 371 def urasuji_of(pai, target_pai_set) if pai.type == "t" return false else sujis = get_possible_sujis(pai) return sujis.any?(){ |s| target_pai_set.has_key?(s.next(-1)) || target_pai_set.has_key?(s.next(4)) } end end |
#visible_n_or_more(pai, n) ⇒ Object
367 368 369 |
# File 'lib/mjai/manue/danger_estimator.rb', line 367 def visible_n_or_more(pai, n) return @visible_set[pai] >= n end |
#weak_suji_of(pai, target_pai_set) ⇒ Object
328 329 330 331 332 333 334 |
# File 'lib/mjai/manue/danger_estimator.rb', line 328 def weak_suji_of(pai, target_pai_set) if pai.type == "t" return false else return get_suji_numbers(pai).any?(){ |n| target_pai_set.has_key?(Pai.new(pai.type, n)) } end end |