Class: TwistyPuzzles::Face

Inherits:
Part
  • Object
show all
Defined in:
lib/twisty_puzzles/cube.rb

Overview

This is an unmoveable center piece, it’s mostly used as a helper class for other pieces.

Constant Summary collapse

FACES =
1
ELEMENTS =
generate_parts

Constants included from CubeConstants

CubeConstants::ALPHABET_SIZE, CubeConstants::CHIRALITY_FACE_SYMBOLS, CubeConstants::FACE_NAMES, CubeConstants::FACE_SYMBOLS, CubeConstants::OPPOSITE_FACE_SYMBOLS, CubeConstants::SKEWB_STICKERS

Instance Attribute Summary

Attributes inherited from Part

#face_symbols, #piece_index

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Part

#<=>, #base_index_on_face, #base_index_on_other_face, #corresponding_part, #eql?, exists_on_cube_size?, exists_on_odd_cube_sizes?, #faces, for_face_symbols, for_face_symbols_internal, for_index, generate_parts, #hash, #initialize, #inspect, max_cube_size, max_parseable_face_symbols, min_parseable_face_symbols, #num_incarnations, parse, #rotate_by, #rotate_face_symbol_up, #rotate_face_up, #rotations, #solved_coordinate, #solved_face, #to_s, #turned_equals?

Methods included from Utils::ArrayHelper

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

Methods included from CubeConstants

#chirality_canonical_face_symbol, #opposite_face_symbol, #valid_chirality?

Constructor Details

This class inherits a constructor from TwistyPuzzles::Part

Class Method Details

.by_name(name) ⇒ Object



286
287
288
289
290
291
# File 'lib/twisty_puzzles/cube.rb', line 286

def self.by_name(name)
  index = FACE_NAMES.index(name.upcase)
  raise "#{name} is not a valid #{self.class.name}." unless index

  ELEMENTS[index]
end

.exists_on_even_cube_sizes?Boolean

Returns:

  • (Boolean)


207
208
209
# File 'lib/twisty_puzzles/cube.rb', line 207

def self.exists_on_even_cube_sizes?
  false
end

.for_face_symbol(face_symbol) ⇒ Object



211
212
213
# File 'lib/twisty_puzzles/cube.rb', line 211

def self.for_face_symbol(face_symbol)
  for_face_symbols([face_symbol])
end

.min_cube_sizeObject



203
204
205
# File 'lib/twisty_puzzles/cube.rb', line 203

def self.min_cube_size
  3
end

.valid?(_face_symbols) ⇒ Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/twisty_puzzles/cube.rb', line 215

def self.valid?(_face_symbols)
  true
end

Instance Method Details

#axis_priorityObject

Priority of the closeness to this face. This is used to index the stickers on other faces.



274
275
276
# File 'lib/twisty_puzzles/cube.rb', line 274

def axis_priority
  @axis_priority ||= [@piece_index, CubeConstants::FACE_SYMBOLS.length - 1 - @piece_index].min
end

#canonical_axis_face?Boolean

Returns:

  • (Boolean)


278
279
280
# File 'lib/twisty_puzzles/cube.rb', line 278

def canonical_axis_face?
  close_to_smaller_indices?
end

#clockwise_cornersObject



334
335
336
# File 'lib/twisty_puzzles/cube.rb', line 334

def clockwise_corners
  neighbors.zip(neighbors.rotate).map { |a, b| Corner.between_faces([self, a, b]) }
end

#clockwise_neighbor_after(neighbor) ⇒ Object

Raises:

  • (ArgumentError)


310
311
312
313
314
# File 'lib/twisty_puzzles/cube.rb', line 310

def clockwise_neighbor_after(neighbor)
  raise ArgumentError if same_axis?(neighbor)

  @neighbors[(@neighbors.index(neighbor) + 1) % @neighbors.length]
end

#close_to_smaller_indices?Boolean

