twisty_puzzles 0.0.10 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7616a5e5bd64a5beb6ea98bed6a6f6bc2dc5ae145491db533e4693cd10d0ff6d
4
- data.tar.gz: 8bc2cd597844fb86f9168c8e368c6bbb01cc34a82598ebef7f5dcb77c1e3713c
3
+ metadata.gz: f95cf6c568aab20bad9dd5d48222afd5261215984a5da7c2c18b9d3bdf315763
4
+ data.tar.gz: 713e3825d332a49805f4938b8bc2be924f3813d49e25e9997278966409bb73fe
5
5
  SHA512:
6
- metadata.gz: 42c3be051514680426bed25b66ca09b8c420f1423a778db10512c37663c42128136acf6f4e72847bed68d4111e8563ef5eb1cd427883bf2802e072853f1900b0
7
- data.tar.gz: d26d1c98f90f7bbd15474ac45f200a483983daadfae40016e5f9d2f0ca44b20a652e480f8bbfc13d939f904140358a1acc741fcbbb09306f35b51a298f3a9cf1
6
+ metadata.gz: 2e0ba5a01642a11c57a1d83aeb6b22aa4de037fcbbd6a062a2aff29028f37260cd06a38e009fe5683949a65509a899acd925bbe3b58fdf1552760d5664631ade
7
+ data.tar.gz: 3b2d41b1b10065029813152e693f0c61c6b28557e1794d16dcb4d6c7b300fd7d0d6fa94b2b23de3e01041526ef03463a05a8854b1eec1be7cfaec7ef1943debb
@@ -143,7 +143,7 @@ module TwistyPuzzles
143
143
  "Color #{c} cannot be part of the color scheme because it is a reserved color."
144
144
  end
145
145
  end
146
- raise ArgumentError unless face_symbols_to_colors.values.all? { |c| c.is_a?(Symbol) }
146
+ raise ArgumentError unless face_symbols_to_colors.values.all?(Symbol)
147
147
  end
148
148
 
149
149
  def add_missing_mappings(turned_face_symbols_to_colors, chirality_corner_source, unknown_index)
@@ -6,6 +6,7 @@ require 'twisty_puzzles/native'
6
6
 
7
7
  module TwistyPuzzles
8
8
  # Coordinate of a sticker on the cube.
9
+ # rubocop:disable Metrics/ClassLength
9
10
  class Coordinate
10
11
  def self.highest_coordinate(cube_size)
11
12
  cube_size - 1
@@ -27,7 +28,7 @@ module TwistyPuzzles
27
28
 
28
29
  # Middle coordinate for uneven numbers, the one before for even numbers
29
30
  def self.middle_or_before(cube_size)
30
- cube_size - cube_size / 2 - 1
31
+ cube_size - (cube_size / 2) - 1
31
32
  end
32
33
 
33
34
  # Middle coordinate for uneven numbers, the one after for even numbers
@@ -37,7 +38,7 @@ module TwistyPuzzles
37
38
 
38
39
  # The last coordinate that is strictly before the middle
39
40
  def self.last_before_middle(cube_size)
40
- cube_size / 2 - 1
41
+ (cube_size / 2) - 1
41
42
  end
42
43
 
43
44
  def self.canonicalize(index, cube_size)
@@ -121,6 +122,23 @@ module TwistyPuzzles
121
122
  from_indices(face, cube_size, m, m)
122
123
  end
123
124
 
125
+ def self.face(face, cube_size)
126
+ neighbor_a, neighbor_b = face.neighbors[0..1]
127
+ coordinate_range(cube_size).collect_concat do |x|
128
+ coordinate_range(cube_size).map do |y|
129
+ from_face_distances(face, cube_size, neighbor_a => x, neighbor_b => y)
130
+ end
131
+ end
132
+ end
133
+
134
+ def self.layer(face, cube_size)
135
+ face.neighbors.zip(face.neighbors.rotate(1)).collect_concat do |neighbor, next_neighbor|
136
+ coordinate_range(cube_size).map do |i|
137
+ from_face_distances(neighbor, cube_size, face => 0, next_neighbor => i)
138
+ end
139
+ end + self.face(face, cube_size)
140
+ end
141
+
124
142
  def self.edges_outside(face, cube_size)
