ahhhh! Bestie to HHHH!

19

Jak dowiedzieliśmy się z IBM PC AT, YouTube (patrz wideo) , Wikipedia (patrz artykuł) i Sesame Street:

Litera Hjest najbardziej bezlitosną literą alfabetu !

(Nawet jeśli faktycznie składa się z dwóch elementów w Code Page 437. W rzeczywistości jest to WIĘCEJ bezlitosne).

Jak Obcy w ... ehm ... kosmici , Bestie bezlitośnie ścigają wszystkich, którzy odważą się zbliżyć do swoich jaj. Nie ma z nimi uzasadnienia. Musisz je zgnieść, jeśli nie zginiesz.

Przerażające spotkanie z Klubem 4H

W tym scenariuszu założymy, że sprowadzasz się do ostatniego życia i spotkałeś zwykłe Bestie w terenie bez jajek (jak na zrzucie ekranu Wikipedii). Nie masz klawiatury numerycznej i możesz poruszać się tylko bezpośrednio w górę / w dół / w lewo / w prawo ... ale bestie najwyraźniej ją mają i mogą poruszać się po skosie.

Wybór ruchu Bestii spośród jej opcji będzie tym, który minimalizuje odległość od gracza. Jeśli odległości są równe, następuje zerwanie remisu, faworyzując lewy + górny nad prawym + dolnym, ale oto macierz jednoznacznej jednoznaczności na ten temat ... najniższa liczba do rozstrzygnięcia:

1 3 4
2 H 5
6 8 7

Bestia nigdy nie śpi, ale na szczęście jest nieco wolniejsza od gracza. Poruszają się co drugą turę (dając graczowi przewagę, zaczynając naprzemiennie w drugiej turze). Muszą się poruszyć, jeśli ruch jest możliwy, niezależnie od tego, czy prowadzi to dalej od gracza.

Zmiażdżysz bestię, jeśli poruszysz pociągiem ruchomych ścian, gdzie stał w zamkniętej szczelinie. Te zwykłe bestie są warte 2 punkty za głowę.

