2D地牢爬行者


9

您的程序必须采用多行字符串,如下所示:

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

p是玩家,#是一个障碍。

现在在终端下应该是一条输入行,上面写着:

How do you want to move?

如果玩家键入l必须在没有障碍物的情况下向左走,否则,在存在障碍物的情况下,他将无法通过并且当然也不会移动,因此现在必须更新终端中的输出(并且先前的输出已清除/覆盖):

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

他可以输入l左,r右,u上和d下。

输入将始终为多行,但不会始终用空格填充为理想的矩形。另外,散列可以在字符串中的任何位置,并且不会始终相互连接。例如:

##  ##
#  #
## p
     #

是有效的地牢。(请注意,每行上都没有尾随空格)

如果玩家不在字符串范围内,则不必显示他。但是,如果他稍后再来,则必须再次显示。

字符串“外部”的边界是length(longest_line)by number_of_lines矩形,因此即使一行没有在右边填充空格,该位置也不会被视为超出范围。使用早期地下城的示例:

##  ##
#  #p
##  
     #

第二行现在的p没有空格,但这没关系。

最后,您的程序必须永远循环以获取输入。

测试用例

测试用例1:

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

How do you want to move?
d

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

测试案例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  #
####

当然,这些还不完整。您的代码应该永远循环并清除每个输出之间的屏幕

您的输出被允许以How do you want to move?\n<input>or 提示输入How do you want to move?<input>(即,您不需要在空白行上输入),并且在地牢的最后一行和提示之间也不需要空行。(但是它们不能在同一行)

不允许出现标准漏洞!这是代码高尔夫球,因此以字节为单位的最短代码胜出!


2
输入是字母,然后输入enter是可以接受的吗?另外,我建议摆脱不必打印字符串,它似乎并没有任何补充的挑战
路易斯Mendo

2
我认为这是重新打开的,但我的建议是,输入提示(lru,或d)可以是任何东西,不只是“你怎么想动”?除了打高尔夫球以外,它并不会真正影响答案。
Rɪᴋᴇʀ

@EasterlyIrk:我不会同意。因为在这种情况下,高尔夫球手将不得不考虑如何压缩字符串以节省字节。
LMD

2
@ user7185318 请记住这一点,每个挑战基本上坚持1个问题。压缩字符串是制作地下城爬虫的一个完全独立的问题,因此可能不应该应对这一挑战。
Rɪᴋᴇʀ

1
如果播放器超出范围显示,或者是否需要消失,是否可以接受?
mwh

Answers:


1

MATLAB,268个 247 246字节

可能没有竞争力,但这很有趣。高尔夫球版:

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

可读版本:

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

这些try块是为了防止函数因超出范围错误而崩溃。我确定其中两个是过大的杀伤力,但是我不能比这更好。

值得注意的是,MATLAB会向下和向右扩展数组,但是播放器在第一次移动到“未探索”区域时会消失。例如,如果您在地牢的当前边界之外向右移动一个空格,您将消失,但是下一轮MATLAB将扩展数组以包括新列(或行,如果您向下移动)。'#'==d(y,x)与相比d(y,x)=='#',节省了一个字节,因为您if和之间不需要空格'#'


好答案!我希望这次不是一个短暂的胜利,在这里通用语言也应该有一个机会,因为挑战越大,java等就越好。:)
LMD

1

咖啡脚本:580字节

我已经从这个特定算法和疲惫的大脑中挤出了我所有的可能。我需要放假。

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'

不错的解决方案,拉特勋爵
LMD
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.