hanoi-jane 0.3.1 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|