Wejście

  1. Para liczb całkowitych wskazujących rozmiar mapy w kolumnach, a następnie w wierszach.

  2. Liczba wierszy wierszy wejściowych, każdy rozmiar kolumny ... zawierający albo ścianę pełną ( #), ścianę ruchomą ( ~), bestię ( H), odtwarzacz ( O) lub po prostu spację.

  3. Dane wejściowe, które będą albo U, D, L, R, wskazują na próbę ruchu przez gracza ... lub W, aby tylko poczekać. Pamiętaj, że próba pchnięcia ruchomej ściany, która jest zablokowana, jest zgodna z prawem, po prostu nie spowoduje żadnego działania.

Wynik

  1. aHHHH! jeśli bestie zabiły gracza ... lub nic, jeśli gracz wygrał bez bestii

  2. Wynik

(Uwaga: do celów debugowania i / lub rozrywki prawdopodobnie będziesz chciał móc wyświetlać stan na każdym kroku; ale to zbyt długo, aby opublikować tutaj.)

Wyjaśnienia

  • Gwarantujemy, że mapy będą ograniczone solidnymi ścianami.

  • Kolejność, kto porusza się po kolei, ma znaczenie dla wyniku. Zatem: Gracz zawsze idzie pierwszy, następnie bestie otrzymują porządek na podstawie ich początkowej pozycji na mapie, jeśli przesuwasz się po ekranie od góry do dołu od lewej do prawej. (Bestia z rzędu 1 porusza się przed bestią z rzędu 2, a dwie bestie w tym samym rzędzie to ta o najniższej liczbie kolumn, która poruszałaby się przed drugą)

  • Ruchome ukośne bestie mogą poruszać się w dowolne otwarte sąsiednie pola po przekątnej, niezależnie od tego, czy wymagają ściśnięcia między ścianami.

  • Gracz może pchnąć dowolną liczbę ruchomych ścian w linii, pod warunkiem, że na drugim końcu jest miejsce lub bestia. Ale próba wepchnięcia ciągu ścian w Bestię, która nie jest przypięta między ścianami, traktuje Bestię jak ścianę i nie pozwala na ruch.

  • Decyzja o ruchu Bestii podczas tury zależy od lokalizacji gracza na początku tury. Pożądana optymalizacja „odległości do gracza” polega na obliczeniu „w linii prostej”. Każde przybliżenie, które dałoby taki sam wynik, mierzony od środka jego kwadratu do środka kwadratu gracza, jest w porządku.

  • Jeśli Bestia nie może wykonać swojego pierwszego preferowanego ruchu w turze, ponieważ Bestia o wyższym priorytecie zajęła swoje miejsce, podejmie następny najlepszy wybór, zamiast pozostać na miejscu (jeśli ruch jest nadal możliwy).

Przykładowe przypadki

Simple Crush

Wejście

5 3
#####
#O~H#
#####
R

Wynik

2

Matryca preferencji -> Śmierć

Wejście

5 5
#####
#O  #
# ~ #
#  H#
#####
WWDW

Wynik

aHHHH!
0

Matryca preferencji -> Wygrana

Wejście

5 5
#####
#O  #
# ~ #
#  H#
#####
WRD

Wynik

2

Czekam na żniwiarza

Wejście

5 5
#####
#O  #
# ~ #
#  H#
#####
WWW

Wynik

aHHHH!
0

Udana porażka w scenariuszu Wikipedii

Wejście

40 23
########################################
#~      ~ ~~  ~  ~ ~~   ~ ~~    ~ ~ ~~ #
#~~ ~          ~~   ~   ~ ~~         ~ #
#~# ~~   ~~~~      ~  ~~~~  ~    ~~~  ~#
# ~        ~   ~ ~~ #~~       ~        #
#~~  ~~~   ~ ~ ~      ~ ~~ ~  ~  ~  ~  #
#     ~~  ~  ~ ~ ~~~       H    ~  #~  #
#  O~  ~  #  ~~~ ~      ~ ~~  ~  ~ ~~  #
#       ~ ~H~~   ~~ ~ #        ~~   ~  #
# ~~         ~ ~~~  ~~   ~~~~      ~  ~#
#~  ~    ~~~  ~   ~        ~   ~ ~~  ~~#
#     ~      # ~ ~~  ~~~   ~ ~ ~ #    ~#
#~ ~ ~~  ~  ~   H     ~~  ~~ ~ ~ ~~~   #
#       ~   ~   ~   ~  ~     ~~~ ~     #
# ~~  ~  ~ ~~   ~       ~ ~ ~     ~    #
#      ~~   ~   ~  ~         ~      ~~ #
#~ ~     #    ~~~~  ~    ~~~H   # ~    #
#  ~   ~ ~   ~        ~          ~~  ~ #
#  ~   ~     #~  ~   ~~  ~  ~         ~#
# ~~ ~ ~  ~~                ~   ~      #
#    ~~~        ~ ~~  ~  ~  ~   ~      #
# ~ ~     ~            ~~   ~   ~  ~   #
########################################
RRRUWWWRRRURWWWWRDRRWWRDWWWWD

Wynik

8

Mapa dostarczona przeze mnie, ruchy i wyjście @bobbel, potwierdzone przeze mnie i @Allbeert.

Zwycięskie kryteria

Myślę, że jest to możliwe do gry w golfa, więc stosuję się do zasad golfa, chyba że ludzie narzekają.

Dodatkowy kredyt

Grywalna implementacja Unicode z podwójnie szerokimi znakami przypominającymi obraz!

Dr. Rebmu
źródło
Czy ruchy diagonalne przeskakują ponad antyiagonalnymi liniami ścian? Biorąc pod uwagę, że bestia wykonuje ruch co turę, w jaki sposób przełamuje odległość między dwoma ruchami poziomymi lub dwoma ruchami pionowymi? Czy porusza się w kierunku miejsca, w którym gracz był na początku tury, czy po ruchu gracza? Kiedy mówisz „pociąg ruchomych ścian”, czy to oznacza, że ​​gracz może popchnąć dowolną liczbę ruchomych ścian w linii, pod warunkiem, że na drugim końcu jest miejsce lub bestia?
Peter Taylor
2
Jeśli dobrze rozumiem, drugi przykład jest błędny, ponieważ pastebin.com/raw.php?i=CqPJPjTR .
Klamka
1
@ Dr.Rebmu: ogólnie bardzo lubię twoje zadanie, ale jest wiele pytań, które należy zadać. Dzięki za wytłumaczenie! Więc dalej: co z tą sytuacją dwóch bestii: pastebin.com/raw.php?i=FENVAkCH Czy moje założenie jest prawidłowe?
Bobbel
1
Kolejne pytanie: co zrobić, jeśli przeniesiesz ciąg ścian do bestii, która nie jest „przygnieciona”? pastebin.com/raw.php?i=isN4L6pJ
Claudiu
3
@ Bobbel Człowieku, pisanie pytań jest trudniejsze niż ich rozwiązywanie! :-) Mówię, że biorąc pod uwagę skłonność Bestii do pozostania w bezruchu, wykonają swój następny najlepszy ruch, jeśli jest dostępny, zamiast zignorować swój ruch w tej turze, jeśli Bestia o wyższym priorytecie zajmie idealne miejsce. Wyjaśnione.
Dr. Rebmu,

