ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Games-Sokoban/Sokoban.pm
(Generate patch)

Comparing Games-Sokoban/Sokoban.pm (file contents):
Revision 1.4 by root, Tue May 11 23:32:15 2010 UTC vs.
Revision 1.8 by root, Wed May 12 00:24:37 2010 UTC

70 Carp::croak "unable to autodetect sokoban level format"; 70 Carp::croak "unable to autodetect sokoban level format";
71} 71}
72 72
73=item $level->data ([$new_data, [$new_data_format]]]) 73=item $level->data ([$new_data, [$new_data_format]]])
74 74
75Sets the level from the given data.
76
75=cut 77=cut
76 78
77sub data { 79sub data {
80 if (@_ > 1) {
78 my ($self, $data, $format) = @_; 81 my ($self, $data, $format) = @_;
79 82
80 $format ||= detect_format $data; 83 $format ||= detect_format $data;
81 84
82 if ($format eq "text" or $format eq "rle") { 85 if ($format eq "text" or $format eq "rle") {
83 $data =~ y/-_|/ \n/; 86 $data =~ y/-_|/ \n/;
84 $data =~ s/(\d)(.)/$2 x $1/ge; 87 $data =~ s/(\d)(.)/$2 x $1/ge;
85 my @lines = split /[\015\012]+/, $data; 88 my @lines = split /[\015\012]+/, $data;
86 my $w = List::Util::max map length, @lines; 89 my $w = List::Util::max map length, @lines;
87 90
88 $_ .= " " x ($w - length) 91 $_ .= " " x ($w - length)
89 for @lines; 92 for @lines;
90 93
91 $self->{data} = join "\n", @lines; 94 $self->{data} = join "\n", @lines;
92 95
93 } elsif ($format eq "binpack") { 96 } elsif ($format eq "binpack") {
94 (my ($w, $s), $data) = unpack "wwB*", $data; 97 (my ($w, $s), $data) = unpack "wwB*", $data;
95 98
96 my @enc = ('#', '$', '.', ' ', ' ', '###', '*', '# '); 99 my @enc = ('#', '$', '.', ' ', ' ', '###', '*', '# ');
97 100
98 $data = join "", 101 $data = join "",
99 map $enc[$_], 102 map $enc[$_],
100 unpack "C*", 103 unpack "C*",
101 pack "(b*)*", 104 pack "(b*)*",
102 unpack "(a3)*", $data; 105 unpack "(a3)*", $data;
103 106
104 # clip extra chars (max. 2) 107 # clip extra chars (max. 2)
105 my $extra = (length $data) % $w; 108 my $extra = (length $data) % $w;
106 substr $data, -$extra, $extra, "" if $extra; 109 substr $data, -$extra, $extra, "" if $extra;
107 110
108 (substr $data, $s, 1) =~ y/ ./@+/; 111 (substr $data, $s, 1) =~ y/ ./@+/;
109 112
110 $self->{data} = 113 $self->{data} =
111 join "\n", 114 join "\n",
112 map "#$_#", 115 map "#$_#",
113 "#" x $w, 116 "#" x $w,
114 (unpack "(a$w)*", $data), 117 (unpack "(a$w)*", $data),
115 "#" x $w; 118 "#" x $w;
116 119
117 } else { 120 } else {
118 Carp::croak "$format: unsupported sokoban level format requested"; 121 Carp::croak "$format: unsupported sokoban level format requested";
119 } 122 }
120 123
121 $self->update; 124 $self->update;
125 }
122 126
123 ($self->{data}) 127 $_[0]{data}
124} 128}
125 129
126sub pos2xy { 130sub pos2xy {
127 use integer; 131 use integer;
128 132
158 162
159 "$self->{data}\n" 163 "$self->{data}\n"
160} 164}
161 165
162=item $binary = $level->as_binpack 166=item $binary = $level->as_binpack
167
168Binpack is a very compact binary format (usually 17% of the size of an xsb
169file), that is still reasonably easy to encode/decode.
170
171It only tries to store simplified levels with full fidelity - other levels
172can be slightly changed outside the playable area.
163 173
164=cut 174=cut
165 175
166sub as_binpack { 176sub as_binpack {
167 my ($self) = @_; 177 my ($self) = @_;
205 215
206sub as_lines { 216sub as_lines {
207 split /\n/, $_[0]{data} 217 split /\n/, $_[0]{data}
208} 218}
209 219
210=item @lines = $level->as_rle 220=item $line = $level->as_rle
211 221
212http://www.sokobano.de/wiki/index.php?title=Level_format 222http://www.sokobano.de/wiki/index.php?title=Level_format
213 223
214=cut 224=cut
215 225
222 232
223 $data 233 $data
224} 234}
225 235
226=item ($x, $y) = $level->start 236=item ($x, $y) = $level->start
237
238Returns (0-based) starting coordinate.
227 239
228=cut 240=cut
229 241
230sub start { 242sub start {
231 my ($self) = @_; 243 my ($self) = @_;
396 while (<$fh>) { 408 while (<$fh>) {
397 $data .= $_; 409 $data .= $_;
398 last if /^$/; 410 last if /^$/;
399 } 411 }
400 412
413 # sokevo internally locks some cells
414 $data =~ y/^%:,;-=?/ #.$* +#/;
415
401 push @levels, new Games::Sokoban data => $data; 416 push @levels, new Games::Sokoban data => $data;
402 } 417 }
403 } 418 }
404 419
405 \@levels 420 \@levels

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines