Class: TenpaiWakaruMan::Hand

Inherits:
Object
  • Object
show all
Defined in:
lib/tenpai_wakaru_man/hand.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(head: nil, tiles: [], melds: []) ⇒ Hand

Returns a new instance of Hand.



19
20
21
22
23
24
25
# File 'lib/tenpai_wakaru_man/hand.rb', line 19

def initialize(head: nil, tiles: [], melds: [])
  @head  = head
  @tiles = tiles.sort_by {|tile| TILES[tile] }
  @melds  = melds.sort

  check_tile_count!
end

Instance Attribute Details

#headObject

Returns the value of attribute head.



5
6
7
# File 'lib/tenpai_wakaru_man/hand.rb', line 5

def head
  @head
end

#meldsObject

Returns the value of attribute melds.



5
6
7
# File 'lib/tenpai_wakaru_man/hand.rb', line 5

def melds
  @melds
end

#tilesObject

Returns the value of attribute tiles.



5
6
7
# File 'lib/tenpai_wakaru_man/hand.rb', line 5

def tiles
  @tiles
end

Class Method Details

.build(head: nil, tiles: [], melds: []) ⇒ Object



8
9
10
11
12
# File 'lib/tenpai_wakaru_man/hand.rb', line 8

def build(head: nil, tiles: [], melds: [])
  new(head: head, tiles: tiles, melds: melds)
rescue TileCountError
  nil
end

.parse_from(tile_str) ⇒ Object



14
15
16
# File 'lib/tenpai_wakaru_man/hand.rb', line 14

def parse_from(tile_str)
  Parser.parse(tile_str)
end

Instance Method Details

#==(other) ⇒ Object



27
28
29
# File 'lib/tenpai_wakaru_man/hand.rb', line 27

def ==(other)
  head == other.head && tiles == other.tiles && melds == other.melds
end

#all_tilesObject



81
82
83
# File 'lib/tenpai_wakaru_man/hand.rb', line 81

def all_tiles
  (tiles + melds.map(&:tiles)).flatten.sort_by {|tile| TILES[tile] }
end

#closed?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/tenpai_wakaru_man/hand.rb', line 73

def closed?
  melds.all?(&:closed?)
end

#detect_winning_handsObject



54
55
56
# File 'lib/tenpai_wakaru_man/hand.rb', line 54

def detect_winning_hands
  meld_combination.map {|melds| self.class.build(head: @head.dup, melds: melds) }.compact.select {|hand| hand.all_tiles == all_tiles }
end

#dupObject



31
32
33
# File 'lib/tenpai_wakaru_man/hand.rb', line 31

def dup
  self.class.new(head: head&.dup, tiles: tiles.dup, melds: melds.dup)
end

#inspectObject



35
36
37
# File 'lib/tenpai_wakaru_man/hand.rb', line 35

def inspect
  "#<#{self.class.name}:\"#{to_msp_notation}\", @head=#{@head.inspect}, @melds=#{@melds.map(&:to_s)}, @tiles=#{@tiles}>"
end

#meld_combinationObject



93
94
95
96
97
98
# File 'lib/tenpai_wakaru_man/hand.rb', line 93

def meld_combination
  each_with_rest((@melds + meld_candidates)).with_object([]) {|(meld, rest_candidates), result|
    rest_tiles = extract_meld(all_tiles, meld)
    result.push(*_combination(rest_candidates, Array(meld), rest_tiles))
  }.uniq {|meld_arr| meld_arr.map(&:tiles).hash }
end

#open?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/tenpai_wakaru_man/hand.rb', line 77

def open?
  !closed?
end

#ready?Boolean

Returns:

  • (Boolean)


58
59
60
61
62
63
64
# File 'lib/tenpai_wakaru_man/hand.rb', line 58

def ready?
  TILES.each_key.any? {|tile|
    hand = dup
    hand.tiles << tile
    hand.win?
  }
end

#set_head(tile) ⇒ Object



66
67
68
69
70
71
# File 'lib/tenpai_wakaru_man/hand.rb', line 66

def set_head(tile)
  self.head = tile
  @tiles.slice!(@tiles.index(tile), 2)

  self
end

#seven_pairs?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/tenpai_wakaru_man/hand.rb', line 85

def seven_pairs?
  count_by.keys.count == 7 && count_by.values.all? {|i| i == 2 }
end

#thirteen_orphans?Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/tenpai_wakaru_man/hand.rb', line 89

def thirteen_orphans?
  count_by.keys.count == 13 && all_tiles.all? {|tile| tile[/[#{Parser::HONOR_SYMBOLS}]/] || tile[/[19]/] }
end

#to_msp_notationObject Also known as: to_s



39
40
41
# File 'lib/tenpai_wakaru_man/hand.rb', line 39

def to_msp_notation
  ([Meld.new(@tiles)] + @melds).sort.map(&:msp_notation).join
end

#win?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/tenpai_wakaru_man/hand.rb', line 44

def win?
  !winning_hands.empty?
end

#winning_handsObject



48
49
50
51
52
# File 'lib/tenpai_wakaru_man/hand.rb', line 48

def winning_hands
  detect_special_form!

  @winning_hands ||= head_candidates.map {|head| dup.set_head(head) }.map {|hand| hand.detect_winning_hands }.reject(&:empty?).flatten
end