twisty_puzzles 0.0.15 → 0.0.20
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/native.c +2 -0
- data/ext/twisty_puzzles/native/sticker_cycle.c +196 -0
- data/ext/twisty_puzzles/native/sticker_cycle.h +5 -0
- data/lib/twisty_puzzles/abstract_direction.rb +1 -1
- data/lib/twisty_puzzles/color_scheme.rb +10 -0
- data/lib/twisty_puzzles/cube_state.rb +4 -6
- data/lib/twisty_puzzles/parser.rb +2 -0
- data/lib/twisty_puzzles/part_cycle.rb +40 -0
- data/lib/twisty_puzzles/rotation.rb +1 -0
- data/lib/twisty_puzzles/skewb_state.rb +0 -11
- data/lib/twisty_puzzles/sticker_cycle.rb +33 -8
- data/lib/twisty_puzzles/{part_cycle_factory.rb → sticker_cycle_factory.rb} +4 -3
- data/lib/twisty_puzzles/version.rb +1 -1
- data/lib/twisty_puzzles.rb +2 -2
- metadata +7 -5
- data/lib/twisty_puzzles/state_helper.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b520c95ebe0051fb847be3781d6f82a6b2f41f00e006e3935157d8c6c3843726
|
4
|
+
data.tar.gz: 8cfb1439b07cf4983d17198952d56ae4b903afa994c67c549ea210063bc42eb9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b841bc0e3f1de064c2bee48eaf041528abeec5b3751486b380933ead4633ea78430445793351bf3a80eff1da9d2b535ecea6dd63ace544c18f0a456b5fd348fe
|
7
|
+
data.tar.gz: 8732d36c49fc52b9292401b82b1b795f6f00994bb0ab80d2cbb029555af383fd20769cb083bb7d2af3348d7fda7811d76b693764f30699a79d239bde2cf93151
|
@@ -9,6 +9,7 @@
|
|
9
9
|
#include "skewb_coordinate.h"
|
10
10
|
#include "skewb_layer_fingerprint.h"
|
11
11
|
#include "skewb_state.h"
|
12
|
+
#include "sticker_cycle.h"
|
12
13
|
|
13
14
|
VALUE TwistyPuzzlesModule = Qnil;
|
14
15
|
VALUE NativeModule = Qnil;
|
@@ -25,4 +26,5 @@ void Init_native() {
|
|
25
26
|
init_skewb_coordinate_class_under(NativeModule);
|
26
27
|
init_skewb_layer_fingerprint_method_under(NativeModule);
|
27
28
|
init_skewb_state_class_under(NativeModule);
|
29
|
+
init_sticker_cycle_class_under(NativeModule);
|
28
30
|
}
|
@@ -0,0 +1,196 @@
|
|
1
|
+
#include "cube_state.h"
|
2
|
+
|
3
|
+
#include "cube_coordinate.h"
|
4
|
+
#include "cube_state.h"
|
5
|
+
#include "utils.h"
|
6
|
+
|
7
|
+
static ID reverse;
|
8
|
+
|
9
|
+
typedef struct {
|
10
|
+
long cube_size;
|
11
|
+
size_t length;
|
12
|
+
VALUE coordinates;
|
13
|
+
size_t* indices;
|
14
|
+
} StickerCycleData;
|
15
|
+
|
16
|
+
extern const rb_data_type_t StickerCycleData_type;
|
17
|
+
|
18
|
+
#define GetStickerCycleData(obj, data) \
|
19
|
+
do { \
|
20
|
+
TypedData_Get_Struct((obj), StickerCycleData, &StickerCycleData_type, (data)); \
|
21
|
+
} while (0)
|
22
|
+
|
23
|
+
#define GetInitializedStickerCycleData(obj, data) \
|
24
|
+
do { \
|
25
|
+
GetStickerCycleData((obj), (data)); \
|
26
|
+
if (data->indices == NULL) { \
|
27
|
+
rb_raise(rb_eArgError, "Sticker cycle isn't initialized."); \
|
28
|
+
} \
|
29
|
+
} while(0)
|
30
|
+
|
31
|
+
static VALUE StickerCycleClass = Qnil;
|
32
|
+
|
33
|
+
static void StickerCycleData_mark(void* const ptr) {
|
34
|
+
const StickerCycleData* data = ptr;
|
35
|
+
rb_gc_mark(data->coordinates);
|
36
|
+
}
|
37
|
+
|
38
|
+
static void StickerCycleData_free(void* const ptr) {
|
39
|
+
const StickerCycleData* const data = ptr;
|
40
|
+
free(data->indices);
|
41
|
+
free(ptr);
|
42
|
+
}
|
43
|
+
|
44
|
+
static size_t StickerCycleData_size(const void* const ptr) {
|
45
|
+
const StickerCycleData* const data = ptr;
|
46
|
+
return sizeof(StickerCycleData) + num_stickers(data->cube_size) * sizeof(VALUE);
|
47
|
+
}
|
48
|
+
|
49
|
+
const rb_data_type_t StickerCycleData_type = {
|
50
|
+
"TwistyPuzzles::Native::StickerCycleData",
|
51
|
+
{StickerCycleData_mark, StickerCycleData_free, StickerCycleData_size, NULL},
|
52
|
+
NULL, NULL,
|
53
|
+
RUBY_TYPED_FREE_IMMEDIATELY
|
54
|
+
};
|
55
|
+
|
56
|
+
static VALUE* malloc_indices(const size_t n) {
|
57
|
+
VALUE* const indices = malloc(n * sizeof(size_t));
|
58
|
+
if (indices == NULL) {
|
59
|
+
rb_raise(rb_eNoMemError, "Allocating sticker cycle failed.");
|
60
|
+
}
|
61
|
+
return indices;
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE StickerCycle_alloc(const VALUE klass) {
|
65
|
+
StickerCycleData* data;
|
66
|
+
const VALUE object = TypedData_Make_Struct(klass, StickerCycleData, &StickerCycleData_type, data);
|
67
|
+
data->cube_size = 0;
|
68
|
+
data->length = 0;
|
69
|
+
data->coordinates = Qnil;
|
70
|
+
data->indices = NULL;
|
71
|
+
return object;
|
72
|
+
}
|
73
|
+
|
74
|
+
static VALUE StickerCycle_initialize(const VALUE self, const VALUE cube_size, const VALUE coordinates) {
|
75
|
+
Check_Type(cube_size, T_FIXNUM);
|
76
|
+
Check_Type(coordinates, T_ARRAY);
|
77
|
+
const long checked_cube_size = FIX2INT(cube_size);
|
78
|
+
check_cube_size(checked_cube_size);
|
79
|
+
const size_t n = RARRAY_LEN(coordinates);
|
80
|
+
StickerCycleData* data;
|
81
|
+
GetStickerCycleData(self, data);
|
82
|
+
data->cube_size = checked_cube_size;
|
83
|
+
data->length = n;
|
84
|
+
data->coordinates = coordinates;
|
85
|
+
data->indices = malloc_indices(data->length);
|
86
|
+
for (size_t i = 0; i < n; ++i) {
|
87
|
+
const VALUE coordinate = rb_ary_entry(coordinates, i);
|
88
|
+
data->indices[i] = CubeCoordinate_sticker_index(coordinate, checked_cube_size);
|
89
|
+
}
|
90
|
+
return self;
|
91
|
+
}
|
92
|
+
|
93
|
+
static VALUE StickerCycle_apply_to(const VALUE self, const VALUE cube_state) {
|
94
|
+
const StickerCycleData* sticker_cycle_data;
|
95
|
+
GetInitializedStickerCycleData(self, sticker_cycle_data);
|
96
|
+
|
97
|
+
const CubeStateData* cube_state_data;
|
98
|
+
GetInitializedCubeStateData(cube_state, cube_state_data);
|
99
|
+
|
100
|
+
if (cube_state_data->cube_size != sticker_cycle_data->cube_size) {
|
101
|
+
rb_raise(rb_eArgError, "Cube size of sticker cycle must equal cube size of cube state. Got %ld vs %ld.", sticker_cycle_data->cube_size, cube_state_data->cube_size);
|
102
|
+
}
|
103
|
+
if (sticker_cycle_data->length >= 2) {
|
104
|
+
apply_sticker_cycle(cube_state_data->stickers, sticker_cycle_data->indices, sticker_cycle_data->length, false);
|
105
|
+
}
|
106
|
+
return Qnil;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE StickerCycle_hash(const VALUE self) {
|
110
|
+
const StickerCycleData* data;
|
111
|
+
GetInitializedStickerCycleData(self, data);
|
112
|
+
|
113
|
+
st_index_t hash = rb_hash_start((st_index_t)StickerCycle_hash);
|
114
|
+
hash = rb_hash_uint(hash, data->length);
|
115
|
+
hash = rb_hash_uint(hash, data->cube_size);
|
116
|
+
const size_t n = data->length;
|
117
|
+
for (size_t i = 0; i < n; ++i) {
|
118
|
+
hash = rb_hash_uint(hash, data->indices[i]);
|
119
|
+
}
|
120
|
+
return ST2FIX(rb_hash_end(hash));
|
121
|
+
}
|
122
|
+
|
123
|
+
static VALUE StickerCycle_eql(const VALUE self, const VALUE other) {
|
124
|
+
if (self == other) {
|
125
|
+
return Qtrue;
|
126
|
+
}
|
127
|
+
if (rb_obj_class(self) != rb_obj_class(other)) {
|
128
|
+
return Qfalse;
|
129
|
+
}
|
130
|
+
const StickerCycleData* self_data;
|
131
|
+
GetInitializedStickerCycleData(self, self_data);
|
132
|
+
const StickerCycleData* other_data;
|
133
|
+
GetInitializedStickerCycleData(other, other_data);
|
134
|
+
if (self_data->cube_size != other_data->cube_size) {
|
135
|
+
return Qfalse;
|
136
|
+
}
|
137
|
+
if (self_data->length != other_data->length) {
|
138
|
+
return Qfalse;
|
139
|
+
}
|
140
|
+
const size_t n = self_data->length;
|
141
|
+
for (size_t i = 0; i < n; ++i) {
|
142
|
+
if (self_data->indices[i] != other_data->indices[i]) {
|
143
|
+
return Qfalse;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
return Qtrue;
|
147
|
+
}
|
148
|
+
|
149
|
+
static VALUE StickerCycle_cube_size(const VALUE self) {
|
150
|
+
const StickerCycleData* data;
|
151
|
+
GetInitializedStickerCycleData(self, data);
|
152
|
+
return ST2FIX(data->cube_size);
|
153
|
+
}
|
154
|
+
|
155
|
+
static VALUE StickerCycle_length(const VALUE self) {
|
156
|
+
const StickerCycleData* data;
|
157
|
+
GetInitializedStickerCycleData(self, data);
|
158
|
+
return ST2FIX(data->length);
|
159
|
+
}
|
160
|
+
|
161
|
+
static VALUE StickerCycle_coordinates(const VALUE self) {
|
162
|
+
const StickerCycleData* data;
|
163
|
+
GetInitializedStickerCycleData(self, data);
|
164
|
+
return data->coordinates;
|
165
|
+
}
|
166
|
+
|
167
|
+
static VALUE StickerCycle_inverse(const VALUE self) {
|
168
|
+
const StickerCycleData* data;
|
169
|
+
GetInitializedStickerCycleData(self, data);
|
170
|
+
const long n = data->length;
|
171
|
+
StickerCycleData* inverse_data;
|
172
|
+
const VALUE inverse = TypedData_Make_Struct(rb_obj_class(self), StickerCycleData, &StickerCycleData_type, inverse_data);
|
173
|
+
inverse_data->cube_size = data->cube_size;
|
174
|
+
inverse_data->length = n;
|
175
|
+
inverse_data->indices = malloc_indices(n);
|
176
|
+
inverse_data->coordinates = rb_funcall(data->coordinates, reverse, 0);
|
177
|
+
for (int i = 0; i < n; ++i) {
|
178
|
+
inverse_data->indices[i] = data->indices[n - 1 - i];
|
179
|
+
}
|
180
|
+
return inverse;
|
181
|
+
}
|
182
|
+
|
183
|
+
void init_sticker_cycle_class_under(const VALUE module) {
|
184
|
+
reverse = rb_intern("reverse");
|
185
|
+
StickerCycleClass = rb_define_class_under(module, "StickerCycle", rb_cObject);
|
186
|
+
rb_define_alloc_func(StickerCycleClass, StickerCycle_alloc);
|
187
|
+
rb_define_method(StickerCycleClass, "initialize", StickerCycle_initialize, 2);
|
188
|
+
rb_define_method(StickerCycleClass, "apply_to", StickerCycle_apply_to, 1);
|
189
|
+
rb_define_method(StickerCycleClass, "hash", StickerCycle_hash, 0);
|
190
|
+
rb_define_method(StickerCycleClass, "eql?", StickerCycle_eql, 1);
|
191
|
+
rb_define_alias(StickerCycleClass, "==", "eql?");
|
192
|
+
rb_define_method(StickerCycleClass, "cube_size", StickerCycle_cube_size, 0);
|
193
|
+
rb_define_method(StickerCycleClass, "length", StickerCycle_length, 0);
|
194
|
+
rb_define_method(StickerCycleClass, "coordinates", StickerCycle_coordinates, 0);
|
195
|
+
rb_define_method(StickerCycleClass, "inverse", StickerCycle_inverse, 0);
|
196
|
+
}
|
@@ -4,7 +4,7 @@ module TwistyPuzzles
|
|
4
4
|
# Base class for directions.
|
5
5
|
class AbstractDirection
|
6
6
|
include Comparable
|
7
|
-
POSSIBLE_DIRECTION_NAMES = [[''], ['2', '2\''], ['\'', '3']].freeze
|
7
|
+
POSSIBLE_DIRECTION_NAMES = [[''], ['2', '2\''], ['\'', '3', '’']].freeze
|
8
8
|
SIMPLE_DIRECTION_NAMES = (['0'] + POSSIBLE_DIRECTION_NAMES.map(&:first)).freeze
|
9
9
|
POSSIBLE_SKEWB_DIRECTION_NAMES = [['', '2\''], ['\'', '2']].freeze
|
10
10
|
SIMPLE_SKEWB_DIRECTION_NAMES = (['0'] + POSSIBLE_SKEWB_DIRECTION_NAMES.map(&:first)).freeze
|
@@ -28,6 +28,16 @@ module TwistyPuzzles
|
|
28
28
|
@colors_to_face_symbols = face_symbols_to_colors.invert
|
29
29
|
end
|
30
30
|
|
31
|
+
def eql?(other)
|
32
|
+
self.class.equal?(other.class) && colors == other.colors
|
33
|
+
end
|
34
|
+
|
35
|
+
alias == eql?
|
36
|
+
|
37
|
+
def hash
|
38
|
+
@hash ||= ([self.class] + colors).hash
|
39
|
+
end
|
40
|
+
|
31
41
|
def color(face_symbol)
|
32
42
|
@face_symbols_to_colors[face_symbol]
|
33
43
|
end
|
@@ -4,7 +4,6 @@ require 'twisty_puzzles/cube'
|
|
4
4
|
require 'twisty_puzzles/cube_constants'
|
5
5
|
require 'twisty_puzzles/coordinate'
|
6
6
|
require 'twisty_puzzles/cube_print_helper'
|
7
|
-
require 'twisty_puzzles/state_helper'
|
8
7
|
require 'twisty_puzzles/utils/array_helper'
|
9
8
|
require 'twisty_puzzles/native'
|
10
9
|
|
@@ -13,7 +12,6 @@ module TwistyPuzzles
|
|
13
12
|
class CubeState
|
14
13
|
include Utils::ArrayHelper
|
15
14
|
include CubePrintHelper
|
16
|
-
include StateHelper
|
17
15
|
include CubeConstants
|
18
16
|
|
19
17
|
def self.check_cube_size(cube_size)
|
@@ -75,6 +73,10 @@ module TwistyPuzzles
|
|
75
73
|
|
76
74
|
alias == eql?
|
77
75
|
|
76
|
+
def hash
|
77
|
+
@hash ||= [self.class, @native].hash
|
78
|
+
end
|
79
|
+
|
78
80
|
def rotation_algorithms
|
79
81
|
Rotation::ALL_ROTATIONS.combination(2).reject do |r0, r1|
|
80
82
|
r0.inverse == r1
|
@@ -85,10 +87,6 @@ module TwistyPuzzles
|
|
85
87
|
rotation_algorithms.any? { |r| r.apply_temporarily_to(self) { |state| state == other } }
|
86
88
|
end
|
87
89
|
|
88
|
-
def hash
|
89
|
-
@hash ||= [self.class, @native].hash
|
90
|
-
end
|
91
|
-
|
92
90
|
# TODO: Get rid of this backwards compatibility artifact
|
93
91
|
def sticker_array(face)
|
94
92
|
raise TypeError unless face.is_a?(Face)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'twisty_puzzles/utils/array_helper'
|
4
|
+
require 'twisty_puzzles/sticker_cycle_factory'
|
5
|
+
require 'twisty_puzzles/cube'
|
6
|
+
|
7
|
+
module TwistyPuzzles
|
8
|
+
# A cycle of parts of the cube, e.g. a corner 3 cycle.
|
9
|
+
# Note that this is abstract and contains no information on the cube size.
|
10
|
+
# E.g. for wings on a 7x7, it's not clear whether inner or outer wings are used.
|
11
|
+
# Check StickerCycleFactory for making it concrete and applyable.
|
12
|
+
class PartCycle
|
13
|
+
include Utils::ArrayHelper
|
14
|
+
|
15
|
+
def initialize(parts)
|
16
|
+
check_types(parts, Part)
|
17
|
+
check_type_consistency(parts)
|
18
|
+
|
19
|
+
@parts = parts
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :parts
|
23
|
+
|
24
|
+
def eql?(other)
|
25
|
+
self.class.equal?(other.class) && @parts == other.parts
|
26
|
+
end
|
27
|
+
|
28
|
+
alias == eql?
|
29
|
+
|
30
|
+
def hash
|
31
|
+
@hash ||= ([self.class] + @parts).hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def check_type_consistency(parts)
|
35
|
+
return unless parts.any? { |p| p.class != parts.first.class }
|
36
|
+
|
37
|
+
raise TypeError, "Cycles of heterogenous piece types #{parts.inspect} are not supported."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -3,14 +3,12 @@
|
|
3
3
|
require 'twisty_puzzles/coordinate'
|
4
4
|
require 'twisty_puzzles/cube'
|
5
5
|
require 'twisty_puzzles/cube_print_helper'
|
6
|
-
require 'twisty_puzzles/state_helper'
|
7
6
|
require 'twisty_puzzles/cube_constants'
|
8
7
|
|
9
8
|
module TwistyPuzzles
|
10
9
|
# Represents the state (i.e. the sticker positions) of a Skewb.
|
11
10
|
class SkewbState
|
12
11
|
include CubePrintHelper
|
13
|
-
include StateHelper
|
14
12
|
include CubeConstants
|
15
13
|
# Pairs of coordinate pairs that should match in case of solved layers.
|
16
14
|
MATCHING_CORNERS =
|
@@ -151,14 +149,5 @@ module TwistyPuzzles
|
|
151
149
|
|
152
150
|
layer_check_neighbors(face).map { |c| self[c] }.uniq.length == 1
|
153
151
|
end
|
154
|
-
|
155
|
-
def rotate_face(face, direction)
|
156
|
-
neighbors = face.neighbors
|
157
|
-
inverse_order_face = face.coordinate_index_close_to(neighbors[0]) <
|
158
|
-
face.coordinate_index_close_to(neighbors[1])
|
159
|
-
direction = direction.inverse if inverse_order_face
|
160
|
-
cycle = SkewbCoordinate.corners_on_face(face)
|
161
|
-
apply_4sticker_cycle(cycle, direction)
|
162
|
-
end
|
163
152
|
end
|
164
153
|
end
|
@@ -10,22 +10,47 @@ module TwistyPuzzles
|
|
10
10
|
class StickerCycle
|
11
11
|
include ReversibleApplyable
|
12
12
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
13
|
+
def self.from_coordinates(cube_size, coordinates)
|
14
|
+
CubeState.check_cube_size(cube_size)
|
15
|
+
raise TypeError unless coordinates.all?(Coordinate)
|
16
|
+
|
17
|
+
new(Native::StickerCycle.new(cube_size, coordinates.map(&:native)))
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(native)
|
21
|
+
raise TypeError unless native.is_a?(Native::StickerCycle)
|
22
|
+
|
23
|
+
@native = native
|
24
|
+
end
|
25
|
+
|
26
|
+
attr_reader :native
|
27
|
+
|
28
|
+
def eql?(other)
|
29
|
+
self.class.equal?(other.class) && @native == other.native
|
16
30
|
end
|
17
31
|
|
18
|
-
|
32
|
+
alias == eql?
|
33
|
+
|
34
|
+
def hash
|
35
|
+
@hash ||= [self.class, @native].hash
|
36
|
+
end
|
37
|
+
|
38
|
+
def cube_size
|
39
|
+
@native.cube_size
|
40
|
+
end
|
41
|
+
|
42
|
+
def length
|
43
|
+
@native.length
|
44
|
+
end
|
19
45
|
|
20
46
|
def apply_to(cube_state)
|
21
47
|
raise TypeError unless cube_state.is_a?(CubeState)
|
22
|
-
raise ArgumentError unless cube_state.n == @cube_size
|
23
48
|
|
24
|
-
cube_state.
|
49
|
+
@native.apply_to(cube_state.native)
|
25
50
|
end
|
26
51
|
|
27
52
|
def inverse
|
28
|
-
StickerCycle.new(@
|
53
|
+
StickerCycle.new(@native.inverse)
|
29
54
|
end
|
30
55
|
end
|
31
56
|
|
@@ -38,7 +63,7 @@ module TwistyPuzzles
|
|
38
63
|
sticker_cycles.each do |c|
|
39
64
|
raise TypeError unless c.is_a?(StickerCycle)
|
40
65
|
|
41
|
-
c.
|
66
|
+
c.native.coordinates.each do |s|
|
42
67
|
raise ArgumentError unless affected_set.add?(s)
|
43
68
|
end
|
44
69
|
end
|
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'twisty_puzzles/sticker_cycle'
|
4
4
|
require 'twisty_puzzles/utils/array_helper'
|
5
|
+
require 'twisty_puzzles/cube'
|
5
6
|
|
6
7
|
module TwistyPuzzles
|
7
8
|
# Factory for sticker cycles given part cycles.
|
8
|
-
class
|
9
|
+
class StickerCycleFactory
|
9
10
|
include Utils::ArrayHelper
|
10
11
|
|
11
12
|
def initialize(cube_size, incarnation_index)
|
@@ -28,7 +29,7 @@ module TwistyPuzzles
|
|
28
29
|
raise TypeError, 'Twists are only supported for edges and corners.'
|
29
30
|
end
|
30
31
|
|
31
|
-
cycles = parts.map { |p| StickerCycle.
|
32
|
+
cycles = parts.map { |p| StickerCycle.from_coordinates(@cube_size, coordinates(p)) }
|
32
33
|
StickerCycles.new(@cube_size, cycles)
|
33
34
|
end
|
34
35
|
|
@@ -49,7 +50,7 @@ module TwistyPuzzles
|
|
49
50
|
check_types(parts, Part)
|
50
51
|
check_type_consistency(parts)
|
51
52
|
part_coordinates = parts.map { |p| coordinates(p) }
|
52
|
-
cycles = part_coordinates.transpose.map { |c| StickerCycle.
|
53
|
+
cycles = part_coordinates.transpose.map { |c| StickerCycle.from_coordinates(@cube_size, c) }
|
53
54
|
StickerCycles.new(@cube_size, cycles)
|
54
55
|
end
|
55
56
|
end
|
data/lib/twisty_puzzles.rb
CHANGED
@@ -24,7 +24,7 @@ require 'twisty_puzzles/letter_scheme'
|
|
24
24
|
require 'twisty_puzzles/move_type_creator'
|
25
25
|
require 'twisty_puzzles/native'
|
26
26
|
require 'twisty_puzzles/parser'
|
27
|
-
require 'twisty_puzzles/
|
27
|
+
require 'twisty_puzzles/part_cycle'
|
28
28
|
require 'twisty_puzzles/puzzle'
|
29
29
|
require 'twisty_puzzles/reversible_applyable'
|
30
30
|
require 'twisty_puzzles/rotation'
|
@@ -33,8 +33,8 @@ require 'twisty_puzzles/skewb_move'
|
|
33
33
|
require 'twisty_puzzles/skewb_move_parser'
|
34
34
|
require 'twisty_puzzles/skewb_notation'
|
35
35
|
require 'twisty_puzzles/skewb_state'
|
36
|
-
require 'twisty_puzzles/state_helper'
|
37
36
|
require 'twisty_puzzles/sticker_cycle'
|
37
|
+
require 'twisty_puzzles/sticker_cycle_factory'
|
38
38
|
require 'twisty_puzzles/twisty_puzzles_error'
|
39
39
|
require 'twisty_puzzles/version'
|
40
40
|
|
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.20
|
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: 2021-11-
|
11
|
+
date: 2021-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -196,6 +196,8 @@ files:
|
|
196
196
|
- ext/twisty_puzzles/native/skewb_layer_fingerprint.h
|
197
197
|
- ext/twisty_puzzles/native/skewb_state.c
|
198
198
|
- ext/twisty_puzzles/native/skewb_state.h
|
199
|
+
- ext/twisty_puzzles/native/sticker_cycle.c
|
200
|
+
- ext/twisty_puzzles/native/sticker_cycle.h
|
199
201
|
- ext/twisty_puzzles/native/utils.c
|
200
202
|
- ext/twisty_puzzles/native/utils.h
|
201
203
|
- lib/twisty_puzzles.rb
|
@@ -222,7 +224,7 @@ files:
|
|
222
224
|
- lib/twisty_puzzles/letter_scheme.rb
|
223
225
|
- lib/twisty_puzzles/move_type_creator.rb
|
224
226
|
- lib/twisty_puzzles/parser.rb
|
225
|
-
- lib/twisty_puzzles/
|
227
|
+
- lib/twisty_puzzles/part_cycle.rb
|
226
228
|
- lib/twisty_puzzles/puzzle.rb
|
227
229
|
- lib/twisty_puzzles/reversible_applyable.rb
|
228
230
|
- lib/twisty_puzzles/rotation.rb
|
@@ -231,8 +233,8 @@ files:
|
|
231
233
|
- lib/twisty_puzzles/skewb_move_parser.rb
|
232
234
|
- lib/twisty_puzzles/skewb_notation.rb
|
233
235
|
- lib/twisty_puzzles/skewb_state.rb
|
234
|
-
- lib/twisty_puzzles/state_helper.rb
|
235
236
|
- lib/twisty_puzzles/sticker_cycle.rb
|
237
|
+
- lib/twisty_puzzles/sticker_cycle_factory.rb
|
236
238
|
- lib/twisty_puzzles/twisty_puzzles_error.rb
|
237
239
|
- lib/twisty_puzzles/utils.rb
|
238
240
|
- lib/twisty_puzzles/utils/array_helper.rb
|
@@ -260,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
260
262
|
- !ruby/object:Gem::Version
|
261
263
|
version: '0'
|
262
264
|
requirements: []
|
263
|
-
rubygems_version: 3.2.
|
265
|
+
rubygems_version: 3.2.22
|
264
266
|
signing_key:
|
265
267
|
specification_version: 4
|
266
268
|
summary: Gem for my cube_trainer rails app. Some things are better left in a separate
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'twisty_puzzles/abstract_direction'
|
4
|
-
|
5
|
-
module TwistyPuzzles
|
6
|
-
# Common utilities for different puzzle states.
|
7
|
-
# TODO: Remove
|
8
|
-
module StateHelper
|
9
|
-
def apply_sticker_cycle(cycle)
|
10
|
-
last_sticker = self[cycle[-1]]
|
11
|
-
(cycle.length - 1).downto(1) do |i|
|
12
|
-
self[cycle[i]] = self[cycle[i - 1]]
|
13
|
-
end
|
14
|
-
self[cycle[0]] = last_sticker
|
15
|
-
end
|
16
|
-
|
17
|
-
def apply_4sticker_cycle(cycle, direction)
|
18
|
-
raise ArgumentError unless cycle.length == 4
|
19
|
-
raise TypeError unless direction.is_a?(AbstractDirection)
|
20
|
-
|
21
|
-
if direction.double_move?
|
22
|
-
apply_sticker_cycle([cycle[0], cycle[2]])
|
23
|
-
apply_sticker_cycle([cycle[1], cycle[3]])
|
24
|
-
else
|
25
|
-
# Note that we cannot do reverse! because the values are cached.
|
26
|
-
actual_cycle = direction.value == 3 ? cycle.reverse : cycle
|
27
|
-
apply_sticker_cycle(actual_cycle)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|