#!/usr/bin/perl -w use strict; no warnings 'recursion'; use Time::HiRes qw(usleep); use Getopt::Std; my (%opts, $maze, $n, $i, $j, $M, $C); %opts = ( d => 50, # delay ); getopts('d:', \%opts); open F, $ARGV[0] or die; $i = $maze->{width} = 0; while () { chomp; $n = length; $maze->{b}[$i] = [ split // ]; $maze->{width} = $n if $n > $maze->{width}; $n = index($_,'@'); if ($n >= 0) { # mouse $M->{r} = $i; $M->{c} = $n; } $n = index($_,'C'); if ($n >= 0) { # cheese $C->{r} = $i; $C->{c} = $n; } ++$i; } $maze->{height} = $i; $| = 1; clearscr(); for ($i=0; $i<$maze->{height}; ++$i) { gotorc(maze2scr($i,0)); print join "", @{ $maze->{b}[$i] }; } my ($delta); $delta = [ [1,0], [0,1], [-1,0], [0,-1] ]; for ($i=0; $i<4; ++$i) { try_dir($i); } gotorc(24,1); print "找不到起司!\n"; sub try_dir { my ($dir) = @_; my ($i, $next, $prev); %$next = %$M; $next->{r} += $delta->[$dir][0]; $next->{c} += $delta->[$dir][1]; return if ( $next->{r} < 0 || $next->{r} >= $maze->{height} || $next->{c} < 0 || $next->{c} >= $maze->{width} ); if ($maze->{b}[$next->{r}][$next->{c}] eq 'C') { gotorc(24,1); print "好吃好吃!\n"; exit 0; } elsif ($maze->{b}[$next->{r}][$next->{c}] ne ' ') { return; } usleep($opts{d}*1000); setrc($M->{r}, $M->{c}, '.'); %$prev = %$M; %$M = %$next; setrc($M->{r}, $M->{c}, '@'); for ($i=0; $i<4; ++$i) { try_dir($i); } usleep($opts{d}*1000); setrc($M->{r}, $M->{c}, ' ', 1); %$M = %$prev; setrc($M->{r}, $M->{c}, '@'); } sub gotorc { my ($row, $col) = @_; print "\x1b[${row};${col}H"; } sub maze2scr { my ($r, $c) = @_; return( $r+int((24-$maze->{height})/2), $c+int((76-$maze->{width})/2) ); } sub clearscr { print "\x1b[2J"; } sub setrc { my ($r, $c, $v, $do_not_set_maze) = @_; gotorc(maze2scr($r, $c)); print $v; $maze->{b}[$r][$c] = $v unless defined $do_not_set_maze; }