Module: TwistyPuzzles::CubePrintHelper

Includes:
Utils::ArrayHelper
Included in:
CubeState, SkewbState
Defined in:
lib/twisty_puzzles/cube_print_helper.rb

Overview

Module to print and display cube and Skewb states.

Defined Under Namespace

Classes: ColorInfo

Constant Summary collapse

COLOR_MODES =
%i[color nocolor].freeze
FACE_SYMBOL_INFOS =
{
  U: ColorInfo.new(:reverse, :reverse, [2, 3, 0, 1]),
  L: ColorInfo.new(:keep, :reverse, [2, 0, 3, 1]),
  F: ColorInfo.new(:keep, :reverse, [2, 0, 3, 1]),
  R: ColorInfo.new(:keep, :keep, [1, 0, 3, 2]),
  B: ColorInfo.new(:keep, :keep, [1, 0, 3, 2]),
  D: ColorInfo.new(:keep, :reverse, [2, 0, 3, 1])
}.freeze
SKEWB_FACE_SIZE =
5

Instance Method Summary collapse

Methods included from Utils::ArrayHelper

#apply_permutation, #check_types, #find_only, #only, #replace_once, #rotate_out_nils, #turned_equals?

Instance Method Details

#color_character(color, color_mode) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 30

def color_character(color, color_mode)
  unless COLOR_MODES.include?(color_mode)
    raise ArgumentError, "Invalid color mode #{color_mode}"
  end

  char = color.to_s[0].upcase
  if color_mode == :color
    char.colorize(background: color_symbol(color))
  else
    char
  end
end

#color_symbol(color) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 11

def color_symbol(color)
  case color
  when :orange then :light_red
  when :unknown then :light_black
  else color
  end
end

#cube_string(cube_state, color_mode) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 122

def cube_string(cube_state, color_mode)
  top_face = simple_face_lines(cube_state, :U, color_mode)
  left_face = simple_face_lines(cube_state, :L, color_mode)
  front_face = simple_face_lines(cube_state, :F, color_mode)
  right_face = simple_face_lines(cube_state, :R, color_mode)
  back_face = simple_face_lines(cube_state, :B, color_mode)
  bottom_face = simple_face_lines(cube_state, :D, color_mode)
  middle_belt = zip_concat_lines(left_face, front_face, right_face, back_face)
  lines = pad_lines(top_face, cube_state.n) + middle_belt +
          pad_lines(bottom_face, cube_state.n)
  lines.join("\n")
end

#empty_nameObject



148
149
150
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 148

def empty_name
  ' '
end

#face_lines(cube_state, face_symbol, row_multiplicity = 1, column_multiplicity = 1) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 54

def face_lines(cube_state, face_symbol, row_multiplicity = 1, column_multiplicity = 1)
  face = Face.for_face_symbol(face_symbol)
  face_symbol_info = FACE_SYMBOL_INFOS[face_symbol]
  stickers = cube_state.sticker_array(face)
  lines =
    stickers.flat_map do |sticker_line|
      line = sticker_line.map { |c| yield(c) * column_multiplicity }
      [maybe_reverse(face_symbol_info.reverse_columns_mode, line).join] * row_multiplicity
    end
  maybe_reverse(face_symbol_info.reverse_lines_mode, lines)
end

#ll_string(cube_state, color_mode) ⇒ Object



114
115
116
117
118
119
120
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 114

def ll_string(cube_state, color_mode)
  top_face = face_lines(cube_state, :U, 2, 3) { |c| color_character(c, color_mode) }
  front_face = face_lines(cube_state, :F, 1, 3) { |c| color_character(c, color_mode) }
  right_face = face_lines(cube_state, :R, 1, 3) { |c| color_character(c, color_mode) }
  pll_line = front_face.first + right_face.first
  (top_face + ([pll_line] * 3)).join("\n")
end

#maybe_reverse(reverse_mode, stuff) ⇒ Object



43
44
45
46
47
48
49
50
51
52
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 43

def maybe_reverse(reverse_mode, stuff)
  case reverse_mode
  when :reverse
    stuff.reverse
  when :keep
    stuff
  else
    raise
  end
end

#pad_lines(lines, padding) ⇒ Object



152
153
154
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 152

def pad_lines(lines, padding)
  lines.map { |line| (empty_name * padding) + line }
end

#simple_face_lines(cube_state, face_symbol, color_mode) ⇒ Object



66
67
68
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 66

def simple_face_lines(cube_state, face_symbol, color_mode)
  face_lines(cube_state, face_symbol) { |c| color_character(c, color_mode) }
end

#skewb_ascii_art(center_color, corner_colors) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 80

def skewb_ascii_art(center_color, corner_colors)
  raise unless corner_colors.length == 4

  first_part =
    (1..SKEWB_FACE_SIZE / 2).to_a.reverse.map do |i|
      skewb_ascii_art_line(corner_colors[0], center_color, corner_colors[1], i)
    end
  middle_part = SKEWB_FACE_SIZE.odd? ? [center_color * SKEWB_FACE_SIZE] : []
  last_part =
    (1..SKEWB_FACE_SIZE / 2).map do |i|
      skewb_ascii_art_line(corner_colors[2], center_color, corner_colors[3], i)
    end
  first_part + middle_part + last_part
end

#skewb_ascii_art_line(first_color, middle_color, last_color, num_first_color) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 72

def skewb_ascii_art_line(first_color, middle_color, last_color, num_first_color)
  raise if num_first_color > SKEWB_FACE_SIZE / 2

  (first_color * num_first_color) +
    (middle_color * (SKEWB_FACE_SIZE - (2 * num_first_color))) +
    (last_color * num_first_color)
end

#skewb_face_lines(cube_state, face_symbol, color_mode) ⇒ Object

Prints a Skewb face like this: rrgww rgggw ggggg ogggb oogbb



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 101

def skewb_face_lines(cube_state, face_symbol, color_mode)
  face = Face.for_face_symbol(face_symbol)
  face_symbol_info = FACE_SYMBOL_INFOS[face_symbol]
  stickers = cube_state.sticker_array(face)
  center_color = color_character(stickers[0], color_mode)
  corner_colors = stickers[1..].map { |c| color_character(c, color_mode) }
  permuted_corner_colors =
    apply_permutation(corner_colors, face_symbol_info.skewb_corner_permutation)
  raise unless corner_colors.length == 4

  skewb_ascii_art(center_color, permuted_corner_colors)
end

#skewb_string(skewb_state, color_mode) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 135

def skewb_string(skewb_state, color_mode)
  top_face = skewb_face_lines(skewb_state, :U, color_mode)
  left_face = skewb_face_lines(skewb_state, :L, color_mode)
  front_face = skewb_face_lines(skewb_state, :F, color_mode)
  right_face = skewb_face_lines(skewb_state, :R, color_mode)
  back_face = skewb_face_lines(skewb_state, :B, color_mode)
  bottom_face = skewb_face_lines(skewb_state, :D, color_mode)
  middle_belt = zip_concat_lines(left_face, front_face, right_face, back_face)
  lines = pad_lines(top_face, SKEWB_FACE_SIZE) + middle_belt +
          pad_lines(bottom_face, SKEWB_FACE_SIZE)
  lines.join("\n")
end

#zip_concat_lines(*args) ⇒ Object



156
157
158
# File 'lib/twisty_puzzles/cube_print_helper.rb', line 156

def zip_concat_lines(*args)
  args.transpose.map(&:join)
end