2D Dungeon Crawler

9

Ihr Programm muss eine mehrzeilige Zeichenfolge wie folgt enthalten:

#############
#           #
#     p     #
#           #
#############

pist der Spieler und #ist ein Block.

Darunter im Terminal sollte eine Eingabezeile stehen, die sagt:

How do you want to move?

Wenn der Spieler tippt l, muss er nach links gehen, wenn es keinen Block gibt, andernfalls, wenn es einen Block gibt, kann er nicht durchgehen und bewegt sich natürlich nicht, jetzt muss die Ausgabe im Terminal aktualisiert werden ( und die vorherige Ausgabe gelöscht / überschrieben):

#############
#           #
#    p      #
#           #
#############

Er kann lfür links, rfür rechts, ufür oben und dfür unten tippen .

Die Eingabe ist immer mehrzeilig, wird jedoch nicht immer mit Leerzeichen in einem perfekten Rechteck aufgefüllt. Darüber hinaus können sich die Hashes an einer beliebigen Stelle in der Zeichenfolge befinden und sind nicht immer miteinander verbunden. Beispielsweise:

##  ##
#  #
## p
     #

ist ein gültiger Dungeon. (Beachten Sie das Fehlen von Leerzeichen in jeder Zeile)

Wenn der Spieler die Zeichenfolge verlässt, muss er nicht angezeigt werden. Wenn er später zurückkommt, muss er erneut angezeigt werden.

Und die Grenzen von „außerhalb“ der Zeichenfolge das sind length(longest_line)durch number_of_linesRechteck, so dass selbst wenn eine Zeile mit Leerzeichen auf der rechten Seite nicht aufgefüllt, wird diese Position nicht der Grenzen betrachtet werden. Beispiel mit dem früheren Dungeon:

##  ##
#  #p
##  
     #

Die zweite Zeile hatte kein Leerzeichen, wo das p jetzt ist, aber das spielt keine Rolle.

Schließlich muss Ihr Programm für immer eine Schleife ausführen und Eingaben vornehmen.

Testfälle

Testfall 1:

####
# p#
#
####

How do you want to move?
d

####
#  #
# p
####

Testfall 2:

####
  p#
   #
####

How do you want to move?
l

####
 p #
   #
####

How do you want to move?
d

####
   #
 p #
####

How do you want to move?
l

####
   #
p  #
####

How do you want to move?
l

####
   #
   #
####

How do you want to move?
r

####
   #
p  #
####

Natürlich sind diese nicht vollständig. Ihr Code sollte für immer eine Schleife bilden und den Bildschirm zwischen den einzelnen Ausgaben löschen .

Ihre Ausgabe darf zur Eingabe als How do you want to move?\n<input>oder How do you want to move?<input>auffordern (dh Sie benötigen die Eingabe nicht in einer leeren Zeile), und Sie benötigen keine leere Zeile zwischen der letzten Zeile des Dungeons und der Eingabeaufforderung. (Sie können jedoch nicht in derselben Zeile sein)

Standardlücken sind nicht erlaubt! Dies ist Code-Golf, also gewinnt der kürzeste Code in Bytes!

LMD
quelle
2
Ist es akzeptabel, wenn die Eingabe ein Buchstabe gefolgt von einer Eingabe ist? Außerdem schlage ich vor, diese Zeichenfolge nicht mehr drucken zu müssen, was der Herausforderung nichts hinzuzufügen scheint
Luis Mendo,
2
Ich denke , das ist wieder geöffnet werden kann, aber mein Vorschlag ist , dass die Eingabeaufforderung (für l, r, u, oder d) kann alles sein, nicht nur „Wie Sie verschieben möchten“? Es wirkt sich nicht wirklich auf die Antworten aus, außer auf Golf.
Rɪᴋᴇʀ
@ EastlyIrk: Ich würde nicht zustimmen. In diesem Fall müssen die Golfer darüber nachdenken, wie die Zeichenfolge komprimiert werden soll, um Bytes zu sparen.
LMD
2
@ user7185318 Denken Sie daran , bleiben Sie grundsätzlich bei 1 Problem pro Herausforderung. Das Komprimieren der Zeichenfolge ist ein völlig anderes Problem als das Erstellen eines Dungeon-Crawlers und sollte daher wahrscheinlich nicht für diese Herausforderung angegangen werden.
Rɪᴋᴇʀ
1
Ist es akzeptabel, wenn der Spieler angezeigt wird, wenn er sich außerhalb der Grenzen befindet, oder müssen sie verschwinden?
MattWH

