puzzled 0.0.1 → 0.2
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.
- data/README.md +19 -10
- data/lib/puzzled/cube.rb +50 -0
- data/lib/puzzled/revenge_cube.rb +15 -0
- data/lib/puzzled/rubiks_cube.rb +4 -43
- data/lib/puzzled/version.rb +1 -1
- data/lib/puzzled.rb +2 -4
- data/spec/cube_spec.rb +56 -0
- data/spec/revenge_cube_spec.rb +23 -0
- data/spec/rubiks_cube_spec.rb +4 -48
- data/spec/spec_helper.rb +20 -0
- metadata +10 -2
data/README.md
CHANGED
@@ -1,18 +1,27 @@
|
|
1
1
|
Puzzled?
|
2
2
|
========
|
3
|
-
Generates scrambles for
|
4
|
-
|
5
|
-
Current Status
|
6
|
-
--------------
|
7
|
-
`Puzzled::RubiksCube.scramble` generates Rubik's Cube scrambles
|
3
|
+
Generates scrambles for the Rubik's Cube.
|
8
4
|
|
9
5
|
Usage
|
10
6
|
-----
|
7
|
+
Install:
|
8
|
+
|
9
|
+
$ gem install puzzled
|
11
10
|
|
12
|
-
|
11
|
+
Play:
|
13
12
|
|
14
13
|
> require 'puzzled'
|
15
|
-
>
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
> Puzzled::RubiksCube.new.scramble 10
|
15
|
+
|
16
|
+
#=> ["F", "D'", "U", "F", "U'", "D2", "F2", "B", "U", "B'"]
|
17
|
+
|
18
|
+
> Puzzled::RevengeCube.new.scramble 10
|
19
|
+
|
20
|
+
#=> ["L", "R'", "u", "d2", "f2", "D", "B", "b", "r'", "L'"]
|
21
|
+
|
22
|
+
Test:
|
23
|
+
|
24
|
+
$ git clone git://github.com/huntca/puzzled.git
|
25
|
+
$ cd puzzled
|
26
|
+
$ bundle
|
27
|
+
$ rspec spec
|
data/lib/puzzled/cube.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module Puzzled
|
2
|
+
class Cube
|
3
|
+
# Set the move groups and dirs for this cube
|
4
|
+
def initialize(groups = nil)
|
5
|
+
@groups = groups ? groups : [["F","B"],["L","R"],["D","U"]]
|
6
|
+
@dirs = ["","'","2"]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Retun Cube scramble of length n
|
10
|
+
def scramble(n=10)
|
11
|
+
scramble = []
|
12
|
+
prev_group = nil
|
13
|
+
prev_prev_group = nil
|
14
|
+
n.times do
|
15
|
+
# Find a move group for the next move
|
16
|
+
# We cannot have 3 moves in a row that are in the same group
|
17
|
+
group = rand(@groups.size)
|
18
|
+
if prev_group == nil
|
19
|
+
prev_group = group
|
20
|
+
elsif prev_prev_group == nil
|
21
|
+
prev_prev_group = prev_group
|
22
|
+
prev_group = group
|
23
|
+
else
|
24
|
+
# While we have 3 moves in the same group, pick a new group
|
25
|
+
while group == prev_group && group == prev_prev_group
|
26
|
+
group = rand(@groups.size)
|
27
|
+
end
|
28
|
+
prev_prev_group = prev_group
|
29
|
+
prev_group = group
|
30
|
+
end
|
31
|
+
|
32
|
+
# Find the next move from move group
|
33
|
+
# We cannot have two turns in a row on the same face
|
34
|
+
move = @groups[group][rand(@groups[group].size)]
|
35
|
+
if scramble.size > 0
|
36
|
+
while move == scramble.last[0] do
|
37
|
+
move = @groups[group][rand(@groups[group].size)]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find a direction for this move
|
42
|
+
dir = @dirs[rand(@dirs.size)]
|
43
|
+
|
44
|
+
# Add move to scramble
|
45
|
+
scramble << move + dir
|
46
|
+
end
|
47
|
+
return scramble
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Puzzled
|
2
|
+
class RevengeCube < Cube
|
3
|
+
# Set the move groups for that of a Revenge Cube
|
4
|
+
def initialize
|
5
|
+
super([["F","B","f","b"],
|
6
|
+
["L","R","l","r"],
|
7
|
+
["D","U","d","u"]])
|
8
|
+
end
|
9
|
+
|
10
|
+
# Retun Revenge Cube scramble of length n
|
11
|
+
def scramble(n=40)
|
12
|
+
super(n)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/puzzled/rubiks_cube.rb
CHANGED
@@ -1,47 +1,8 @@
|
|
1
1
|
module Puzzled
|
2
|
-
class RubiksCube
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Retun Rubik's Cube scramble of size = size
|
7
|
-
def scramble(size=25)
|
8
|
-
scramble = []
|
9
|
-
prev_group = nil
|
10
|
-
prev_prev_group = nil
|
11
|
-
size.times do
|
12
|
-
# Find a move group for the next move
|
13
|
-
# We cannot have 3 moves in a row that are in the same group
|
14
|
-
group = rand(GROUPS.size)
|
15
|
-
if prev_group == nil
|
16
|
-
prev_group = group
|
17
|
-
elsif prev_prev_group == nil
|
18
|
-
prev_prev_group = prev_group
|
19
|
-
prev_group = group
|
20
|
-
else
|
21
|
-
# While we have 3 moves in the same group, pick a new group
|
22
|
-
while group == prev_group && group == prev_prev_group
|
23
|
-
group = rand(GROUPS.size)
|
24
|
-
end
|
25
|
-
prev_prev_group = prev_group
|
26
|
-
prev_group = group
|
27
|
-
end
|
28
|
-
|
29
|
-
# Find the next move from move group
|
30
|
-
# We cannot have two turns in a row on the same face
|
31
|
-
move = GROUPS[group][rand(2)]
|
32
|
-
if scramble.size > 0
|
33
|
-
while move == scramble.last[0] do
|
34
|
-
move = GROUPS[group][rand(2)]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Find a direction for this move
|
39
|
-
dir = DIRS[rand(DIRS.size)]
|
40
|
-
|
41
|
-
# Add move to scramble
|
42
|
-
scramble << move + dir
|
43
|
-
end
|
44
|
-
return scramble
|
2
|
+
class RubiksCube < Cube
|
3
|
+
# Return Rubik's Cube scramble of length n
|
4
|
+
def scramble(n=25)
|
5
|
+
super(n)
|
45
6
|
end
|
46
7
|
end
|
47
8
|
end
|
data/lib/puzzled/version.rb
CHANGED
data/lib/puzzled.rb
CHANGED
data/spec/cube_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Puzzled::Cube do
|
4
|
+
describe "#scramble" do
|
5
|
+
before(:each) do
|
6
|
+
@cube = Puzzled::Cube.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns correct number of moves" do
|
10
|
+
scramble_size = 30
|
11
|
+
@cube.scramble(scramble_size).size.should == scramble_size
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns default set of moves when no size is given" do
|
15
|
+
@cube.scramble.size.should > 0
|
16
|
+
end
|
17
|
+
|
18
|
+
it "contains only valid moves" do
|
19
|
+
moves = ["F","B","L","R","D","U",
|
20
|
+
"f","b","l","r","d","u"]
|
21
|
+
contains_valid_moves(@cube.scramble, moves)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "does not rotate the same face 2 times in a row" do
|
25
|
+
prev = nil
|
26
|
+
@cube.scramble(500).each do |move|
|
27
|
+
if prev != nil
|
28
|
+
move[0].should_not == prev
|
29
|
+
end
|
30
|
+
prev = move[0]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does not rotate parallel faces 3 times in a row" do
|
35
|
+
group = { "F" => 1, "B" => 1, "f" => 1, "b" => 1,
|
36
|
+
"L" => 2, "R" => 2, "l" => 2, "r" => 2,
|
37
|
+
"D" => 3, "U" => 3, "d" => 3, "u" => 3 }
|
38
|
+
prev = nil
|
39
|
+
prev_prev = nil
|
40
|
+
@cube.scramble(500).each do |move|
|
41
|
+
if prev == nil
|
42
|
+
prev = move
|
43
|
+
elsif prev_prev == nil
|
44
|
+
prev_prev = prev
|
45
|
+
prev = move
|
46
|
+
else
|
47
|
+
if group[prev[0]] == group[move[0]]
|
48
|
+
group[prev_prev[0]].should_not == group[move[0]]
|
49
|
+
end
|
50
|
+
prev_prev = prev
|
51
|
+
prev = move
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Puzzled::RevengeCube do
|
4
|
+
describe "#scramble" do
|
5
|
+
before(:each) do
|
6
|
+
@revenge_cube = Puzzled::RevengeCube.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns correct number of moves by default" do
|
10
|
+
@revenge_cube.scramble.size == 40
|
11
|
+
end
|
12
|
+
|
13
|
+
it "contains only valid moves" do
|
14
|
+
moves = ["F","B","L","R","D","U",
|
15
|
+
"f","b","l","r","d","u"]
|
16
|
+
contains_valid_moves(@revenge_cube.scramble, moves)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "contains some slice moves" do
|
20
|
+
contains_slice_moves(@revenge_cube.scramble)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/spec/rubiks_cube_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Puzzled::RubiksCube do
|
4
4
|
describe "#scramble" do
|
@@ -6,57 +6,13 @@ describe Puzzled::RubiksCube do
|
|
6
6
|
@rubiks_cube = Puzzled::RubiksCube.new
|
7
7
|
end
|
8
8
|
|
9
|
-
it "returns correct number of moves" do
|
10
|
-
|
11
|
-
@rubiks_cube.scramble(scramble_size).size.should == scramble_size
|
12
|
-
end
|
13
|
-
|
14
|
-
it "returns correct number of moves when no size is given" do
|
15
|
-
@rubiks_cube.scramble.size.should > 0
|
9
|
+
it "returns correct number of moves by default" do
|
10
|
+
@rubiks_cube.scramble.size.should == 25
|
16
11
|
end
|
17
12
|
|
18
13
|
it "contains only valid moves" do
|
19
14
|
moves = ["F","B","L","R","D","U"]
|
20
|
-
|
21
|
-
@rubiks_cube.scramble.each do |move|
|
22
|
-
move.size.should > 0
|
23
|
-
move.size.should <= 2
|
24
|
-
moves.include?(move[0]).should == true
|
25
|
-
dirs.include?(move[1]).should == true if move.size > 1
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
it "does not rotate the same face 2 times in a row" do
|
30
|
-
prev = nil
|
31
|
-
@rubiks_cube.scramble(500).each do |move|
|
32
|
-
if prev != nil
|
33
|
-
move[0].should_not == prev
|
34
|
-
end
|
35
|
-
prev = move[0]
|
36
|
-
end
|
15
|
+
contains_valid_moves(@rubiks_cube.scramble, moves)
|
37
16
|
end
|
38
|
-
|
39
|
-
it "does not rotate parallel faces 3 times in a row" do
|
40
|
-
group = { "F" => 1, "B" => 1,
|
41
|
-
"L" => 2, "R" => 2,
|
42
|
-
"D" => 3, "U" => 3 }
|
43
|
-
prev = nil
|
44
|
-
prev_prev = nil
|
45
|
-
@rubiks_cube.scramble(500).each do |move|
|
46
|
-
if prev == nil
|
47
|
-
prev = move
|
48
|
-
elsif prev_prev == nil
|
49
|
-
prev_prev = prev
|
50
|
-
prev = move
|
51
|
-
else
|
52
|
-
if group[prev[0]] == group[move[0]]
|
53
|
-
group[prev_prev[0]].should_not == group[move[0]]
|
54
|
-
end
|
55
|
-
prev_prev = prev
|
56
|
-
prev = move
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
17
|
end
|
62
18
|
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'puzzled'
|
2
|
+
|
3
|
+
def contains_valid_moves(scramble, moves)
|
4
|
+
dirs = ["'","2"]
|
5
|
+
scramble.each do |move|
|
6
|
+
move.size.should > 0
|
7
|
+
move.size.should <= 2
|
8
|
+
moves.include?(move[0]).should == true
|
9
|
+
dirs.include?(move[1]).should == true if move.size > 1
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def contains_slice_moves(scramble)
|
14
|
+
contains_slice = false
|
15
|
+
slices = ["f","b","l","r","d","u"]
|
16
|
+
scramble.each do |move|
|
17
|
+
contains_slice = true if slices.include?(move)
|
18
|
+
end
|
19
|
+
contains_slice.should == true
|
20
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: puzzled
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: "0.2"
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Chris Hunt
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-08-
|
13
|
+
date: 2011-08-17 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -38,10 +38,15 @@ files:
|
|
38
38
|
- README.md
|
39
39
|
- Rakefile
|
40
40
|
- lib/puzzled.rb
|
41
|
+
- lib/puzzled/cube.rb
|
42
|
+
- lib/puzzled/revenge_cube.rb
|
41
43
|
- lib/puzzled/rubiks_cube.rb
|
42
44
|
- lib/puzzled/version.rb
|
43
45
|
- puzzled.gemspec
|
46
|
+
- spec/cube_spec.rb
|
47
|
+
- spec/revenge_cube_spec.rb
|
44
48
|
- spec/rubiks_cube_spec.rb
|
49
|
+
- spec/spec_helper.rb
|
45
50
|
homepage: ""
|
46
51
|
licenses: []
|
47
52
|
|
@@ -70,4 +75,7 @@ signing_key:
|
|
70
75
|
specification_version: 3
|
71
76
|
summary: Rubik's Cube scramble generator.
|
72
77
|
test_files:
|
78
|
+
- spec/cube_spec.rb
|
79
|
+
- spec/revenge_cube_spec.rb
|
73
80
|
- spec/rubiks_cube_spec.rb
|
81
|
+
- spec/spec_helper.rb
|