twisty_puzzles 0.0.39 → 0.0.41
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 +4 -4
- data/ext/twisty_puzzles/native/face_symbols.c +1 -1
- data/ext/twisty_puzzles/native/native.c +1 -1
- data/ext/twisty_puzzles/native/skewb_layer_fingerprint.c +1 -1
- data/lib/twisty_puzzles/axis_face_and_direction_move.rb +2 -0
- data/lib/twisty_puzzles/cancellation_helper.rb +1 -1
- data/lib/twisty_puzzles/compiled_cube_algorithm.rb +1 -1
- data/lib/twisty_puzzles/coordinate.rb +16 -3
- data/lib/twisty_puzzles/cube.rb +26 -1
- data/lib/twisty_puzzles/cube_print_helper.rb +1 -1
- data/lib/twisty_puzzles/part_cycle.rb +18 -1
- data/lib/twisty_puzzles/skewb_notation.rb +1 -1
- data/lib/twisty_puzzles/version.rb +1 -1
- metadata +7 -147
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 318db705055907b0c7da7b895b10b6450e66ee9000a09e024a9dba8cbe20d75e
|
|
4
|
+
data.tar.gz: 72833568969ddf43cfddbeebe5d1036f027dc24c097b068d23dffd5cd83bd96a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 02f6f14509fabe89c008e14fa654413ee794858b2c49f5e695e9bce13736f765ff6e87448e5acf4b25af981fa78cb1e4c559a4c6a8067a069b8b23d13c8b2c29
|
|
7
|
+
data.tar.gz: 2b7af50fe7102cb822b91bb674a85dd936ea080decfc520b70f9e43944b4ee8df9e158470c471c1a464f4ddc41ff555090855df1f5eee1b286ad0a4fcc96b23e
|
|
@@ -57,7 +57,7 @@ size_t neighbor_index(const face_index_t base_face_index, const face_index_t oth
|
|
|
57
57
|
return -1;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
void init_face_symbols() {
|
|
60
|
+
void init_face_symbols(void) {
|
|
61
61
|
face_ids[U] = rb_intern("U");
|
|
62
62
|
face_ids[F] = rb_intern("F");
|
|
63
63
|
face_ids[R] = rb_intern("R");
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
VALUE TwistyPuzzlesModule = Qnil;
|
|
15
15
|
VALUE NativeModule = Qnil;
|
|
16
16
|
|
|
17
|
-
void Init_native() {
|
|
17
|
+
void Init_native(void) {
|
|
18
18
|
TwistyPuzzlesModule = rb_define_module("TwistyPuzzles");
|
|
19
19
|
NativeModule = rb_define_module_under(TwistyPuzzlesModule, "Native");
|
|
20
20
|
init_cube_algorithm_class_under(NativeModule);
|
|
@@ -258,7 +258,7 @@ static void init_corner_pair_groups_for_face_index(const face_index_t layer_face
|
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
static void init_corner_pair_groups() {
|
|
261
|
+
static void init_corner_pair_groups(void) {
|
|
262
262
|
for (face_index_t layer_face_index = 0; layer_face_index < cube_faces; ++layer_face_index) {
|
|
263
263
|
init_corner_pair_groups_for_face_index(layer_face_index);
|
|
264
264
|
}
|
|
@@ -95,7 +95,7 @@ module TwistyPuzzles
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def self.combined_rotation_algs
|
|
98
|
-
Rotation::NON_ZERO_ROTATIONS.
|
|
98
|
+
Rotation::NON_ZERO_ROTATIONS.flat_map do |left|
|
|
99
99
|
second_rotations =
|
|
100
100
|
Rotation::NON_ZERO_ROTATIONS.reject do |e|
|
|
101
101
|
e.direction.double_move? || e.same_axis?(left)
|
|
@@ -56,7 +56,7 @@ module TwistyPuzzles
|
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def self.for_moves(cube_size, moves)
|
|
59
|
-
transformed_moves = moves.
|
|
59
|
+
transformed_moves = moves.flat_map { |m| transform_move(m, cube_size) }
|
|
60
60
|
native = Native::CubeAlgorithm.new(cube_size, transformed_moves)
|
|
61
61
|
new(native)
|
|
62
62
|
end
|
|
@@ -124,7 +124,7 @@ module TwistyPuzzles
|
|
|
124
124
|
|
|
125
125
|
def self.face(face, cube_size)
|
|
126
126
|
neighbor_a, neighbor_b = face.neighbors[0..1]
|
|
127
|
-
coordinate_range(cube_size).
|
|
127
|
+
coordinate_range(cube_size).flat_map do |x|
|
|
128
128
|
coordinate_range(cube_size).map do |y|
|
|
129
129
|
from_face_distances(face, cube_size, neighbor_a => x, neighbor_b => y)
|
|
130
130
|
end
|
|
@@ -132,7 +132,7 @@ module TwistyPuzzles
|
|
|
132
132
|
end
|
|
133
133
|
|
|
134
134
|
def self.layer(face, cube_size)
|
|
135
|
-
face.neighbors.zip(face.neighbors.rotate(1)).
|
|
135
|
+
face.neighbors.zip(face.neighbors.rotate(1)).flat_map do |neighbor, next_neighbor|
|
|
136
136
|
coordinate_range(cube_size).map do |i|
|
|
137
137
|
from_face_distances(neighbor, cube_size, face => 0, next_neighbor => i)
|
|
138
138
|
end
|
|
@@ -140,7 +140,7 @@ module TwistyPuzzles
|
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
def self.edges_outside(face, cube_size)
|
|
143
|
-
face.neighbors.zip(face.neighbors.rotate(1)).
|
|
143
|
+
face.neighbors.zip(face.neighbors.rotate(1)).flat_map do |neighbor, next_neighbor|
|
|
144
144
|
1.upto(cube_size - 2).map do |i|
|
|
145
145
|
from_face_distances(neighbor, cube_size, face => 0, next_neighbor => i)
|
|
146
146
|
end
|
|
@@ -179,6 +179,19 @@ module TwistyPuzzles
|
|
|
179
179
|
|
|
180
180
|
attr_reader :native
|
|
181
181
|
|
|
182
|
+
def distance_to(to_face)
|
|
183
|
+
return 0 if face == to_face
|
|
184
|
+
return cube_size if face == to_face.opposite
|
|
185
|
+
|
|
186
|
+
index = face.coordinate_index_close_to(to_face)
|
|
187
|
+
coordinate = coordinate(index)
|
|
188
|
+
if to_face.close_to_smaller_indices?
|
|
189
|
+
coordinate
|
|
190
|
+
else
|
|
191
|
+
Coordinate.invert_coordinate(coordinate, cube_size)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
182
195
|
def face
|
|
183
196
|
@face ||= Face.for_face_symbol(@native.face)
|
|
184
197
|
end
|
data/lib/twisty_puzzles/cube.rb
CHANGED
|
@@ -148,6 +148,17 @@ module TwistyPuzzles
|
|
|
148
148
|
self.class.for_face_symbols(@face_symbols.rotate(number))
|
|
149
149
|
end
|
|
150
150
|
|
|
151
|
+
def rotate_by_rotation(rotation)
|
|
152
|
+
rotated_face_symbols = corresponding_part.faces.map { |f| f.rotate_by_rotation(rotation) }
|
|
153
|
+
self.class.for_face_symbols(rotated_face_symbols.map(&:face_symbol))
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def mirror(normal_face)
|
|
157
|
+
mirrored_face_symbols = corresponding_part.faces.map { |f| f.mirror(normal_face) }
|
|
158
|
+
transformed_face_symbols = mirrored_face_symbols.reverse.rotate(@face_symbols.length - 1)
|
|
159
|
+
self.class.for_face_symbols(transformed_face_symbols.map(&:face_symbol))
|
|
160
|
+
end
|
|
161
|
+
|
|
151
162
|
# Returns true if the pieces are equal modulo rotation.
|
|
152
163
|
def turned_equals?(other)
|
|
153
164
|
@face_symbols.include?(other.face_symbols.first) &&
|
|
@@ -207,6 +218,20 @@ module TwistyPuzzles
|
|
|
207
218
|
|
|
208
219
|
ELEMENTS = generate_parts
|
|
209
220
|
|
|
221
|
+
def rotate_by_rotation(rotation)
|
|
222
|
+
return self if same_axis?(rotation.axis_face)
|
|
223
|
+
|
|
224
|
+
rotation_neighbors = rotation.axis_face.neighbors.reverse
|
|
225
|
+
face_index = rotation_neighbors.index(self)
|
|
226
|
+
raise unless face_index
|
|
227
|
+
|
|
228
|
+
rotation_neighbors[(face_index + rotation.direction.value) % rotation_neighbors.length]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def mirror(normal_face)
|
|
232
|
+
same_axis?(normal_face) ? opposite : self
|
|
233
|
+
end
|
|
234
|
+
|
|
210
235
|
# Whether closeness to this face results in smaller indices for the stickers of other faces.
|
|
211
236
|
def close_to_smaller_indices?
|
|
212
237
|
@piece_index < 3
|
|
@@ -359,7 +384,7 @@ module TwistyPuzzles
|
|
|
359
384
|
def self.for_face_symbols(face_symbols)
|
|
360
385
|
unless face_symbols.length == self::CORRESPONDING_PART_CLASS::FACES
|
|
361
386
|
raise ArgumentError, "Need #{self::CORRESPONDING_PART_CLASS::FACES} face_symbols for a " \
|
|
362
|
-
"#{
|
|
387
|
+
"#{name}, have #{face_symbols.inspect}."
|
|
363
388
|
end
|
|
364
389
|
|
|
365
390
|
corresponding_part = self::CORRESPONDING_PART_CLASS.for_face_symbols(face_symbols)
|
|
@@ -56,7 +56,7 @@ module TwistyPuzzles
|
|
|
56
56
|
face_symbol_info = FACE_SYMBOL_INFOS[face_symbol]
|
|
57
57
|
stickers = cube_state.sticker_array(face)
|
|
58
58
|
lines =
|
|
59
|
-
stickers.
|
|
59
|
+
stickers.flat_map do |sticker_line|
|
|
60
60
|
line = sticker_line.map { |c| yield(c) * column_multiplicity }
|
|
61
61
|
[maybe_reverse(face_symbol_info.reverse_columns_mode, line).join] * row_multiplicity
|
|
62
62
|
end
|
|
@@ -108,8 +108,11 @@ module TwistyPuzzles
|
|
|
108
108
|
self == other || canonicalize == other.canonicalize
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
+
def inverse_twist
|
|
112
|
+
@twist.zero? ? @twist : parts.first.rotations.length - @twist
|
|
113
|
+
end
|
|
114
|
+
|
|
111
115
|
def inverse
|
|
112
|
-
inverse_twist = @twist.zero? ? @twist : parts.first.rotations.length - @twist
|
|
113
116
|
self.class.new([@parts[0]] + @parts[1..].reverse, inverse_twist)
|
|
114
117
|
end
|
|
115
118
|
|
|
@@ -121,6 +124,20 @@ module TwistyPuzzles
|
|
|
121
124
|
new(parts, twist)
|
|
122
125
|
end
|
|
123
126
|
|
|
127
|
+
def rotate_by_rotation(rotation)
|
|
128
|
+
raise TypeError unless rotation.is_a?(Rotation)
|
|
129
|
+
|
|
130
|
+
rotated_parts = @parts.map { |p| p.rotate_by_rotation(rotation) }
|
|
131
|
+
PartCycle.new(rotated_parts, @twist)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def mirror(normal_face)
|
|
135
|
+
raise TypeError unless normal_face.is_a?(Face)
|
|
136
|
+
|
|
137
|
+
mirrored_parts = @parts.map { |p| p.mirror(normal_face) }
|
|
138
|
+
self.class.new(mirrored_parts, inverse_twist)
|
|
139
|
+
end
|
|
140
|
+
|
|
124
141
|
private
|
|
125
142
|
|
|
126
143
|
def twist_suffix
|
|
@@ -18,7 +18,7 @@ module TwistyPuzzles
|
|
|
18
18
|
check_move_corner_pairs(move_corner_pairs)
|
|
19
19
|
@name = name
|
|
20
20
|
@move_to_corner = move_corner_pairs.to_h.freeze
|
|
21
|
-
@corner_to_move = move_corner_pairs.
|
|
21
|
+
@corner_to_move = move_corner_pairs.flat_map do |m, c|
|
|
22
22
|
c.rotations.map { |e| [e, m] }
|
|
23
23
|
end.to_h.freeze
|
|
24
24
|
@move_strings = move_corner_pairs.map(&:first).freeze
|
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.
|
|
4
|
+
version: 0.0.41
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bernhard F. Brodowsky
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: colorize
|
|
@@ -24,147 +24,7 @@ dependencies:
|
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: '0'
|
|
27
|
-
|
|
28
|
-
name: pry
|
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
|
30
|
-
requirements:
|
|
31
|
-
- - ">="
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
34
|
-
type: :development
|
|
35
|
-
prerelease: false
|
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
-
requirements:
|
|
38
|
-
- - ">="
|
|
39
|
-
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
- !ruby/object:Gem::Dependency
|
|
42
|
-
name: rake
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '13.0'
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '13.0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: rake-compiler
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - ">="
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - ">="
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rantly
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - ">="
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0'
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - ">="
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0'
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: rspec
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - "~>"
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: '3.8'
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - "~>"
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: '3.8'
|
|
97
|
-
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: rspec-prof
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - ">="
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: '0'
|
|
104
|
-
type: :development
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - ">="
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: '0'
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: rubocop
|
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
|
114
|
-
requirements:
|
|
115
|
-
- - "~>"
|
|
116
|
-
- !ruby/object:Gem::Version
|
|
117
|
-
version: '1.38'
|
|
118
|
-
type: :development
|
|
119
|
-
prerelease: false
|
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
requirements:
|
|
122
|
-
- - "~>"
|
|
123
|
-
- !ruby/object:Gem::Version
|
|
124
|
-
version: '1.38'
|
|
125
|
-
- !ruby/object:Gem::Dependency
|
|
126
|
-
name: rubocop-performance
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
132
|
-
type: :development
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0'
|
|
139
|
-
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: rubocop-rake
|
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
|
142
|
-
requirements:
|
|
143
|
-
- - ">="
|
|
144
|
-
- !ruby/object:Gem::Version
|
|
145
|
-
version: '0'
|
|
146
|
-
type: :development
|
|
147
|
-
prerelease: false
|
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
-
requirements:
|
|
150
|
-
- - ">="
|
|
151
|
-
- !ruby/object:Gem::Version
|
|
152
|
-
version: '0'
|
|
153
|
-
- !ruby/object:Gem::Dependency
|
|
154
|
-
name: simplecov
|
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
|
156
|
-
requirements:
|
|
157
|
-
- - ">="
|
|
158
|
-
- !ruby/object:Gem::Version
|
|
159
|
-
version: '0'
|
|
160
|
-
type: :development
|
|
161
|
-
prerelease: false
|
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
-
requirements:
|
|
164
|
-
- - ">="
|
|
165
|
-
- !ruby/object:Gem::Version
|
|
166
|
-
version: '0'
|
|
167
|
-
description:
|
|
27
|
+
description:
|
|
168
28
|
email: bernhard.brodowsky@gmail.com
|
|
169
29
|
executables: []
|
|
170
30
|
extensions:
|
|
@@ -248,7 +108,7 @@ metadata:
|
|
|
248
108
|
source_code_uri: https://github.com/Lykos/twisty_puzzles
|
|
249
109
|
changelog_uri: https://github.com/Lykos/twisty_puzzles/blob/master/CHANGELOG.md
|
|
250
110
|
rubygems_mfa_required: 'true'
|
|
251
|
-
post_install_message:
|
|
111
|
+
post_install_message:
|
|
252
112
|
rdoc_options: []
|
|
253
113
|
require_paths:
|
|
254
114
|
- lib
|
|
@@ -263,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
263
123
|
- !ruby/object:Gem::Version
|
|
264
124
|
version: '0'
|
|
265
125
|
requirements: []
|
|
266
|
-
rubygems_version: 3.2.
|
|
267
|
-
signing_key:
|
|
126
|
+
rubygems_version: 3.2.33
|
|
127
|
+
signing_key:
|
|
268
128
|
specification_version: 4
|
|
269
129
|
summary: Gem for my cube_trainer rails app. Some things are better left in a separate
|
|
270
130
|
gem with no rails, e.g. native extensions. The main purpose is to support my Rails
|