… | |
… | |
22 | use common::sense; |
22 | use common::sense; |
23 | |
23 | |
24 | use Carp (); |
24 | use Carp (); |
25 | use List::Util (); |
25 | use List::Util (); |
26 | |
26 | |
27 | our $VERSION = '0.02'; |
27 | our $VERSION = '1.0'; |
28 | |
28 | |
29 | =item $level = new Games::Sokoban [format => "text|rle|binpack"], [data => "###..."] |
29 | =item $level = new Games::Sokoban [format => "text|rle|binpack"], [data => "###..."] |
30 | |
30 | |
31 | =cut |
31 | =cut |
32 | |
32 | |
… | |
… | |
245 | $self->pos2xy ($-[0]); |
245 | $self->pos2xy ($-[0]); |
246 | } |
246 | } |
247 | |
247 | |
248 | =item $level->hflip |
248 | =item $level->hflip |
249 | |
249 | |
|
|
250 | Mirror horizontally. |
|
|
251 | |
250 | =item $level->vflip |
252 | =item $level->vflip |
251 | |
253 | |
252 | =item $level->transpose # topleft to bottomright |
254 | Mirror vertically. |
|
|
255 | |
|
|
256 | =item $level->transpose |
|
|
257 | |
|
|
258 | Transpose level (mirror at top-left/bottom-right diagonal). |
253 | |
259 | |
254 | =item $level->rotate_90 |
260 | =item $level->rotate_90 |
255 | |
261 | |
|
|
262 | Rotate by 90 degrees clockwise. |
|
|
263 | |
256 | =item $level->rotate_180 |
264 | =item $level->rotate_180 |
|
|
265 | |
|
|
266 | Rotate by 180 degrees clockwise. |
257 | |
267 | |
258 | =cut |
268 | =cut |
259 | |
269 | |
260 | sub hflip { |
270 | sub hflip { |
261 | $_[0]{data} = join "\n", map { scalar reverse $_ } split /\n/, $_[0]{data}; |
271 | $_[0]{data} = join "\n", map { scalar reverse $_ } split /\n/, $_[0]{data}; |
… | |
… | |
349 | # phew, done |
359 | # phew, done |
350 | } |
360 | } |
351 | |
361 | |
352 | =item $id = $level->normalise |
362 | =item $id = $level->normalise |
353 | |
363 | |
354 | normalises the level map and calculates/returns it's identity code |
364 | Simplifies the level map and calculates/returns its identity code. |
355 | |
365 | . |
356 | http://www.sourcecode.se/sokoban/level_id.php, assume uppercase and hex. |
366 | http://www.sourcecode.se/sokoban/level_id.php, assume uppercase and hex. |
357 | |
367 | |
358 | =cut |
368 | =cut |
359 | |
369 | |
360 | sub normalise { |
370 | sub normalise { |
… | |
… | |
405 | local $/ = "\n\n"; |
415 | local $/ = "\n\n"; |
406 | scalar <$fh>; |
416 | scalar <$fh>; |
407 | |
417 | |
408 | while (<$fh>) { |
418 | while (<$fh>) { |
409 | chomp; |
419 | chomp; |
410 | my %meta = split /[:\n]/; |
420 | my %meta = split /(?:: |\n)/; |
411 | |
421 | |
412 | $_ = <$fh>; |
422 | $_ = <$fh>; |
413 | |
423 | |
414 | /^##+\n/ or last; |
424 | /^##+\n/ or last; |
415 | |
425 | |
416 | # sokevo internally locks some cells |
426 | # sokevo internally locks some cells |
417 | y/^%:,;-=?/ #.$* +#/; |
427 | y/^%:,;-=?/ #.$* +#/; |
418 | |
428 | |
|
|
429 | # skip levels without pusher |
|
|
430 | y/@+// or next; |
|
|
431 | |
419 | push @levels, new Games::Sokoban data => $_, meta => \%meta; |
432 | push @levels, new Games::Sokoban data => $_, meta => \%meta; |
420 | } |
433 | } |
421 | |
434 | |
422 | \@levels |
435 | \@levels |
423 | } |
436 | } |