125
143
  face.neighbors.zip(face.neighbors.rotate(1)).collect_concat do |neighbor, next_neighbor|
126
144
  1.upto(cube_size - 2).map do |i|
@@ -261,6 +279,7 @@ module TwistyPuzzles
261
279
  rots
262
280
  end
263
281
  end
282
+ # rubocop:enable Metrics/ClassLength
264
283
 
265
284
  # Coordinate of a sticker on the Skewb.
266
285
  class SkewbCoordinate
@@ -291,7 +310,7 @@ module TwistyPuzzles
291
310
 
292
311
  def self.for_corner(corner)
293
312
  native = Native::SkewbCoordinate.for_corner(corner.face_symbols)
294
- new(Face.for_face_symbol(corner.face_symbols.first), 1 + corner.piece_index % 4, native)
313
+ new(Face.for_face_symbol(corner.face_symbols.first), 1 + (corner.piece_index % 4), native)
295
314
  end
296
315
 
297
316
  def hash
@@ -34,6 +34,14 @@ module TwistyPuzzles
34
34
 
35
35
  attr_reader :piece_index, :face_symbols
36
36
 
37
+ def self.min_parseable_face_symbols
38
+ self::FACES
39
+ end
40
+
41
+ def self.max_parseable_face_symbols
42
+ self::FACES
43
+ end
44
+
37
45
  def self.generate_parts
38
46
  valid_face_symbol_combinations =
39
47
  FACE_SYMBOLS.permutation(self::FACES).select do |p|
@@ -147,7 +155,7 @@ module TwistyPuzzles
147
155
 
148
156
  def self.parse(piece_description)
149
157
  face_symbols =
150
- piece_description.upcase.strip.split('').map do |e|
158
+ piece_description.upcase.strip.chars.map do |e|
151
159
  FACE_SYMBOLS[FACE_NAMES.index(e)]
152
160
  end
153
161
  for_face_symbols(face_symbols)
@@ -327,6 +335,14 @@ module TwistyPuzzles
327
335
  class MoveableCenter < Part
328
336
  FACES = 1
329
337
 
338
+ def self.min_parseable_face_symbols
339
+ self::CORRESPONDING_PART_CLASS::FACES
340
+ end
341
+
342
+ def self.max_parseable_face_symbols
343
+ self::CORRESPONDING_PART_CLASS::FACES
344
+ end
345
+
330
346
  def self.min_cube_size
331
347
  4
332
348
  end
@@ -467,11 +483,15 @@ module TwistyPuzzles
467
483
  false
468
484
  end
469
485
 
486
+ def self.max_parseable_face_symbols
487
+ FACES + 1
488
+ end
489
+
470
490
  def self.for_face_symbols(face_symbols)
471
491
  # One additional face symbol is usually mentioned for wings.
472
492
  raise unless face_symbols.length == FACES || face_symbols.length == FACES + 1
473
493
 
474
- if face_symbols.length == 3
494
+ if face_symbols.length == FACES + 1
475
495
  for_corner_face_symbols(face_symbols)
476
496
  else
477
497
  for_face_symbols_internal(face_symbols)
@@ -518,7 +538,7 @@ module TwistyPuzzles
518
538
  end
519
539
 
520
540
  def num_incarnations(cube_size)
521
- cube_size > 3 ? cube_size / 2 - 1 : 0
541
+ cube_size > 3 ? (cube_size / 2) - 1 : 0
522
542
  end
523
543
 
524
544
  # One index of such a piece on a on a NxN face.
@@ -617,7 +637,7 @@ module TwistyPuzzles
617
637
  ELEMENTS = generate_parts
618
638
 
619
639
  def num_incarnations(cube_size)
620
- cube_size > 3 ? cube_size / 2 - 1 : 0
640
+ cube_size > 3 ? (cube_size / 2) - 1 : 0
621
641
  end
622
642
 
623
643
  # One index of such a piece on a on a NxN face.
