hanoi-jane 0.3.1 → 0.3.3
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/config/config.yml +3 -2
- data/lib/hanoi/jane.rb +36 -8
- data/lib/hanoi/jane/animation/drop_in.rb +43 -0
- data/lib/hanoi/jane/animation/dropper.rb +11 -3
- data/lib/hanoi/jane/animation/frame.rb +20 -0
- data/lib/hanoi/jane/animation/smoosher.rb +45 -0
- data/lib/hanoi/jane/cli.rb +25 -27
- data/lib/hanoi/jane/formatters/matrix.rb +1 -1
- data/lib/hanoi/jane/towers/animated_towers.rb +0 -10
- data/lib/hanoi/jane/towers/constrained_towers.rb +14 -2
- data/lib/hanoi/jane/towers/regular_towers.rb +28 -3
- data/lib/hanoi/jane/version.rb +1 -1
- metadata +5 -3
- data/lib/hanoi/jane/towers/stack_finders.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29597fd9ae3dadaf88e2edb71d794ba60c9a3f44
|
4
|
+
data.tar.gz: a26ad504df7e1df2aaa61b619c9337440dc2dac0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0ddbeb638c7e2e6a90da9c2dc4a079da42dd69397ee184e70135a5f3131e0a8b51f95f7bff3298f87d2671572ea71188bf9df71b389d7b834cb3f3718a59c75
|
7
|
+
data.tar.gz: a8886bb1e1cbcd00ff9a064572b5b34aeab4a9830e3e5e1ea0e537383fd3dc1a527cd6d59dd6827166f7212f502ed1f9faa54b1584326af2fbcb1f82d7a08e70
|
data/config/config.yml
CHANGED
@@ -2,14 +2,12 @@ chars:
|
|
2
2
|
regular:
|
3
3
|
space: ' '
|
4
4
|
disc: 'o'
|
5
|
-
pole: '|'
|
6
5
|
vert_divider: '|'
|
7
6
|
horiz_divider: '-'
|
8
7
|
|
9
8
|
fancy:
|
10
9
|
space: ' '
|
11
10
|
disc: '🎾'
|
12
|
-
pole: '💈'
|
13
11
|
vert_divider: '🔺'
|
14
12
|
horiz_divider: '🔻'
|
15
13
|
|
@@ -28,3 +26,6 @@ digits:
|
|
28
26
|
- [1, 1, 0]
|
29
27
|
- [0, 1, 0]
|
30
28
|
- [0, 1, 1]
|
29
|
+
|
30
|
+
animation:
|
31
|
+
tween-scale: 0.1
|
data/lib/hanoi/jane.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'yaml'
|
3
|
-
require 'ostruct'
|
4
3
|
|
5
4
|
require 'thor'
|
6
5
|
require 'httparty'
|
@@ -10,31 +9,34 @@ require 'hanoi/jane/version'
|
|
10
9
|
require 'hanoi/jane/config'
|
11
10
|
require 'hanoi/jane/exceptions'
|
12
11
|
|
13
|
-
require 'hanoi/jane/towers/stack_finders'
|
14
12
|
require 'hanoi/jane/towers/regular_towers'
|
15
13
|
require 'hanoi/jane/towers/constrained_towers'
|
16
14
|
require 'hanoi/jane/towers/animated_towers'
|
17
15
|
|
18
16
|
require 'hanoi/jane/animation/animation'
|
17
|
+
require 'hanoi/jane/animation/frame'
|
19
18
|
require 'hanoi/jane/animation/lifter'
|
20
19
|
require 'hanoi/jane/animation/dropper'
|
21
20
|
require 'hanoi/jane/animation/padded_stacks'
|
21
|
+
require 'hanoi/jane/animation/drop_in'
|
22
|
+
require 'hanoi/jane/animation/smoosher'
|
22
23
|
|
23
24
|
require 'hanoi/jane/formatters/matrix'
|
24
25
|
require 'hanoi/jane/formatters/console'
|
25
26
|
|
26
27
|
module Hanoi
|
27
28
|
module Jane
|
28
|
-
def self.
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def self.render_to_phat source, interval, phat
|
30
|
+
source.each do |frame|
|
31
|
+
Hanoi::Jane.hit_phat frame.to_dots, phat
|
32
|
+
sleep interval * interval_factor(frame)
|
32
33
|
end
|
33
|
-
|
34
|
+
end
|
34
35
|
|
36
|
+
def self.hit_phat grid, phat
|
35
37
|
url = "http://#{phat}/lights"
|
36
38
|
payload = {
|
37
|
-
matrix:
|
39
|
+
matrix: grid
|
38
40
|
}
|
39
41
|
headers = {
|
40
42
|
'Content-Type' => 'application/json',
|
@@ -43,5 +45,31 @@ module Hanoi
|
|
43
45
|
|
44
46
|
HTTParty.patch(url, body: payload.to_json, headers: headers)
|
45
47
|
end
|
48
|
+
|
49
|
+
def self.render_to_console source, interval, fancy
|
50
|
+
source.each do |frame|
|
51
|
+
Hanoi::Jane.draw_console frame.stacks, frame.value, fancy
|
52
|
+
sleep interval * interval_factor(frame)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.draw_console stacks, value, fancy = false
|
57
|
+
system('clear')
|
58
|
+
|
59
|
+
c = Formatters::Console.new do |c|
|
60
|
+
c.stacks = stacks
|
61
|
+
c.fancy = fancy
|
62
|
+
end
|
63
|
+
|
64
|
+
puts value
|
65
|
+
puts c
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.interval_factor frame
|
69
|
+
if frame.animtype == :tween
|
70
|
+
return Config.instance.config.animation['tween-scale']
|
71
|
+
end
|
72
|
+
1
|
73
|
+
end
|
46
74
|
end
|
47
75
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Hanoi
|
2
|
+
module Jane
|
3
|
+
class DropIn
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_accessor :height, :discs
|
7
|
+
attr_reader :stacks, :disc, :animtype
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@height = 7
|
11
|
+
@discs = 3
|
12
|
+
@animtype = :tween
|
13
|
+
yield self if block_given?
|
14
|
+
|
15
|
+
@stacks = PaddedStacks.new [[], [], []], @height
|
16
|
+
@disc = discs - 1
|
17
|
+
@dropper = Dropper.new @stacks[0], @disc, true
|
18
|
+
end
|
19
|
+
|
20
|
+
def value
|
21
|
+
'0' * (@discs - @disc)
|
22
|
+
end
|
23
|
+
|
24
|
+
def each
|
25
|
+
while @disc >= 0
|
26
|
+
@dropper = Dropper.new @stacks[0], @disc, (@disc == 0 ? false : true)
|
27
|
+
@dropper.each do |state|
|
28
|
+
@stacks[0] = state.to_a
|
29
|
+
yield self
|
30
|
+
end
|
31
|
+
@disc -= 1
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_dots
|
36
|
+
Formatters::Matrix.new do |m|
|
37
|
+
m.stacks = @stacks
|
38
|
+
m.digits = '0' * (@discs - @disc)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Hanoi
|
2
2
|
module Jane
|
3
3
|
class Dropper < Array
|
4
|
-
def initialize stack, item
|
4
|
+
def initialize stack, item, full_drop = false
|
5
5
|
stack.map { |i| self.push i }
|
6
6
|
@item = item
|
7
|
+
@full_drop = full_drop
|
7
8
|
end
|
8
9
|
|
9
10
|
def drop
|
@@ -16,10 +17,17 @@ module Hanoi
|
|
16
17
|
end
|
17
18
|
|
18
19
|
def dropped
|
19
|
-
|
20
|
+
if @full_drop
|
21
|
+
return self[(Dropper.position self, @item)] || (Dropper.position self, @item) < 0
|
22
|
+
end
|
23
|
+
|
24
|
+
(
|
25
|
+
self[(Dropper.position self, @item) - 1] ||
|
26
|
+
self[(Dropper.position self, @item)]
|
27
|
+
) || (Dropper.position self, @item) == 0
|
20
28
|
end
|
21
29
|
|
22
|
-
def each
|
30
|
+
def each
|
23
31
|
until dropped
|
24
32
|
drop
|
25
33
|
yield self
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Hanoi
|
2
|
+
module Jane
|
3
|
+
class Frame
|
4
|
+
attr_reader :stacks, :animtype, :value
|
5
|
+
|
6
|
+
def initialize stacks, value, type
|
7
|
+
@stacks = stacks
|
8
|
+
@value = value
|
9
|
+
@animtype = type
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_dots
|
13
|
+
Formatters::Matrix.new do |m|
|
14
|
+
m.stacks = @stacks
|
15
|
+
m.digits = @value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Hanoi
|
2
|
+
module Jane
|
3
|
+
class Smoosher < Array
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_accessor :direction
|
7
|
+
attr_reader :animtype
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@direction = :close
|
11
|
+
@step = 0.05
|
12
|
+
@animtype = :tween
|
13
|
+
|
14
|
+
yield self if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def each
|
18
|
+
@range = (0..1).step(0.05).to_a
|
19
|
+
@range.reverse! if @direction == :open
|
20
|
+
@range.each do |weight|
|
21
|
+
populate weight
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def populate weight
|
27
|
+
7.times do |i|
|
28
|
+
self[i] = Smoosher.row weight
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_dots
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
def Smoosher.row weight = 0
|
37
|
+
a = []
|
38
|
+
45.times do
|
39
|
+
a.push (weight > Random.rand) ? 1 : 0
|
40
|
+
end
|
41
|
+
a
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/hanoi/jane/cli.rb
CHANGED
@@ -11,23 +11,30 @@ module Hanoi
|
|
11
11
|
|
12
12
|
desc 'phat', "Solve the towers against the pHAT's webserver"
|
13
13
|
option :phat, type: :string, required: true, desc: 'Address of the pHAT you want to hit'
|
14
|
+
option :discs, type: :numeric, default: 5, desc: 'Number of discs'
|
14
15
|
option :constrained, type: :boolean, desc: 'Solve the constrained variant'
|
15
16
|
option :interval, type: :numeric, default: 0.1, desc: 'Time between frames (ish)'
|
16
17
|
|
17
18
|
def phat
|
18
|
-
|
19
|
+
smoosher = Hanoi::Jane::Smoosher.new
|
20
|
+
[:close, :open].each do |direction|
|
21
|
+
smoosher.direction = direction
|
22
|
+
Hanoi::Jane.render_to_phat smoosher, options[:interval], options[:phat]
|
23
|
+
end
|
24
|
+
|
25
|
+
drop_in = DropIn.new do |d|
|
26
|
+
d.height = 7
|
27
|
+
d.discs = options[:discs]
|
28
|
+
end
|
29
|
+
|
30
|
+
towers = AnimatedTowers.new do |a|
|
19
31
|
a.towers = ConstrainedTowers
|
20
|
-
a.discs =
|
32
|
+
a.discs = options[:discs]
|
21
33
|
a.height = 7
|
22
34
|
end
|
23
35
|
|
24
|
-
|
25
|
-
Hanoi::Jane.
|
26
|
-
interval = options[:interval]
|
27
|
-
if frame.type == :tween
|
28
|
-
interval = interval * 0.1
|
29
|
-
end
|
30
|
-
sleep interval
|
36
|
+
[drop_in, towers].each do |source|
|
37
|
+
Hanoi::Jane.render_to_phat source, options[:interval], options[:phat]
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
@@ -40,31 +47,22 @@ module Hanoi
|
|
40
47
|
|
41
48
|
def console
|
42
49
|
begin
|
43
|
-
|
50
|
+
drop_in = DropIn.new do |d|
|
51
|
+
d.height = options[:discs] + options[:height]
|
52
|
+
d.discs = options[:discs]
|
53
|
+
end
|
54
|
+
|
55
|
+
towers = AnimatedTowers.new do |a|
|
44
56
|
a.towers = options[:constrained] ? ConstrainedTowers : RegularTowers
|
45
57
|
a.discs = options[:discs]
|
46
58
|
a.height = options[:discs] + options[:height]
|
47
59
|
end
|
48
60
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
c = Formatters::Console.new do |c|
|
53
|
-
c.stacks = frame.stacks
|
54
|
-
c.fancy = options[:fancy]
|
55
|
-
end
|
56
|
-
|
57
|
-
puts frame.value
|
58
|
-
puts c
|
59
|
-
|
60
|
-
interval = options[:interval]
|
61
|
-
if frame.type == :tween
|
62
|
-
interval = interval * 0.1
|
63
|
-
end
|
64
|
-
sleep interval
|
61
|
+
[drop_in, towers].each do |source|
|
62
|
+
Hanoi::Jane.render_to_console source, options[:interval], options[:fancy]
|
65
63
|
end
|
66
64
|
|
67
|
-
puts '%d moves to solve for %d discs' % [
|
65
|
+
puts '%d moves to solve for %d discs' % [towers.towers.total, towers.discs]
|
68
66
|
|
69
67
|
rescue HanoiException => he
|
70
68
|
puts he.text
|
@@ -38,15 +38,5 @@ module Hanoi
|
|
38
38
|
yield Frame.new (PaddedStacks.new @towers.stacks, @height), @towers.rebased, :key
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
42
|
-
class Frame
|
43
|
-
attr_reader :stacks, :type, :value
|
44
|
-
|
45
|
-
def initialize stacks, value, type
|
46
|
-
@stacks = stacks
|
47
|
-
@value = value
|
48
|
-
@type = type
|
49
|
-
end
|
50
|
-
end
|
51
41
|
end
|
52
42
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Hanoi
|
2
2
|
module Jane
|
3
3
|
class ConstrainedTowers < RegularTowers
|
4
|
-
extend ConstrainedStackFinder
|
5
|
-
|
6
4
|
def initialize discs = 3
|
7
5
|
super
|
8
6
|
@base = 3
|
@@ -17,6 +15,20 @@ module Hanoi
|
|
17
15
|
i[:ternary] = i.delete :binary
|
18
16
|
i
|
19
17
|
end
|
18
|
+
|
19
|
+
def ConstrainedTowers.find_stack stacks:, from:, disc: nil, total:
|
20
|
+
# if we're in the middle
|
21
|
+
if from == 1
|
22
|
+
# we always move to the right on an even total
|
23
|
+
if total % 2 == 0
|
24
|
+
return 2
|
25
|
+
else
|
26
|
+
return 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# otherwise we're at the edges and can only move to the middle
|
30
|
+
1
|
31
|
+
end
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module Hanoi
|
2
2
|
module Jane
|
3
3
|
class RegularTowers
|
4
|
-
|
4
|
+
include Enumerable
|
5
5
|
|
6
|
-
attr_reader :
|
7
|
-
attr_accessor :
|
6
|
+
attr_reader :total, :base, :disc, :from, :to, :discs
|
7
|
+
attr_accessor :stacks
|
8
8
|
|
9
9
|
def initialize discs = 3
|
10
10
|
@discs = discs
|
@@ -57,6 +57,12 @@ module Hanoi
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
+
def clone
|
61
|
+
c = self.dup
|
62
|
+
c.stacks = self.stacks.clone.map { |s| s.clone }
|
63
|
+
c
|
64
|
+
end
|
65
|
+
|
60
66
|
def to_s
|
61
67
|
s = ''
|
62
68
|
@stacks.each do |stack|
|
@@ -68,6 +74,10 @@ module Hanoi
|
|
68
74
|
s
|
69
75
|
end
|
70
76
|
|
77
|
+
def to_json
|
78
|
+
inspect.to_json
|
79
|
+
end
|
80
|
+
|
71
81
|
def binary
|
72
82
|
rebased
|
73
83
|
end
|
@@ -76,6 +86,21 @@ module Hanoi
|
|
76
86
|
self.class.rebase @total, @base, @discs
|
77
87
|
end
|
78
88
|
|
89
|
+
def RegularTowers.find_stack stacks:, from:, disc:, total: nil
|
90
|
+
# if the next stack is empty, move there
|
91
|
+
if stacks[(from + 1) % 3] == []
|
92
|
+
return (from + 1) % 3
|
93
|
+
end
|
94
|
+
|
95
|
+
# if the next stack has a smaller top disc than our disc, go one more over
|
96
|
+
if stacks[(from + 1) % 3][-1] < disc
|
97
|
+
return (from + 2) % 3
|
98
|
+
end
|
99
|
+
|
100
|
+
# default to the next one
|
101
|
+
(from + 1) % 3
|
102
|
+
end
|
103
|
+
|
79
104
|
def RegularTowers.starter_stacks discs
|
80
105
|
[(0...discs).to_a.reverse, [], []]
|
81
106
|
end
|
data/lib/hanoi/jane/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanoi-jane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pikesley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -148,9 +148,12 @@ files:
|
|
148
148
|
- hanoi-jane.gemspec
|
149
149
|
- lib/hanoi/jane.rb
|
150
150
|
- lib/hanoi/jane/animation/animation.rb
|
151
|
+
- lib/hanoi/jane/animation/drop_in.rb
|
151
152
|
- lib/hanoi/jane/animation/dropper.rb
|
153
|
+
- lib/hanoi/jane/animation/frame.rb
|
152
154
|
- lib/hanoi/jane/animation/lifter.rb
|
153
155
|
- lib/hanoi/jane/animation/padded_stacks.rb
|
156
|
+
- lib/hanoi/jane/animation/smoosher.rb
|
154
157
|
- lib/hanoi/jane/cli.rb
|
155
158
|
- lib/hanoi/jane/config.rb
|
156
159
|
- lib/hanoi/jane/exceptions.rb
|
@@ -159,7 +162,6 @@ files:
|
|
159
162
|
- lib/hanoi/jane/towers/animated_towers.rb
|
160
163
|
- lib/hanoi/jane/towers/constrained_towers.rb
|
161
164
|
- lib/hanoi/jane/towers/regular_towers.rb
|
162
|
-
- lib/hanoi/jane/towers/stack_finders.rb
|
163
165
|
- lib/hanoi/jane/version.rb
|
164
166
|
homepage: http://sam.pikesley.org/projects/hanoi-jane/
|
165
167
|
licenses:
|
@@ -1,36 +0,0 @@
|
|
1
|
-
module Hanoi
|
2
|
-
module Jane
|
3
|
-
module StackFinder
|
4
|
-
def find_stack stacks:, from:, disc:, total: nil
|
5
|
-
# if the next stack is empty, move there
|
6
|
-
if stacks[(from + 1) % 3] == []
|
7
|
-
return (from + 1) % 3
|
8
|
-
end
|
9
|
-
|
10
|
-
# if the next stack has a smaller top disc than our disc, go one more over
|
11
|
-
if stacks[(from + 1) % 3][-1] < disc
|
12
|
-
return (from + 2) % 3
|
13
|
-
end
|
14
|
-
|
15
|
-
# default to the next one
|
16
|
-
return (from + 1) % 3
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module ConstrainedStackFinder
|
21
|
-
def find_stack stacks:, from:, disc: nil, total:
|
22
|
-
# if we're in the middle
|
23
|
-
if from == 1
|
24
|
-
# we always move to the right on an even total
|
25
|
-
if total % 2 == 0
|
26
|
-
return 2
|
27
|
-
else
|
28
|
-
return 0
|
29
|
-
end
|
30
|
-
end
|
31
|
-
# otherwise we're at the edges and can only move to the middle
|
32
|
-
1
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|