Whether closeness to this face results in smaller indices for the stickers of other faces.

Returns:

  • (Boolean)


237
238
239
# File 'lib/twisty_puzzles/cube.rb', line 237

def close_to_smaller_indices?
  @piece_index < 3
end

#coordinate_index_base_face(coordinate_index) ⇒ Object



241
242
243
244
245
246
# File 'lib/twisty_puzzles/cube.rb', line 241

def coordinate_index_base_face(coordinate_index)
  (@coordinate_index_base_face ||= {})[coordinate_index] ||=
    find_only(neighbors) do |n|
      n.close_to_smaller_indices? && coordinate_index_close_to(n) == coordinate_index
    end
end

#coordinate_index_close_to(to_face) ⇒ Object

Returns the index of the coordinate that is used to determine how close a sticker on ‘on_face` is to `to_face`.



258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/twisty_puzzles/cube.rb', line 258

def coordinate_index_close_to(to_face)
  if same_axis?(to_face)
    raise ArgumentError, "Cannot get the coordinate index close to #{to_face.inspect} " \
                         "on #{inspect} because they are not neighbors."
  end

  to_priority = to_face.axis_priority
  if axis_priority < to_priority
    to_priority - 1
  else
    to_priority
  end
end

#face_symbolObject



293
294
295
# File 'lib/twisty_puzzles/cube.rb', line 293

def face_symbol
  @face_symbols[0]
end

#mirror(normal_face) ⇒ Object



232
233
234
# File 'lib/twisty_puzzles/cube.rb', line 232

def mirror(normal_face)
  same_axis?(normal_face) ? opposite : self
end

#nameObject



282
283
284
# File 'lib/twisty_puzzles/cube.rb', line 282

def name
  @name ||= FACE_NAMES[ELEMENTS.index(self)]
end

#neighborsObject

Neighbor faces in clockwise order.



298
299
300
301
302
303
304
305
306
307
308
# File 'lib/twisty_puzzles/cube.rb', line 298

def neighbors
  @neighbors ||=
    begin
      partial_neighbors =
        self.class::ELEMENTS.select do |e|
          !same_axis?(e) && e.canonical_axis_face?
        end
      ordered_partial_neighbors = sort_partial_neighbors(partial_neighbors)
      ordered_partial_neighbors + ordered_partial_neighbors.map(&:opposite)
    end
end

#oppositeObject



248
249
250
# File 'lib/twisty_puzzles/cube.rb', line 248

def opposite
  Face.for_face_symbol(opposite_face_symbol(face_symbol))
end

#rotate_by_rotation(rotation) ⇒ Object



221
222
223
224
225
226
227
228
229
230
# File 'lib/twisty_puzzles/cube.rb', line 221

def rotate_by_rotation(rotation)
  return self if same_axis?(rotation.axis_face)

  rotation_neighbors = rotation.axis_face.neighbors.reverse
  face_index = rotation_neighbors.index(self)
  raise unless face_index

  after_rotation_index = face_index + rotation_neighbors.length - rotation.direction.value
  rotation_neighbors[after_rotation_index % rotation_neighbors.length]
end

#rotation_to(other) ⇒ Object

Returns the algorithm that performs a rotation after which the current face will lie where the given other face currently is.



318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/twisty_puzzles/cube.rb', line 318

def rotation_to(other)
  if other == self
    Algorithm.empty
  else
    # There can be multiple solutions.
    axis_face =
      self.class::ELEMENTS.find do |e|
        !same_axis?(e) && !other.same_axis?(e) && e.canonical_axis_face?
      end
    direction = rotation_direction_to(other)
    Algorithm.move(Rotation.new(axis_face, direction))
  end
end

#same_axis?(other) ⇒ Boolean

Returns:

  • (Boolean)


252
253
254
# File 'lib/twisty_puzzles/cube.rb', line 252

def same_axis?(other)
  axis_priority == other.axis_priority
end