@@ -643,7 +663,7 @@ module TwistyPuzzles
643
663
  if cube_size.even? || cube_size <= 3
644
664
  0
645
665
  else
646
- cube_size / 2 - 1
666
+ (cube_size / 2) - 1
647
667
  end
648
668
  end
649
669
 
@@ -68,8 +68,8 @@ module TwistyPuzzles
68
68
 
69
69
  def equivalent_slice_move?(other, cube_size)
70
70
  cube_size == 3 && other.slice_index == 1 &&
71
- (@axis_face == other.axis_face && @direction == other.direction ||
72
- @axis_face == other.axis_face.opposite && @direction == other.direction.inverse)
71
+ ((@axis_face == other.axis_face && @direction == other.direction) ||
72
+ (@axis_face == other.axis_face.opposite && @direction == other.direction.inverse))
73
73
  end
74
74
  end
75
75
 
@@ -72,9 +72,9 @@ module TwistyPuzzles
72
72
  def skewb_ascii_art_line(first_color, middle_color, last_color, num_first_color)
73
73
  raise if num_first_color > SKEWB_FACE_SIZE / 2
74
74
 
75
- first_color * num_first_color +
76
- middle_color * (SKEWB_FACE_SIZE - 2 * num_first_color) +
77
- last_color * num_first_color
75
+ (first_color * num_first_color) +
76
+ (middle_color * (SKEWB_FACE_SIZE - (2 * num_first_color))) +
77
+ (last_color * num_first_color)
78
78
  end
79
79
 
80
80
  def skewb_ascii_art(center_color, corner_colors)
@@ -116,7 +116,7 @@ module TwistyPuzzles
116
116
  front_face = face_lines(cube_state, :F, 1, 3) { |c| color_character(c, color_mode) }
117
117
  right_face = face_lines(cube_state, :R, 1, 3) { |c| color_character(c, color_mode) }
118
118
  pll_line = front_face.first + right_face.first
119
- (top_face + [pll_line] * 3).join("\n")
119
+ (top_face + ([pll_line] * 3)).join("\n")
120
120
  end
121
121
 
122
122
  def cube_string(cube_state, color_mode)
@@ -150,7 +150,7 @@ module TwistyPuzzles
150
150
  end
151
151
 
152
152
  def pad_lines(lines, padding)
153
- lines.map { |line| empty_name * padding + line }
153
+ lines.map { |line| (empty_name * padding) + line }
154
154
  end
155
155
 
156
156
  def zip_concat_lines(*args)
@@ -6,7 +6,7 @@ module TwistyPuzzles
6
6
  class MoveTypeCreator
7
7
  def initialize(capture_keys, move_class)
8
8
  raise TypeError unless move_class.is_a?(Class)
9
- raise TypeError unless capture_keys.all? { |k| k.is_a?(Symbol) }
9
+ raise TypeError unless capture_keys.all?(Symbol)
10
10
 
11
11
  @capture_keys = capture_keys.freeze
12
12
  @move_class = move_class
@@ -77,8 +77,8 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
77
77
  end
78
78
 
79
79
  # Parses at least one move.
80
- def parse_nonempty_moves
81
- moves = parse_moves
80
+ def parse_nonempty_moves_with_triggers
81
+ moves = parse_moves_with_triggers
82
82
  complain('move') if moves.empty?
83
83
  moves
84
84
  end
@@ -117,8 +117,24 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
117
117
  if @scanner.peek(1) == OPENING_BRACKET
118
118
  parse_commutator_internal
119
119
  else
120
- FakeCommutator.new(parse_moves_with_triggers)
120
+ parse_commutator_no_brackets
121
+ end
122
+ end
123
+
124
+ def parse_commutator_no_brackets
125
+ setup_or_first_part_or_algorithm = parse_moves_with_triggers
126
+ skip_spaces
127
+ if @scanner.eos? || !SEPARATORS.include?(@scanner.peek(1))
128
+ return FakeCommutator.new(setup_or_first_part_or_algorithm)
121
129
  end
