sokoban 0.0.13 → 0.0.14
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 +7 -0
- data/Gemfile.lock +1 -1
- data/lib/sokoban.rb +26 -9
- data/lib/sokoban/version.rb +1 -1
- data/spec/lib/sokoban_spec.rb +70 -16
- metadata +12 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 589a162f779a7a0c824b766c4238d681b9895b6f
|
4
|
+
data.tar.gz: f391280ce7a29fc65dfc013c9105328e007835ee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 760e2cc272f589f563ba266415fda7093fc23c19f8332209b5ec0086058bd1432b5ba42f396a919389189b2a74bd46a08d490c5e1a2dada21fd56df8fff844fe
|
7
|
+
data.tar.gz: 700b9c9f2cfaee7d3a1e48ca5f4aaa5029b62052820f0608129f53749a6b287b2dc2d1170a7309a166ef153336e0e0e72c7b3258d22881de7101c158882636f0
|
data/Gemfile.lock
CHANGED
data/lib/sokoban.rb
CHANGED
@@ -37,8 +37,15 @@ module Sokoban
|
|
37
37
|
def initialize
|
38
38
|
@level = Level.new
|
39
39
|
parse_opts
|
40
|
-
# -l and -r opts may change lnum
|
40
|
+
# -l and -r opts may change lnum
|
41
|
+
# set @lnum after parse_opts
|
41
42
|
@lnum = @level.lnum
|
43
|
+
play
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def play
|
42
49
|
loop do
|
43
50
|
begin
|
44
51
|
@lnum += 1 if @level.play
|
@@ -48,8 +55,11 @@ module Sokoban
|
|
48
55
|
exit
|
49
56
|
end
|
50
57
|
log_moves
|
58
|
+
break if @lnum > 50
|
51
59
|
@level.restart(@lnum)
|
52
60
|
end
|
61
|
+
puts "You won Sokoban!"
|
62
|
+
puts "やったね!"
|
53
63
|
end
|
54
64
|
|
55
65
|
def log_moves
|
@@ -87,6 +97,7 @@ module Sokoban
|
|
87
97
|
@logger = Logger.new LOG_FILE
|
88
98
|
@logger.level = Logger::DEBUG
|
89
99
|
@logger.debug "Created logger"
|
100
|
+
@logger.debug "#{BASENAME} #{VERSION}"
|
90
101
|
@logger.debug "#{$0} --debug #{ARGV.join(" ")}"
|
91
102
|
@options[:debug] = true
|
92
103
|
end
|
@@ -123,7 +134,7 @@ module Sokoban
|
|
123
134
|
end
|
124
135
|
|
125
136
|
class Level
|
126
|
-
attr_reader :lnum
|
137
|
+
attr_reader :lnum, :pushes
|
127
138
|
|
128
139
|
def initialize(lnum = 1)
|
129
140
|
unless lnum.between?(1, 50)
|
@@ -136,16 +147,20 @@ module Sokoban
|
|
136
147
|
@pushes = 0
|
137
148
|
end
|
138
149
|
|
150
|
+
def moves
|
151
|
+
@moves.size
|
152
|
+
end
|
153
|
+
|
139
154
|
def restart(lnum)
|
140
155
|
initialize(lnum)
|
141
156
|
end
|
142
157
|
|
143
158
|
def play
|
144
|
-
while
|
159
|
+
while free_boxes > 0
|
145
160
|
print self
|
146
161
|
if $batch
|
147
162
|
# Input a string terminated by newline
|
148
|
-
gets.strip.each_char{|c| parse_move(c.downcase)}
|
163
|
+
gets.strip.each_char {|c| parse_move(c.downcase) }
|
149
164
|
else
|
150
165
|
# Handle single key press
|
151
166
|
parse_move(STDIN.getch)
|
@@ -156,23 +171,25 @@ module Sokoban
|
|
156
171
|
end
|
157
172
|
print self
|
158
173
|
print "Level #{@lnum} complete! "
|
159
|
-
|
160
|
-
|
174
|
+
unless @lnum == 50
|
175
|
+
print "Congratulations, on to level #{@lnum + 1}. "
|
176
|
+
end
|
177
|
+
STDIN.getch unless $batch
|
161
178
|
end
|
162
179
|
|
163
|
-
def
|
180
|
+
def free_boxes
|
164
181
|
@level.scan(/o/).size
|
165
182
|
end
|
166
183
|
|
167
184
|
def inspect
|
168
185
|
s = "Level: #{@lnum} Moves: #{@moves.size} Pushes: #{@pushes} "
|
169
|
-
s << @moves.map{|m| DIRECTIONS.keys[m - 1].to_s}.join
|
186
|
+
s << @moves.map {|m| DIRECTIONS.keys[m - 1].to_s }.join
|
170
187
|
end
|
171
188
|
|
172
189
|
def to_s
|
173
190
|
clear_screen
|
174
191
|
s = "Level: #{@lnum}\n\n"
|
175
|
-
s << (0...16).map{|i| @level[i * 19, 19]}.join("\n")
|
192
|
+
s << (0...16).map {|i| @level[i * 19, 19] }.join("\n")
|
176
193
|
s << "\nMoves: #{@moves.size} Pushes: #{@pushes}\n> "
|
177
194
|
end
|
178
195
|
|
data/lib/sokoban/version.rb
CHANGED
data/spec/lib/sokoban_spec.rb
CHANGED
@@ -1,31 +1,85 @@
|
|
1
1
|
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
2
|
include Sokoban
|
3
3
|
|
4
|
+
# Test input: One move away from level 1 completion
|
5
|
+
# Strip out whitespace due to multiline heredoc - ugly & effective
|
6
|
+
INPUT = <<-eos.gsub(/\s+/, "")
|
7
|
+
WAAAWWWAWAASSWAASSSDDDDDDDDDDDDDSDWAAAAAAAAAWWWAWAASSSWWAASSSDDD
|
8
|
+
DDDDDDDDDWDSASDWAAAAAAAAWWWAAWASSSWWAASSSDDDDDDDDDDDDSDWAAAAAAAA
|
9
|
+
WWWAWAWWDSSWWAASSSSSWWAASSSDDDDDDDDDDDWDSASDWAAAAAAAWWWAAWASSSWW
|
10
|
+
AASSSDDDDDDDDDDDDDAAAAAAAAAAAAAWAASDDDDDDDDDDDDD
|
11
|
+
eos
|
12
|
+
|
4
13
|
describe Level do
|
5
|
-
it "
|
6
|
-
Level.new.lnum.
|
14
|
+
it "defaults to level 1" do
|
15
|
+
expect(Level.new.lnum).to eq(1)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets lnum to the given level" do
|
19
|
+
expect(Level.new(42).lnum).to eq(42)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "initializes moves to 0" do
|
23
|
+
expect(Level.new.moves).to eq(0)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "initializes pushes to 0" do
|
27
|
+
expect(Level.new.pushes).to eq(0)
|
7
28
|
end
|
8
29
|
|
9
|
-
it "
|
10
|
-
Level.new
|
30
|
+
it "starts level 1 with 6 free boxes" do
|
31
|
+
expect(Level.new.free_boxes).to eq(6)
|
11
32
|
end
|
12
33
|
|
13
|
-
it "
|
34
|
+
it "raises RangeError when level is out of range" do
|
14
35
|
expect { Level.new(54) }.to raise_error(RangeError)
|
15
36
|
end
|
16
37
|
|
17
|
-
|
38
|
+
def input_moves(level)
|
39
|
+
INPUT.each_char {|c| level.parse_move(c.downcase) }
|
40
|
+
end
|
41
|
+
|
42
|
+
it "accepts valid moves" do
|
18
43
|
level = Level.new
|
19
|
-
level
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
level
|
26
|
-
level.
|
44
|
+
input_moves(level)
|
45
|
+
expect(level.moves).to eq(INPUT.size)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "ignores invalid moves" do
|
49
|
+
level = Level.new
|
50
|
+
input_moves(level)
|
51
|
+
level.parse_move('f') # shouldn't increment moves
|
52
|
+
expect(level.moves).to eq(INPUT.size)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "restarts" do
|
56
|
+
level = Level.new
|
57
|
+
input_moves(level)
|
58
|
+
level.parse_move('r') # restart
|
59
|
+
expect(level.free_boxes).to eq(6)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "plays level 1" do
|
63
|
+
level = Level.new
|
64
|
+
input_moves(level)
|
65
|
+
level.parse_move('d') # east
|
66
|
+
expect(level.free_boxes).to eq(0) # Victory!
|
67
|
+
end
|
68
|
+
|
69
|
+
it "increments pushes on box move" do
|
70
|
+
level = Level.new
|
71
|
+
input_moves(level)
|
72
|
+
expect(level.pushes).to eq(96)
|
73
|
+
level.parse_move('d') # east
|
74
|
+
expect(level.pushes).to eq(97)
|
27
75
|
end
|
28
|
-
end
|
29
76
|
|
30
|
-
|
77
|
+
it "decrements pushes on box move undo" do
|
78
|
+
level = Level.new
|
79
|
+
input_moves(level)
|
80
|
+
level.parse_move('d') # east
|
81
|
+
expect(level.pushes).to eq(97)
|
82
|
+
level.parse_move('u') # undo
|
83
|
+
expect(level.pushes).to eq(96)
|
84
|
+
end
|
31
85
|
end
|
metadata
CHANGED
@@ -1,52 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sokoban
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.14
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Boohbah
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-09 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: bundler
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -83,29 +76,29 @@ files:
|
|
83
76
|
homepage: http://rubygems.org/gems/sokoban
|
84
77
|
licenses:
|
85
78
|
- GPL
|
79
|
+
metadata: {}
|
86
80
|
post_install_message:
|
87
81
|
rdoc_options: []
|
88
82
|
require_paths:
|
89
83
|
- lib
|
90
84
|
- bin
|
91
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
-
none: false
|
93
86
|
requirements:
|
94
|
-
- -
|
87
|
+
- - '>='
|
95
88
|
- !ruby/object:Gem::Version
|
96
89
|
version: '0'
|
97
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
91
|
requirements:
|
100
|
-
- -
|
92
|
+
- - '>='
|
101
93
|
- !ruby/object:Gem::Version
|
102
94
|
version: '0'
|
103
95
|
requirements: []
|
104
96
|
rubyforge_project:
|
105
|
-
rubygems_version:
|
97
|
+
rubygems_version: 2.0.3
|
106
98
|
signing_key:
|
107
|
-
specification_version:
|
99
|
+
specification_version: 4
|
108
100
|
summary: A classic warehouse puzzle game
|
109
101
|
test_files:
|
110
102
|
- spec/lib/sokoban_spec.rb
|
111
103
|
- spec/spec_helper.rb
|
104
|
+
has_rdoc:
|