Odpowiedzi:

3

Perl 6: 741 znaków, 758 bajtów

Wersja w golfa znajduje się na dole, ponieważ jest zasadniczo płócienna. Powyżej jest moja wersja z golfem. Oba są interaktywne (odczytują jak najwięcej poleceń z pliku wejściowego, jak to możliwe, a następnie przechodzą do używania STDIN, aby uzyskać polecenia). Starają się używać oryginalnych znaków i kolorów.

Użycie jest jak perl6 beast.p6 beast-input:

use Term::ANSIColor;
class BeastGame {
    enum BeastParts <None Player Beast M-Wall S-Wall>;

    has @.board;
    has Int $.turn = 0;
    has Int $.score = 0;

    method indices (\matcher) {
        @.board.pairs.map: {
            .key*i X+ .value[].pairs.map: {
                .key if .value ~~ matcher
            }
        }
    }
    multi postcircumfix:<[ ]> (BeastGame \SELF, Complex \c) is rw { SELF.board[c.im][c.re] }

    has Complex $!player;
    method player { $!player = $.indices(Player)[0] }
    method Bool { so $.indices(Player) & $.indices(Beast) }

    method new (@lines) {
        my @board = @lines.map:
            {[ %(' ',<O H ~ #> Z=> None, Player, Beast, M-Wall, S-Wall){ .comb } ]}

        self.bless: :@board
    }
    method gist {
        state @symbol-map = map {colored .key, .value~' on_black'},
            ('  ',<◄► ├┤ ▒▒ ██> Z=> <default cyan red green yellow>);

        @.board.map({ @symbol-map[@$_].join }).join("\n")
    }

    method step ($d) {
        my $direction = %(:W(0), :L(-1+0i), :R(1+0i), :U(-1i), :D(1i)){$d};
        $direction // return self;
        self.move($.player,$direction);

        if ++$!turn %% 2 {
            for $.indices(Beast).eager -> $c {
                for (-1-1i,-1+0i,-1i,1-1i,1+0i,-1+1i,1+1i,1i,0i)\
                        .sort({abs $c + $^d - $!player})
                {
                    last if self.move($c, $_).defined;
                }
            }
        }

        self;
    }
    method move ($cur, $by) {
        return $cur if $by == 0;

        my $to = $cur + $by;
        my &cur-is  = { self[$cur] ~~ $^o }
        my &next-is = { self[$to]  ~~ $^o }
        return if cur-is S-Wall;
        (self[$to], self[$cur]) = (self[$cur], None)
            if next-is None
            # Move wall
            or cur-is Player | M-Wall and next-is M-Wall and self.move($to, $by)
            # Kill Player
            or cur-is Beast  and next-is Player
            # Squish Beast
            or cur-is M-Wall and next-is Beast  and self[$to+$by] ~~ M-Wall|S-Wall and $!score += 2
    }
}
my $width = get.words[1];
my $game  = BeastGame.new(lines[^$width]);
my @commands = '',lines.comb,{$*IN.get.comb}...*;

while $game {
    $game.step: @commands.shift;
    print "\e[2J";
    print "\e[H";
    say $game;
}

say "aHHHH!" unless $game.player;
say $game.score;

Wersja golfowa:

my ($u,$s,$m)=0,0;my@b=lines[^get.words[1]].map:{[%(' ',<O H ~ #>Z=>^5){.comb}]}
my@a='',lines.comb,{$*IN.get.comb}...*;sub g(\c)is rw {@b[c.im][c.re]}
my&n=->\o{@b.kv.map:{$^k*i X+$^v[].kv.map:{$^l if $^w==o}}}
my&p={$m=n(1)[0]}
my&M=->$c,$b{my$t=$c+$b;my&c={$^o==g $c}
my&x={$^o==g $t}
c(4)??0!!$b??(($c,$t)».&g=(0,g $c)
if x(0)||c(1|3)&&x(3)&&M($t,$b)||c(2)&&x(1)||c(3)&&x(2)&&2 <g($t+$b)&&($s+=2))!!1}
while n(1)&n(2) {for 1
{M p,%(:W(0),:L(-1),:R(1),:U(-1i),:D(1i)){@a.shift}//last;if $u++%2
{for n(2).eager ->$c{last if M $c,$_
for(-1-1i,-1+0i,-1i,1-1i,1+0i,-1+1i,1+1i,1i,0i).sort({abs $c+$_-$m})}}}
say "\e[2J\e[H",join "\n",map {[~]
(map {"\e[$^v;40m$^k\e[0m"},'  ',<39 ◄► 36 ├┤ 31 ▒▒ 32 ██ 33>)[@$_]},@b}
say "aHHHH!" if !p;say $s;

Wesołego Alleluja!

Mouq
źródło
To są zasady gry w golfa, więc biorąc pod uwagę, że twoje rozwiązanie wygrywa ... nawet jeśli sam bardzo nie lubię Perla. ;-) Dobra praca z konsolą i kolorem!
Dr. Rebmu
14

Java, 1843

Moja pierwsza próba rozwiązania tej zagadki za pomocą Javy. Wiem, że jest wiele ulepszeń, które mogą być krótsze. Ale w końcu na razie działa.

Aby spróbować, musisz utworzyć klasę Ci wkleić kod. args[0](ściśle mówiąc a[0]) służy do wprowadzania danych. Metoda wydruku mapy nie jest uwzględniona, ponieważ nie jest niezbędna do wydruku puzzli.

class C{static char                    [][]C;static int A=
0,B=0,D=0,E=0,F=0,G                    = 0 ; public static
void main(String[]a                    ){String []b= a[0].
split("\n");int c =                    Byte. decode(b [0].
split(" ")[1]); G=a                    [ 0 ] . replaceAll(
"[^H]","").length()                    ; String d = b [ b.
length - 1 ] ;C=new                    char[c][];for(int e
=1;e<b.length-1;e++                    ) C [ e - 1 ]=b[e].
toCharArray ( ) ; f                    ();boolean X= 0> 1;
for ( char  g : d .                    toCharArray ( ) ) {
switch(g){case 'U':                    h(0,-1);break; case
'D':h(0, 1); break;                    case 'L':h( -1, 0);
break;case'R':h(1,0                    );}if(X)i();X=!X;f(
);}System.out.print                    (D);}static void f(
){for(int a= 0;a<C.                    length;a++)for( int
b=0;b<C[a].length;b                    ++)if(C[a][b]=='O')
{A=b;B= a;}}static void h(int x,int y){E =x;F =y;switch(C[
B +y][A +x]){case 'H':g();break;case ' ':j(A,B);break;case
'~':k();}}static void i(){if(G<1){return;}int[][]l=new int
[G][];int m=0;for(int r=0;r<C.length;r++){for(int c=0;c<C[
r].length; c++){if(C[r][c]=='H'){l[m++]=new int[]{c,r};}}}
for(int[]n:l){o(n[0],n[1]);}} static void o(int a, int b){
int[]c=d (a,b);E=c[0];F =c[1];if(E !=0||F !=0){ j(a,b);} }
static int[]d(int a,int b){int[][]d={{1,3,4},{2,0,5},{6,8,
7},};int[]e=new int[]{0,0};double f=999;for(int r=-1;r<2;r
++){for(int c=-1;c<2;c++){if(C[b+r][a+c]==' '||C[b+r][a+c]
=='O'){int g=a+c-A;                    int h=b+r-B; double
i=Math.sqrt(g*g+h*h                    );if(i<f){e=new int
[]{ c,r};f =i;}else                    if(i==f){if(d[r+1][
c+1]<d[e[1]+1][e[0]                    +1]){e=new int[]{c,
r};}}} }}return e;}                    static void k(){if(
p(E,F,false)){q(E,F                    );} }static void q(
int x,int y){switch                    (C[B+y][A+x]){ case
'~':q(x+E,y+F);case                    'H':case ' ':j(A+x-
E,B+y- F);}} static                    boolean p(int x,int
y,boolean h){switch                    (C[B+y][ A+x]){case
' ':return !h; case                    '~':return h?h:p(x+
E,y +F, false);case                    'H':return h?!h:p(x
+E , y+ F, true) ;}                    return h&&C[B+y][A+
x] == '#' ; }static                    void j(int a,int b)
{char c=C[b][a];if(                    C[b+F][a+E]=='O'){g
();}else if(C[b+F][                    a+E]=='H'){D+=2;G--
;c=C[b][a];C[b][a]=                    ' ';}else{C[b][a]=C
[b+F][a+E];}C[b+F][                    a+E]=c;}static void
g () { System .out.                    print("aHHHH!\n"+D)
;     System      .                    exit  ( 0  ) ;  } }

Aby go uruchomić, spróbuj na przykład:

root@host:/cygdrive/c/workspace/project/bin> java C "5 5
> #####
> #O  #
> # ~ #
> #  H#
> #####
> WWDW"
aHHHH!
0
root@host:/cygdrive/c/workspace/project/bin>

Wyjście z ostatniego dużego scenariusza na jedną turę, zanim bestia zje gracza:

████████████████████████████████████████████████████████████████████████████████
██▓▓            ▓▓  ▓▓▓▓    ▓▓    ▓▓  ▓▓▓▓      ▓▓  ▓▓▓▓        ▓▓  ▓▓  ▓▓▓▓  ██
██▓▓▓▓  ▓▓                    ▓▓▓▓      ▓▓      ▓▓  ▓▓▓▓                  ▓▓  ██
██▓▓██  ▓▓▓▓      ▓▓▓▓▓▓▓▓            ▓▓    ▓▓▓▓▓▓▓▓    ▓▓        ▓▓▓▓▓▓    ▓▓██
██  ▓▓                ▓▓      ▓▓  ▓▓▓▓  ██▓▓▓▓              ▓▓                ██
██▓▓▓▓    ▓▓▓▓▓▓      ▓▓  ▓▓  ▓▓            ▓▓  ▓▓▓▓  ▓▓    ▓▓    ▓▓    ▓▓    ██
██          ▓▓▓▓    ▓▓    ▓▓  ▓▓  ▓▓▓▓▓▓                        ▓▓    ██▓▓    ██
██          ▓▓▓▓    ██    ▓▓▓▓▓▓  ▓▓            ▓▓  ▓▓▓▓    ▓▓    ▓▓  ▓▓▓▓    ██
██              ▓▓  ▓▓  ▓▓▓▓      ▓▓▓▓  ▓▓  ██                ▓▓▓▓      ▓▓    ██
██  ▓▓▓▓                  ▓▓  ▓▓▓▓▓▓    ▓▓▓▓  ├┤  ▓▓▓▓▓▓▓▓            ▓▓    ▓▓██
██▓▓    ▓▓    ├┤◄►▓▓▓▓▓▓├┤  ▓▓      ▓▓                ▓▓      ▓▓  ▓▓▓▓    ▓▓▓▓██
██          ▓▓            ██  ▓▓  ▓▓▓▓    ▓▓▓▓▓▓      ▓▓  ▓▓  ▓▓  ██        ▓▓██
██▓▓  ▓▓  ▓▓▓▓    ▓▓    ▓▓                  ▓▓▓▓    ▓▓▓▓  ▓▓  ▓▓  ▓▓▓▓▓▓      ██
██              ▓▓      ▓▓      ▓▓      ▓▓    ▓▓├┤        ▓▓▓▓▓▓  ▓▓          ██
██  ▓▓▓▓    ▓▓    ▓▓  ▓▓▓▓      ▓▓              ▓▓  ▓▓  ▓▓          ▓▓        ██
██            ▓▓▓▓      ▓▓      ▓▓    ▓▓                  ▓▓            ▓▓▓▓  ██
██▓▓  ▓▓          ██        ▓▓▓▓▓▓▓▓    ▓▓        ▓▓▓▓▓▓        ██  ▓▓        ██
██    ▓▓      ▓▓  ▓▓      ▓▓                ▓▓                    ▓▓▓▓    ▓▓  ██
██    ▓▓      ▓▓          ██▓▓    ▓▓      ▓▓▓▓    ▓▓    ▓▓                  ▓▓██
██  ▓▓▓▓  ▓▓  ▓▓    ▓▓▓▓                                ▓▓      ▓▓            ██
██        ▓▓▓▓▓▓                ▓▓  ▓▓▓▓    ▓▓    ▓▓    ▓▓      ▓▓            ██
██  ▓▓  ▓▓          ▓▓                        ▓▓▓▓      ▓▓      ▓▓    ▓▓      ██
████████████████████████████████████████████████████████████████████████████████

Bez głupich spacji między wierszami: http://pastebin.com/raw.php?i=QhpxKcCT

Tak więc droga graczy kończy się po ruchach RRDDDRRRWW, ponieważ w ostatnim Wmeczu bestia po lewej stronie pójdzie w prawo, aby zjeść gracza.


Kolejny przykład oryginalnej dużej mapy, ale różne ruchy:

http://pastebin.com/raw.php?i=nBWjC3PZ

Zobacz tę animację: http://youtu.be/0DIhEhjWd6s


I ostatni przykład z oryginalną mapą i różnymi ruchami (zgodnie z nowymi zasadami ruchu bestii):

http://pastebin.com/raw.php?i=NNmgzx7U

Zobacz na youtube: http://youtu.be/jXPzL88TU2A

Bobbel
źródło
1
HH! :-) Bardzo fajny. Tak długo, jak go dostałeś, masz ochotę zagrać w kilka gier i podać więcej danych przypadków testowych na tej mapie?
Dr. Rebmu
Dodałem nowy scenariusz z oryginalną mapą i różnymi ruchami. Ale tak naprawdę nie możesz wykonać tych kroków, ponieważ nie chciałem wklejać wszystkich 75 kroków do pastebin :)
Bobbel
Więc dodałem film, aby zobaczyć wynik jako animację!
bobbel
Dobry film ... choć wydaje się, że pokazuje, że bestie poruszają się zbyt szybko, aby były zabawne! Czy powinniśmy zmienić regułę, aby poruszali się co drugą turę zamiast każdej tury?
Dr. Rebmu
Nie mam nic przeciwko O dziesięć bajtów więcej dla mnie! Ale całkowicie się zgadzam. Trudno wygrać tak, jak teraz :)
Bobbel
5

C - 1004 984 917

Ahh, piękno C. Podążając za duchem drugiej odpowiedzi, również próbowałem sformatować moją :)

Wyobrażam sobie, że wciąż istnieją pewne ulepszenia tu i tam, ale pisanie i granie w golfa było naprawdę fajne. Liczba znaków obejmuje wszystkie niezbędne spacje i nowe linie.

#define M(y,x,c) {t[y][x]=32;t[p][q]=c;y=p;x=q;}
   #define E {printf("aHHHH!\n%d",Z);exit(0);}
    #define A sqrt(pow(X-Q,2)+pow(Y-P,2))*30
           #define L (char)(m[s]>>8)
            #define G (char)(m[s])
             #define B(b) if(T==b)
              #define J M(Y,X,79)
               #define T t[P][Q]

r,c,X,Y,H,i,j,k,Z,p,q,P,Q,u,v,s,w,m[99],b[8]={
-1,255,65280,65281,1,511,257,256},t[999][999],
x[99],y[99];main(){char N[99];m[85]=b[2];m[68]
=256;m[76]=255; m[82]=1; scanf("%d %d",&c,&r);
for(;P<r;P++)                    for(Q=0;Q<c&&
scanf("%c",&T                    );T-10&&T-13?
Q++:Q){B(79){                    Y=P;X=Q;}B(72
){y[H]=P ;x[H                    ++]=Q;}}scanf
("%s",N);for(                    ;i<strlen(N);
i++){s=N[i];P                    =p=Y+L;Q=q=X+
G;B(32)J B('~')                  {while(P+=L,Q
+=G,T=='~');B                    (72){u=P+L;v=
Q+G;if(t[u][v]                   ==35||t[u][v]
=='~'){Z+=2;T=                   '~';J}}B(32){
T='~';J}}else                    B(72)E if(r=!r)
for(j=0;j<H;j                    ++){P=y[j];Q=
x[j];if(T-72)continue;v=A;s=0;for(k=0;k<8;k++)
{P=y[j]+(char)(b[k]>>8);Q=x[j]+(char)(b[k]);u=
A;B(32)if((c=v-u+99)>s){s=c;q=Q;p=P;}B(79)E}if
(s)M(y[j],x[j],72)}}printf("%d",Z);}//////////

Przetestowałem to ze wszystkimi przykładowymi przypadkami i kilkoma moimi, i wydaje się, że działa poprawnie. Jeśli ktoś znajdzie jakąkolwiek sytuację, w której nie odpowie poprawnie, daj mi znać.

Wejście pochodzi ze standardowego wejścia, a wyjście na standardowe wyjście. Nie ma sprawdzania nieprawidłowego wprowadzania danych. I zwraca wynik, jeśli gracz zostanie zjedzony, lub jeśli gracz żyje po wykonaniu wszystkich ruchów (nawet jeśli nadal Hjest w pobliżu).

Wersja bez golfa:

#define M(y,x,c) {t[y][x]=32;t[p][q]=c;y=p;x=q;}
#define E {printf("aHHHH!\n%d",Z);exit(0);}
#define A sqrt(pow(X-Q,2)+pow(Y-P,2))*30
#define L (char)(m[s]>>8)
#define G (char)(m[s])
#define B(b) if(T==b)
#define J M(Y,X,79)
#define T t[P][Q]

r, c, X, Y, H, i, j, k, Z, p, q, P, Q, u, v, s, w, m[99], b[8] = { -1, 255,
        65280, 65281, 1, 511, 257, 256 }, t[999][999], x[99], y[99];
main() {
    char N[99];
    m[85] = b[2];
    m[68] = 256;
    m[76] = 255;
    m[82] = 1;
    scanf("%d %d", &c, &r);
    for (; P < r; P++)
        for (Q = 0; Q < c && scanf("%c", &T);T-10&&T-13?Q++:Q) {
            B(79) {
                Y=P;
                X=Q;
            }
            B(72) {
                y[H]=P;
                x[H++]=Q;
            }
        }

    scanf("%s", N);
    for (; i < strlen(N); i++) {
        s = N[i];
        P = p = Y + L;
        Q = q = X + G;
        B(32)
            J
        B('~') {
            while (P += L, Q += G, T=='~');
            B(72) {
                u=P+L;
                v=Q+G;
                if(t[u][v]==35||t[u][v]=='~') {
                    Z+=2;
                    T='~';
                    J
                }
            }
            B(32) {
                T='~';
                J
            }
        } else B(72)E
        if (r = !r)
            for (j = 0; j < H; j++) {
                P = y[j];
                Q = x[j];
                if (T-72)
                continue;

                v = A;
                s = 0;

                for (k = 0; k < 8; k++) {
                    P = y[j] + (char) (b[k] >> 8);
                    Q = x[j] + (char) (b[k]);
                    u = A;
                    B(32)
                        if ((c = v - u + 99) > s) {
                            s = c;
                            q = Q;
                            p = P;
                        }

                    B(79)
                        E
                }
                if (s)
                    M(y[j], x[j], 72)
            }
    }
    printf("%d", Z);
}
Allbeert
źródło
Ładny!! Chociaż na wejściu @ bobbla RRRUWWWRRRURWWWWRDRRWWRDWWWWD na dużej mapie dostajesz 6, a on dostaje 8. Zrobił film , być może możesz wydrukować każdy krok i poszukać jakiejkolwiek anomalii ...
Dr. Rebmu
(zauważając oczywiście, że zmieniłem zasadę, aby bestie poruszały się co drugą turę, gdy zobaczyłem, jak niemożliwa do gry była bestia - każda
kolejka
Szczerze mówiąc: nie jestem pewien, czy moje rozwiązanie również działa w 100% poprawnie. Ale to mi wygląda :)
Bobbel
@ Dr.Rebmu Zdałem sobie sprawę, że zredagowałeś to pytanie w tym samym czasie, gdy opublikowałem moje. Więc zrobiłem szybki hack, który najwyraźniej zadziałał. Ponownie sprawdzę to w ten weekend i zaktualizuję. Zamieszczę również „ładną” wersję, aby wszelkie błędy były łatwiejsze do wykrycia również przez innych ludzi :)
Allbeert
FWIW Rozwiązałem to dzisiaj w Rebol i otrzymuję również odpowiedź @ bobbel na 8.
Dr. Rebmu