Antworten:

1

MATLAB, 268 247 246 Bytes

Wahrscheinlich nicht wettbewerbsfähig, aber es hat Spaß gemacht. Golfversion:

function f(s);d=char(split(s,'\n'));[y,x]=ind2sub(size(d),find(d=='p'));while 1;d
c=uint8(input('How do you want to move?','s'))-100;v=y+~c-(c==17);w=x+(c==14)-(c==8);try;d(y,x)=' ';end;try;if'#'==d(v,w);v=y;w=x;end;d(v,w)='p';end;y=v;x=w;clc;end

Lesbare Version:

function f(s)
% Split the string on newlines and convert to a padded char array
d = char(split(s,'\n'));

% Get the initial indices of p
[y,x] = ind2sub(size(d),find(d=='p'));

% Loop forever
while 1
    % Implicitly display the dungeon
    d

    % Get the ASCII of the user input, minus 100 (saves a few bytes in
    % the comparisons)
    c=uint8(input('How do you want to move?','s'))-100;

    % Get the new y from the ASCII
    v = y+~c-(c==17);

    % Get the new x from the ASCII
    w = x+(c==14)-(c==8);

    % Clear the player from the dungeon if they are in it
    try
        d(y,x)=' ';
    end

    % Check if new position is a #, and revert to old position if so
    try
        if '#'==d(v,w)
            v=y;w=x;
        end
        d(v,w)='p';
    end
    % Update x and y
    y=v;
    x=w;

    % Clear the screen
    clc;
end

Die tryBlöcke sollen verhindern, dass die Funktion außerhalb der Grenzen abstürzt. Ich bin mir sicher, dass zwei von ihnen übertrieben sind, aber ich kann es nicht besser spielen.

Es ist erwähnenswert, dass MATLAB das Array nach unten und rechts erweitert, der Player jedoch verschwindet, wenn er zum ersten Mal in einen "unerforschten" Bereich wechselt. Wenn Sie sich beispielsweise um ein Feld außerhalb der aktuellen Grenzen des Dungeons nach rechts bewegen, verschwinden Sie, aber in der nächsten Runde erweitert MATLAB das Array um die neue Spalte (oder Zeile, wenn Sie sich nach unten bewegen). '#'==d(y,x)spart ein Byte im Vergleich zu d(y,x)=='#', da Sie kein Leerzeichen zwischen ifund benötigen'#'

MattWH
quelle
Gute Antwort ! Ich hoffe diesmal gewinnt nicht etwas sehr kurzes, hier sollten auch die gängigen Sprachen eine Chance haben, denn je größer die Herausforderung, desto besser sind Java etc. :)
LMD
1

Kaffeeskript: 580 Bytes

Ich habe alles, was ich konnte, aus diesem speziellen Algorithmus und meinem müden Gehirn herausgepresst. Ich brauche Ferien.

C=console
e='length'
N=null
f=(S)->
    x=y=X=Y=N
    q=(c,v)->
        X=[x+c,N][+(-1<x+c<w)]
        Y=[y+v,N][+(-1<y+v<h)]
        try L[y+v][x+c]!='#'catch
            1
    r=(s)->
        if (X||Y)
            return
        L[y]=((t=L[y].split '')[x]=s)
        L[y]=t.join ''
    while 1
        L=S.split '\n'
        [h,w]=[L[e],L[0][e]]
        x=[X,x][+(x?)]
        y=[Y,y][+(y?)]
        for k in[0..h*w-1]
            if L[k//h][k%w]=='p'
                x=k%w
                y=k//h
        C.clear()
        C.log S
        r(' ')
        switch prompt("How do you want to move?")
            when'l'
                q(-1,0)&&x--
            when'r'
                q(1,0)&&x++
            when'u'
                q(0,-1)&&y--
            when'd'
                q(0,1)&&y++
        r('p')
        S=L.join '\n'
Lord Ratte
quelle
schöne Lösung, Lord Ratte
LMD