sokoban 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|