130
+
131
+ setup_or_first_part = setup_or_first_part_or_algorithm
132
+ complain('move') if setup_or_first_part.empty?
133
+ separator = parse_separator
134
+ comm = parse_commutator_internal_after_separator(setup_or_first_part, separator)
135
+ skip_spaces
136
+ complain('end of commutator') unless @scanner.eos?
137
+ comm
122
138
  end
123
139
 
124
140
  def parse_algorithm
@@ -131,40 +147,69 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
131
147
  if @scanner.peek(1) == OPENING_BRACKET
132
148
  parse_pure_commutator
133
149
  else
134
- FakeCommutator.new(parse_moves_with_triggers)
150
+ parse_pure_commutator_no_brackets
135
151
  end
136
152
  end
137
153
 
138
154
  def parse_pure_commutator
139
155
  skip_spaces
140
156
  parse_open_bracket
141
- first_part = parse_nonempty_moves
157
+ first_part = parse_nonempty_moves_with_triggers
142
158
  skip_spaces
143
- complain('middle of pure commutator') unless @scanner.getch == ','
144
- second_part = parse_nonempty_moves
159
+ parse_pure_separator
160
+ second_part = parse_nonempty_moves_with_triggers
145
161
  skip_spaces
146
162
  parse_close_bracket
147
163
  PureCommutator.new(first_part, second_part)
148
164
  end
149
165
 
166
+ def parse_pure_commutator_no_brackets
167
+ first_part_or_algorithm = parse_moves_with_triggers
168
+ skip_spaces
169
+ if @scanner.eos? || !PURE_SEPARATORS.include?(@scanner.peek(1))
170
+ return FakeCommutator.new(first_part_or_algorithm)
171
+ end
172
+
173
+ first_part = first_part_or_algorithm
174
+ complain('move') if first_part.empty?
175
+ parse_pure_separator
176
+ second_part = parse_nonempty_moves_with_triggers
177
+ skip_spaces
178
+ PureCommutator.new(first_part, second_part)
179
+ end
180
+
181
+ def parse_pure_separator
182
+ complain('middle of pure commutator') unless PURE_SEPARATORS.include?(@scanner.getch)
183
+ end
184
+
150
185
  def parse_commutator_internal_after_separator(setup_or_first_part, separator)
151
- if [':', ';'].include?(separator)
186
+ if SETUP_SEPARATORS.include?(separator)
152
187
  inner_commutator = parse_setup_commutator_inner
153
188
  SetupCommutator.new(setup_or_first_part, inner_commutator)
154
- elsif separator == ','
155
- second_part = parse_nonempty_moves
189
+ elsif PURE_SEPARATORS.include?(separator)
190
+ second_part = parse_nonempty_moves_with_triggers
156
191
  PureCommutator.new(setup_or_first_part, second_part)
157
192
  else
158
193
  complain('end of setup or middle of pure commutator') unless @scanner.eos?
159
194
  end
160
195
  end
161
196
 
197
+ SETUP_SEPARATORS = %w[; :].freeze
198
+ PURE_SEPARATORS = %w[/ ,].freeze
199
+ SEPARATORS = (SETUP_SEPARATORS + PURE_SEPARATORS).freeze
200
+
201
+ def parse_separator
202
+ separator = @scanner.getch
203
+ complain('separator between commutator parts') unless SEPARATORS.include?(separator)
204
+ separator
205
+ end
206
+
162
207
  def parse_commutator_internal
163
208
  skip_spaces
164
209
  parse_open_bracket
165
- setup_or_first_part = parse_nonempty_moves
210
+ setup_or_first_part = parse_nonempty_moves_with_triggers
166
211
  skip_spaces
167
- separator = @scanner.getch
212
+ separator = parse_separator
168
213
  comm = parse_commutator_internal_after_separator(setup_or_first_part, separator)
169
214
  skip_spaces
170
215
  parse_close_bracket
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TwistyPuzzles
4
- VERSION = '0.0.10'
4
+ VERSION = '0.0.14'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twisty_puzzles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernhard F. Brodowsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-21 00:00:00.000000000 Z
11
+ date: 2021-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize