최소한의 NetHack


64

NetHack 은 플레이어가 던전의 가장 낮은 레벨에서 Yendor의 부적을 가져와야하는 불량 게임입니다. 텔넷을 통해 일반적으로 재생되는 전체 게임은 ASCII 그래픽으로 표시됩니다. 이 게임은 매우 도전적이고 성공하기 위해서는 많은 게임 메커니즘에 대한 지식이 필요합니다.

이 도전의 목적을 위해, 전체 던전은 단일 레벨이고 5 x 16 자만 가정합니다. 또한 "안전한"던전이거나 프로토 타입 만 구현한다고 가정 해 봅시다. 괴물, 기아에 대한 우려 등은 없을 것입니다. 실제로 캐릭터와 부적 및 게임의 위치 만 추적해야합니다. 플레이어가 부적과 같은 위치에 도착하면 효과적으로 종료됩니다.

도전 과제

  • 5 × 16 던전 (단일 레벨)이 있습니다.
  • 플레이어에게 던전 내부의 시작 위치 (선택적 무작위)와 부적에게 별도의 무작위 (프로그램이 실행될 때마다 다름) 시작 광장을 제공하십시오. 즉, 부적은 플레이어와 같은 광장에서 시작할 수 없습니다.
  • 플레이어를 한 번에 한 칸씩 이동하는 4 개의 입력 키를 수락하십시오 (4 개의 기본 방향). 다른 입력을 읽거나 처리 할 수 ​​있습니다 ( 'enter'를 눌러야하는 readline () 함수 등).
  • 던전 외곽으로 여행하는 것은 허용되지 않습니다. 예를 들어, 플레이어가 던전의 오른쪽 가장자리에 있으면 오른쪽을 누르면 아무 것도하지 않아야합니다.
  • 초기 생성 후 및 이동 후 게임 상태를 인쇄하십시오. 이것은 코드 골프이고 인쇄는 다소 흥미롭지 않으므로 상태 변경이 없다고 가정하면 인쇄 함수 및 함수 호출의 문자 수를 무시하십시오 . 빈 셀은 마침표 ( .), 부적을 큰 따옴표 ( ")로 표시하고 문자를 기호 ( @)로 표시해야합니다.
  • 플레이어가 부적을 "발견"하면 게임이 끝납니다 (동일한 광장에 도착)

승리

이것은 코드 골프 도전, 오늘부터 일주일의 요구 사항을 충족하는 가장 짧은 코드가 승자로 선언됩니다.

다음은 기본 요구 사항 및 샘플 출력을 보여주는 C # (ungolfed)의 예제 솔루션입니다.

using System;

namespace nh
{
    class Program
    {
        static Random random = new Random();

        // player x/y, amulet x/y
        static int px, py, ax, ay;

        static void Main(string[] args)
        {
            px = random.Next(0, 16);
            py = random.Next(0, 5);

            // amulet starts on a position different from the player
            do { ax = random.Next(0, 16); } while (px == ax);
            do { ay = random.Next(0, 5); } while (py == ay); 

            print();

            do
            {
                // reads a single keypress (no need to press enter)
                // result is cast to int to compare with character literals
                var m = (int)Console.ReadKey(true).Key;

                // Move the player. Here standard WASD keys are used.
                // Boundary checks for edge of dungeon as well.
                if (m == 'W')
                    py = (py > 0) ? py - 1 : py;
                if (m == 'S')
                    py = (py < 5) ? py + 1 : py;
                if (m == 'A')
                    px = (px > 0) ? px - 1 : px;
                if (m == 'D')
                    px = (px < 16) ? px + 1 : px;

                // print state after each keypress. If the player doesn't
                // move this is redundant but oh well.
                print();

            // game ends when player is on same square as amulet
            } while (px != ax || py != ay);
        }

        static void print()
        {
            Console.Write('\n');
            for (int y=0; y<5; y++)
            {
                for (int x = 0; x < 16; x++)
                {
                    if (x == px && y == py)
                        Console.Write('@');
                    else if (x == ax && y == ay)
                        Console.Write('"');
                    else
                        Console.Write('.');
                }
                Console.Write('\n');
            }
        }
    }
}

총 문자 수는 1474이지만 print 함수에 대한 호출을 무시하고 최종 문자 수는 896입니다.

프로그램이 실행될 때 출력 :

................
...."...........
..........@.....
................
................

'a'키를 두 번 누른 후 출력 (위 포함) :

................
...."...........
..........@.....
................
................

................
...."...........
.........@......
................
................

................
...."...........
........@.......
................
................

10
@Doorknob에 관심이있을 것입니다.
Alex A.

10
Rogue 는 플레이어가 던전의 가장 낮은 레벨에서 Yendor의 부적을 가져와야하는 원래의 로그 라이크 게임입니다. 이것을 최소 도적이라고 부르지 않겠습니까?
Gilles

5
@Gilles 왜 이것을 최소한의 뱀이라고 부릅니까?
Casey Kuball

26
Psshh, 대각선 움직임이 없습니까? yubnhjkl 없습니까? 부적을 얻은 후 올라가는 계단조차 없습니까? : P ( 어쨌든 격렬한 공감 )
손잡이

2
@ tolos : 나는 여기 에서 무작위로 간주되는 것이 여전히 확실하지 않습니다 . 프로그램이 80 번 실행될 경우 프로그램이 실행될 때마다 다른 것을 수행 할 수는 없습니다 ... 구체적으로, 이 답변 에서 부적은 가능한 모든 79 개 위치 중 9 개만 차지할 수 있습니다. 그게 중요합니까?
Dennis

답변:


37

TI-BASIC, 42 41 38 36 35 바이트

TI-83 또는 84+ 시리즈 그래프 계산기 용.

int(5irand→A                          //Randomize amulet position
6log(ie^(6→C                          //15.635 + 4.093i
Repeat Ans=A                          //Ans holds the player pos. (starts bottom right)
iPart(C-iPart(C-Ans-e^(igetKey-i      //Boundary check, after adjusting player position
prgmDISPLAY
End

----------
PROGRAM:DISPLAY
For(X,0,15
For(Y,0,4
Output(Y+1,X+1,".
If A=X+Yi
Output(Y+1,X+1,"¨
If Ans=X+Yi
Output(Y+1,X+1,"@
End
End

플레이어가 어떤 방향으로 갈지는 키를 누르는 키 코드 의 기능 이지만 확실히 작동하는 4 개의 키는 맨 위 행에 있습니다.

Key        [Y=]  [WINDOW]  [ZOOM]  [TRACE]  [GRAPH]
           -------------------------------------------
Key code    11      12       13               15
Direction  Left     Up     Right             Down

부적은 첫 번째 열의 5 개 사각형 중 하나에서 시작하고 플레이어는 오른쪽 아래 사각형에서 시작합니다. 예를 들어, 가능한 배열은 다음과 같습니다.

................
¨...............
................
................
...............@

설명

플레이어의 위치는에서 0+0i까지 의 복소수로 저장되며 15+4i, 실제 부분은 오른쪽으로 가고 가상 부분은 아래로 내려갑니다. 이렇게하면 상단과 왼쪽에서 쉽게 경계를 확인할 수 있습니다. 숫자를 약간 오프셋하고 0으로 반올림합니다. 예를 들어, 오프셋이 0.5있고 위치가 -1+3i화면 왼쪽에 있으면 위치가로 수정됩니다 iPart(-0.5+3.5i)=0+3i. 아래쪽과 오른쪽 경계를 확인하는 것이 약간 더 복잡합니다. 우리는 일정한에서 수 뺄 필요가 C약이다, 15.635 + 4.093i(그것이 내가 사이 찾을 수있는 가장 짧은 하나 15+4i16+5i라운드에서 빼기) C다시 수를 뒤집어 다시, 그리고 라운드.

키를 누르면 조정되지 않은 플레이어 위치가 어떤 방향으로 1 단위 씩 이동하지만 정수 부분은 특정 키를 누를 때만 변경됩니다. 다행히 작동하는 키는 모두 맨 위 줄에 있습니다. 아래는 키 11, 12, 13 및 15를 눌렀을 때와 아무 키도 누르지 않은 경우 (중앙 사각형 내부의 점을 누르지 않아 정수 부분이 변경되지 않도록하는 네 가지 키 누르기의 오프셋 그래프입니다. 오프셋은 다른 정수 부분을 갖습니다). C원의 중심에있는 적십자입니다.

여기에 이미지 설명을 입력하십시오

이전 코드 (42 바이트) :

int(9irand→A                     // 0≤rand≤1, so int(9irand) = i*x where 0≤x≤8
1                                //set "Ans"wer variable to 1+0i
Repeat Ans=A                     
Ans-iPart(i^int(48ln(getKey-1    //add -i,-1,i,1 for WASD respectively (see rev. history)
Ans-int(Ans/16+real(Ans/7        //ensure player is inside dungeon
prgmDISPLAY                      //display on top 5 rows of the homescreen   
                                 //(for this version switch X+Yi with Y=Xi in prgmDISPLAY)
End

한계

"문자 를 이스케이프 할 방법이 없으므로 "프로그램 내에서 문자열을 생성 할 수 없습니다. 따라서 ¨따옴표 대신 움라우트 표시 를 사용합니다 (따옴표가있는 기존 문자열이 있으면 표시 할 수 있습니다). 얻으려면 ¨@프로그램에서, 외부 도구가 필요합니다; 그러나 유효한 TI-BASIC입니다.


2
재미를 위해서, 나는 '외부 도구'와 달리 Str1에 분음 기호와 @ 기호를 넣는 이 조각 을 만들었습니다 . 맨 위에 계산기와 일치하는 줄을 선택하고 새 프로그램에 입력 한 다음 Asm (.
MI Wright

아, 계산기에서 기계 코드를 코딩하는 것을 잊었습니다. 잘못된 유형으로 내 충돌을 일으키고 싶지는 않지만 작동한다고 생각합니다.
lirtosiast

44

CHIP-8 , 48 바이트

이것은 합법적 인 것으로 간주되지 않을 수 있지만 왜 그렇지 않습니까? 가상 게임 콘솔을위한 바이트 코드 기반 프로그래밍 언어 인 CHIP-8로 프로그램을 작성했습니다. Octo라는 에뮬레이터 / 디버거를 사용하여 브라우저에서 전체 프로그램 (99 바이트)을 시도 할 수 있습니다.

스크린 샷

http://johnearnest.github.io/Octo/index.html?gist=1318903acdc1dd266469

이 완전한 프로그램의 16 진 덤프는 다음과 같습니다.

0x60 0x14 0x61 0x04 0xC4 0x3C 0xC5 0x08
0x22 0x36 0xF6 0x0A 0x22 0x52 0x40 0x00
0x12 0x16 0x46 0x07 0x70 0xFC 0x40 0x3C
0x12 0x1E 0x46 0x09 0x70 0x04 0x41 0x00
0x12 0x26 0x46 0x05 0x71 0xFC 0x41 0x10
0x12 0x2E 0x46 0x08 0x71 0x04 0x22 0x52
0x3F 0x01 0x12 0x0A 0x00 0xFD 0xA2 0x58
0xD4 0x54 0x22 0x52 0x62 0xFF 0xA2 0x5B
0xD2 0x34 0x72 0x04 0x32 0x3F 0x12 0x40
0x62 0xFF 0x73 0x04 0x33 0x14 0x12 0x40
0x00 0xEE 0xA2 0x5F 0xD0 0x14 0x00 0xEE
0xA0 0xA0 0x40 0x00 0x00 0x20 0x00 0xF0
0x90 0x90 0xD0

ASWD 키 또는 원래 CHIP-8 키패드의 7589 키를 사용하여 플레이어를 이동할 수 있습니다. 배경과 플레이어를 그리기위한 모든 코드와 데이터를 제거하면 대신이 48 바이트 덤프가 나타납니다.

0x60 0x14 0x61 0x04 0xC4 0x3C 0xC5 0x08
0xF6 0x0A 0x40 0x00 0x12 0x12 0x46 0x07
0x70 0xFC 0x40 0x3C 0x12 0x1A 0x46 0x09
0x70 0x04 0x41 0x00 0x12 0x22 0x46 0x05
0x71 0xFC 0x41 0x10 0x12 0x2A 0x46 0x08
0x71 0x04 0x3F 0x01 0x12 0x08 0x00 0xFD

프로그램이 완성되지 않은 완전한 형태는 다음과 같이 고급 어셈블리 언어로 작성되었습니다.

:alias px v0
:alias py v1
:alias tx v2
:alias ty v3
:alias ax v4
:alias ay v5
:alias in v6

: main
    px := 20
    py := 4
    ax := random 0b111100
    ay := random 0b001000
    draw-board
    loop
        in := key
        draw-player
        if px != 0 begin
            if in == 7 then px += -4
        end
        if px != 0x3C begin
            if in == 9 then px +=  4
        end
        if py != 0 begin
            if in == 5 then py += -4
        end
        if py != 16 begin
            if in == 8 then py +=  4
        end
        draw-player
        if vf != 1 then
    again
    exit

: draw-board
    i := amulet
    sprite ax ay 4
    draw-player
    tx := -1
    i := ground
    : draw
    loop
        sprite tx ty 4
        tx += 4
        if tx != 63 then jump draw
        tx := -1
        ty += 4
        if ty != 20 then
    again
;

: draw-player
    i := player
    sprite px py 4  
;

: amulet  0xA0 0xA0 0x40
: ground  0x00 0x00 0x20 0x00
: player  0xF0 0x90 0x90 0xD0

컴파일 된 바이트 자체 는 CHIP-8 프로그래밍 언어입니다. 어셈블러는 이러한 프로그램을 구성하는보다 편리한 수단입니다.


19
작업에 적합한 도구입니다.
Dennis

6
게임을 여러 번 반복하면서 많은 시간을 낭비하게해서 +1.
Alex A.

4
@AlexA. 더 많은 시간을 낭비하고 싶다면 Cave Explorer를 사용해보십시오 . 오버 월드에서 ASWD 이동 및 QE는 플랫 포머 레벨에서 블록을 재설정 / 이동하는 데 사용됩니다.
JohnE

4
잘, 내 주말에 간다.
Alex A.

1
나는 처음에는 회의적이지만 동굴 탐험가는 재미 있었고 CHIP-8은 내가 생각했던 것보다 훨씬 오래되었습니다. 그래서 나는 이것을 배워야 할 것 같습니다.

10

파이썬 3, 86 바이트

def d():
    import sys
    for y in range(5):
        line = []
        for x in range(16):
            line.append('@' if y*16+x == p else \
                        '"' if y*16+x == a else \
                        '.')
        print(''.join(line))
    print()
    sys.stdout.flush()

p=79;a=id(9)%p
while p-a:d();p+=[p%16<15,16*(p<64),-(p%16>0),-16*(p>15)][ord(input())%7%5]

맨 아래 두 줄만 세고 삭제 d();합니다.


오른쪽 하단 모서리 ( "마지막"사각형)에서 플레이어를 시작한 다음 처음 79 개 사각형 에서 무작위로 샘플링하여 다른 바이트를 저장했습니다 .
Lynn

죄송합니다, 수정되었습니다! 수동으로 바이트를 계산하는 것이 놀랍지 않다고 생각합니다. : <
Lynn

1
나는 당신이 대체하여 다른 문자를 저장할 수 있다고 생각 a=id(9)%79과 함께 a=id(9)%p.
kirbyfan64sos

트윗 담아 가기 감사.
Lynn

1
또한 Python 3 에서이 작업을 수행하면 raw_input호출을 just로 변경할 수 있습니다 input.
kirbyfan64sos

10

C, 122 121 115 104 102 101 바이트

#define o ({for(int t=0;t<80;++t)t%16||putchar(10),putchar(t^p?t^a?46:34:64);})
p;main(a){for(a=1+time(0)%79;p^a;o,p+=(int[]){-16*(p>15),16*(p<64),-!!(p%16),p%16<15}[3&getchar()/2]);}

처음으로 여기에 게시! 나는 그것을 좋아하면 좋겠 :)

o인쇄, 음, 기능입니다. 우리의 용감한 영웅은 2, 4, 6 및 8로 움직일 수 있지만 다른 입력을 보내지 않도록주의하십시오 (개행 없음!).

업데이트 1 : 데려 aimain의 매개 변수를 설정합니다.

업데이트 2 : 영업 이익은 한 확인 입력 한 문자열이 OK이다, 나는 제거있어 scanf(내가 줄 바꿈을 건너 뛸 사용한다).

업데이트 3 : 복합 배열 리터럴을 사용하고 입력 레이아웃을 수정했습니다. 잘못된 방향으로 들어가면 프로그램이 이제 건초로갑니다.)

업데이트 4 : 인쇄 기능에 대한 호출은 계산되지 않습니다. 규칙을 더주의 깊게 읽으라는 메모를 받았습니다.

업데이트 5 : Mikkel Alan Stokkebye Christia 덕분에 1 바이트가 절약되었습니다.


!!(p%16)p%16>0있습니까? 작업 순서가 기억 나지 않습니다.
lirtosiast

@ThomasKwa이지만, 단항 -은 도움이 될 수는 없지만 p괄호는 어느 쪽이든 필요합니다. 더블 뱅은 난독 화 :)
Quentin

@Quentin 3 & getchar () / 2 <getchar () / 2-25
미켈 앨런 ​​스토 케비 크리스티 아

@MikkelAlanStokkebyeChristia 감사합니다 :)
Quentin

9

CJam, 46 45 44 40 39 37 바이트

{'.80*W$Gb'"t1$Gb'@tG/W%N*oNo}:P;
5,G,m*:Dmr~{P_l~4b2fm.+_aD&!$_W$=!}gP];

첫 번째 줄 (현재 게임 상태를 인쇄하는 함수를 정의)과 두 번째 줄 의 P 는 해당 함수를 호출하여 바이트 수에 영향을주지 않습니다.

시작 위치와 부적의 위치는 모두 의사 무작위로 선택됩니다. 분포는 균일하며 기본 PRNG가 허용합니다.

입력은 E, 6, 9B에 대한 위로 , 아래로 , 왼쪽오른쪽 으로, Caps Lock활성화, 다음에 Enter.

대체 버전

{'.80*W$Gb'"t1$Gb'@tG/W%N*oNo}:P;
5,G,m*:Dmr~{P_ZYm*l~(=:(.+_aD&!$_W$=!}gP];

4 바이트를 추가로 사용하면 입력 형식이 크게 향상됩니다.

  • 이 버전은 받아 8, 2, 46에 대한 위로 , 아래로 , 왼쪽오른쪽 숫자 패드에 대응하는 화살표 키를 일치.
  • 또한, 수용 7, 9, 13대응하는 대각선 이동합니다.

테스팅

I / O는 대화식이므로 Java 인터프리터를 사용 하여이 코드를 시도해야합니다 .

최신 버전을 다운로드하고 다음과 같이 프로그램을 실행하십시오.

java -jar cjam-0.6.5.jar nethack.cjam

Enter각 키를 누른 후 출력을 적절히 업데이트 하지 않으려면 이 래퍼를 사용하십시오.

#!/bin/bash

lines=5
wait=0.05

coproc "$@"
pid=$!

head -$lines <&${COPROC[0]}

while true; do
    kill -0 $pid 2>&- || break
    read -n 1 -s
    echo $REPLY >&${COPROC[1]}
    printf "\e[${lines}A"
    head -$lines <&${COPROC[0]}
    sleep $wait
done

printf "\e[${lines}B"

다음과 같이 호출하십시오.

./wrapper java -jar cjam-0.6.5.jar nethack.cjam

메인 버전

5,G,   e# Push [0 1 2 3 4] and [0 ... 15].
m*:D   e# Take the Cartesian product and save in D.
mr~    e# Shuffle and dump the array on the stack.
       e# This pushes 80 elements. We'll consider the bottommost the amulet's
       e# position and the topmost the player's.
{      e# Do:
  P    e#   Call P.
  _    e#   Copy the player's position.
  l~   e#   Read and evaluate one line of input.
       e#      "6" -> 6, "9" -> 9, "B" -> 11, "E" -> 14 
  4b   e#   Convert to base 4.
       e#     6 -> [1 2], 9 -> [2 1], 11 -> [2 3], 14 -> [3 2]
  2f-  e#   Subtract 2 from each coordinate.
       e#     [1 2] -> [-1 0], [2 1] -> [0 -1], [2 3] -> [0 1], [3 2] -> [1 0]
  .+   e#   Add the result to the copy of player's position.
  _aD& e#   Push a copy, wrap it in an array and intersect with D.
  !    e#   Logical NOT. This pushes 1 iff the intersection was empty.
  $    e#   Copy the corresponding item from the stack.
       e#     If the intersection was empty, the new position is invalid
       e#     and 1$ copies the old position.
       e#     If the intersection was non-empty, the new position is valid
       e#     and 0$ copies the new position.
  _W$  e#   Push copies of the new position and the amulet's position.
  =!   e#   Push 1 iff the positions are different.
}g     e# While =! pushes 1.
P      e# Call P.
];     e# Clear the stack.

대체 버전

ZYm*   e# Push the Cartesian product of 3 and 2, i.e.,
       e#   [[0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2]].
l~     e#   Read and evaluate one line of input.
(=     e# Subtract 1 and fetch the corresponding element of the array.
:(     e# Subtract 1 from each coordinate.

기능 P

'.80*  e# Push a string of 80 dots.
W$Gb   e# Copy the amulet's position and convert from base 16 to integer.
'"t    e# Set the corresponding character of the string to '"'.
1$Gb   e# Copy the player's position and convert from base 16 to integer.
'@t    e# Set the corresponding character of the string to '@'.
G/     e# Split into chunks of length 16.
W%     e# Reverse the chunks (only needed for the alternate program).
N*     e# Join the chunks, separating by linefeeds.
oNo    e# Print the resulting string and an additional linefeed.

2
TI-BASIC과 함께 당신의 꼬리에 왔습니다! 솔루션을 확인하면 게시하겠습니다.
lirtosiast

8

Java, 231 바이트 (함수 인 경우 196)

342의 전체 프로그램 코드는 다음과 같습니다.

class H{public static void main(String[]a){int p=0,y=79,c;y*=Math.random();y++;p(p,y);do p((p=(c=new java.util.Scanner(System.in).next().charAt(0))<66&p%16>0?p-1:c==68&p%16<15?p+1:c>86&p>15?p-16:c==83&p<64?p+16:p),y);while(p!=y);}static void p(int p,int y){for(int i=0;i<80;i++){System.out.print((i==p?'@':i==y?'"':'.')+(i%16>14?"\n":""));}}}

인쇄 기능이 없으면 231 :

class H{public static void main(String[]a){int p=0,y=79,c;y*=Math.random();y++;p(p,y);do p((p=(c=new java.util.Scanner(System.in).next().charAt(0))<66&p%16>0?p-1:c==68&p%16<15?p+1:c>86&p>15?p-16:c==83&p<64?p+16:p),y);while(p!=y);}}

함수가 괜찮다면 (사양에서 명확하지 않은 경우) 196으로 조금 더 줄일 수 있습니다.

void m(){int p=0,y=79,c;y*=Math.random();y++;p(p,y);do p((p=(c=new java.util.Scanner(System.in).next().charAt(0))<66&p%16>0?p-1:c==68&p%16<15?p+1:c>86&p>15?p-16:c==83&p<64?p+16:p),y);while(p!=y);}

그리고 약간의 명확성을 위해 줄 바꿈이 있습니다 ...

class H{
    public static void main(String[]a){
        int p=0,y=79,c;
        y*=Math.random();
        y++;p(p,y);
        do 
            p(
                (p=(c=new java.util.Scanner(System.in).next().charAt(0))<66&p%16>0?
                    p-1:
                    c==68&p%16<15?
                        p+1:
                        c>86&p>15?
                            p-16:
                            c==83&p<64?
                                p+16:
                                p)
                ,y);
        while(p!=y);
    }

    static void p(int p,int y){
        for(int i=0;i<80;i++){
            System.out.print((i==p?'@':i==y?'"':'.')+(i%16>14?"\n":""));
        }
    }
}

나는 인쇄 기능을 계산 아니에요 참고 p(p,y)자체를하지만, 내가 하고 내가 물건을 호출 문 내에서 변경이 있기 때문에, 그에게 전화를 계산.

대문자와 함께 작동합니다 ASDW. 그것들을 확인하는 방식으로 인해 다른 문자도 작동 할 수 있지만 사양은 다른 키를 누르면 어떻게 될지에 대해 아무 말도하지 않습니다.


if / else if 체인과 마찬가지로 중첩 된 삼항 연산자를 동일한 수준으로 들여 쓰기하는 것을 선호합니다. 더 읽기 쉽습니다.
lirtosiast

@ThomasKwa Yea, 나는 때때로 두 가지 방법으로 그것을했습니다. 이것은 묶인 것보다 중첩 된 if 문과 비슷합니다. 각 삼항의 양쪽 절반은 같은 수준이지만 다른 것과는 다르기 때문에 나에게 기분이 좋습니다.
Geobits

익명 함수가 허용되는 경우에는 192 바이트 답을 트리밍 할 수 있습니다 void m()된다()->
앙크 - morpork

@ dohaqatar7 예, 그러나 코드 골프에는 Java의 음이온 함수를 사용하지 않습니다. 다른 사람들이 똑같이 느끼는지 여부에 상관없이 원칙적으로 나에게 그늘을 느낍니다.
Geobits

당신은 할 수 있습니까 p+=?
lirtosiast

5

자바, 574 바이트

import java.util.*;public class N{static Random r=new Random();static int v,b,n,m;public static void main(String[] a){v=r.nextInt(16);b=r.nextInt(5);n=r.nextInt(16);m=r.nextInt(5);p();do{Scanner e=new Scanner(System.in);char m=e.next().charAt(0);if(m=='w')b=b>0?b-1:b;if(m=='s')b=b<5?b+1:b;if(m=='a')v=v>0?v-1:v;if(m=='d')v=v<16?v+1:v;p();}while(v!=n || b!=m);}static void p(){System.out.println();for(int y=0;y<5;y++){for(int x=0;x<16;x++){if(x==z && y==x)System.out.print('@');else if(x==n && y==m)System.out.print('"');else System.out.print('.');}System.out.println();}}}

난독 화 및 최소화를 제외하고 C # 버전과 기본적으로 동일합니다.


너무 많은 불필요한 공간 ...;)
Will

@ 그냥 그냥 고칠 것입니다 : P
Phase

1
또한 한 글자의 이름과 삼항을 사용하십시오.
lirtosiast

@ThomasKwa fixed : D
단계

6
여전히 불필요한 공간이 많고 삼항이 부족합니다.)
Will

5

줄리아, 161 바이트

용도는 w, a, s, 및 d각각 위, 아래, 오른쪽, 왼쪽, 위로 이동합니다.

인쇄를 포함한 전체 코드 (330 바이트) :

B=fill('.',5,16)
a=[rand(1:5),rand(1:16)]
B[a[1],a[2]]='"'
c=[1,a==[1,1]?2:1]
B[c[1],c[2]]='@'
for i=1:5 println(join(B[i,:]))end
while c!=a
B[c[1],c[2]]='.'
m=readline()[1]
c[2]+=m=='a'&&c[2]>1?-1:m=='d'&&c[2]<16?1:0
c[1]+=m=='w'&&c[1]>1?-1:m=='s'&&c[1]<5?1:0
m∈"wasd"&&(B[c[1],c[2]]='@')
for i=1:5 println(join(B[i,:]))end
end

스코어 코드, 인쇄 제외 (161 바이트) :

a=[rand(1:5),rand(1:16)]
c=[1,a==[1,1]?2:1]
while c!=a
m=readline()[1]
c[2]+=m=='a'&&c[2]>1?-1:m=='d'&&c[2]<16?1:0
c[1]+=m=='w'&&c[1]>1?-1:m=='s'&&c[1]<5?1:0
end

여기서 차이점은 게임 상태를 행렬로 저장하지 않는다는 것입니다. 모든 관련 정보가 배열에 포함 c하고 a. 물론 아무것도 인쇄되지 않습니다. 플레이어가 부적에 도달하면 더 이상 입력하라는 메시지가 표시되지 않습니다.


Ungolfed + 설명 (전체 코드) :

# Initialize a 5x16 matrix of dots
B = fill('.', 5, 16)

# Get a random location for the amulet
a = [rand(1:5), rand(1:16)]

# Put the amulet in B
B[a[1], a[2]] = '"'

# Start the player in the upper left unless the amulet is there
c = [1, a == [1,1] ? 2 : 1]

# Put the player in B
B[c[1], c[2]] = '@'

# Print the initial game state
for i = 1:5 println(join(B[i,:])) end

# Loop until the player gets the amulet
while c != a

    # Put a dot in the player's previous location
    B[c[1], c[2]] = '.'

    # Read a line from STDIN, take the first character
    m = readline()[1]

    # Move the player horizontally within the bounds
    if m == 'a' && c[2] > 1
        c[2] -= 1
    elseif m == 'd' && c[2] < 16
        c[2] += 1
    end

    # Move the player vertically within the bounds
    if m == 'w' && c[1] > 1
        c[1] -= 1
    elseif m == 's' && c[1] < 5
        c[1] += 1
    end

    # Set the player's new location in B
    if m ∈ "wasd"
        B[c[1], c[2]] = '@'
    end

    # Print the game state
    for i = 1:5 println(join(B[i,:])) end

end

괜찮습니다.

3
압축 / 난독 처리 된 버전의 경우 +1 실제 nethack 소스 코드를 기억하는 것과 매우 유사합니다.
벤 잭슨

더 나쁜 무작위 화를 사용하여 몇 바이트를 절약 할 수 있습니다.a=[rand(1:5),1] c=a+1
lirtosiast

@ThomasKwa : 항상 첫 줄에 있다면 얼마나 재미 있습니까? :)
Alex A.

3

배치, 329 바이트

@echo off
set e=goto e
set f= set/a
%f%a=0
%f%b=0
%f%c=%random%*3/32768+1
%f%d=%random%*16/32768+1
:et
call:p %a% %b% %c% %d%
if %a%%b% EQU %c%%d% exit/b
choice/C "wasd"
goto %errorlevel%
:1
%f%a-=1
%e%
:2
%f%b-=1
%e%
:3
%f%a+=1
%e%
:4
%f%b+=1
:e
if %a% GTR 4%f%a=4
if %a% LSS 0%f%a=0
if %b% GTR 15%f%b=15
if %b% LSS 0%f%b=0
%e%t

:p
setlocal enabledelayedexpansion
::creating a new line variable for multi line strings
set NL=^


:: Two empty lines are required here
cls
set "display="
for /l %%r in (0,1,4) do (
    set "line="
    for /l %%c in (0,1,15) do (
        set "char=."
        if %3 EQU %%r (
            if %4 EQU %%c (
                set char="
            )
        )
        if %1 EQU %%r (
            if %2 EQU %%c (
                set "char=@"
            )
        )
        set "line=!line!!char!"
    )
    set "display=!display!!line!!NL!"
)
echo !display!
exit /b

이것은 매우 인상적입니다. 나는 이것이 가능하다는 것에 놀랐다.
EIS

이것은 나에게 던전을 표시하지 않고 [W, A, S, D]? 표시되지 않은 던전을 걷는 것은 결국 종료됩니다. win7 cmd.exe
Dan Pritts

그것은 내가 witn Win7 cmd.exe를 위해 작동합니다-내가 ver을 입력하면Microsoft Windows [Version 6.1.7601]
Jerry Jeremiah

@DanPritts 이상합니다. 그것은 Windows 8 ( Microsoft Windows [Version 6.2.9200]) 에서 나를 위해 완벽하게 작동합니다
ankh-morpork

doh, 나는 모든 것을 복사하고 붙여 넣지 않았으며, 창에서 아래로 스크롤하지 않았습니다. 잘 했어.
Dan Pritts

3

Perl, 228 222 자 (코드 작업에 없어서는 안되는 줄 바꿈은 제외) — 207 인쇄에 사용되는 printand print if문 부분을 세지 않지만 게임 논리에 추가하지 않는 경우 207 144 주석에서 Yakk이 제안한 것처럼 인쇄의 일부로 필드 표현 생성 코드를 고려하는 경우)

이 코드는 제어를 위해 소문자 wasd를 사용합니다. 입력은 Enter로 확인해야합니다. Perl 5.14.2로 테스트되었습니다.

($a=$==rand(79))+=($a>=($==rand(80)));
print $_=("."x80)=~s/(.{$=})./\1@/r=~s/(.{$a})./\1"/r=~s/(.{16})/\1\n/gr;
%r=qw(w s/.(.{16})@/@\1./s a s/.@/@./ s s/@(.{16})./.\1@/s d s/@./.@/);
while(/"/){print if eval $r{getc STDIN}}

이 코드의 경우 정규식을 사용하여 인쇄 된 표현에서 작업이 직접 수행되므로 계산과 인쇄를 분리 할 수 ​​없습니다.

설명:

($a=$==rand(79))+=($a>=($==rand(80)));

이 선은 플레이어와 부적의 위치를 ​​결정합니다. 플레이어 위치는 다음 $==rand(80)과 같이 결정되며 실제로 이해하기 쉽습니다. 5 × 16 보드에는 플레이어가있을 수있는 80 개의 개별 위치가 있습니다. 위치는 $=변수에 저장되어 저장된 값을 정수로 만듭니다. 결과적으로 명시 적으로 결과를 정수로 캐스트 할 필요가 없기 때문에 몇 바이트가 절약됩니다 ( rand부동 소수점 값 제공).

포지션 중 하나가 이미 플레이어에 의해 점유되어 있기 때문에, 부적에 대해 79 개의 포지션 만이 남으므로, 부적의 포지션에 대해 $a=$==rand(79)사용됩니다. 다시 한 번, $=정수로 변환하도록 할당하지만 플레이어의 위치에 $a재사용하기 위해 할당을 더 할당합니다 $=.

부적이 플레이어와 같은 위치를 차지하는 것을 피하기 위해, 플레이어의 위치가 최소한 플레이어의 위치보다 크면 하나의 위치만큼 전진하여 플레이어가 점유하지 않은 장소에 균일 한 분포를 제공합니다. 이것은에 의해 달성되는 $a = ($a >= $=)경우 $=여기에 플레이어의 위치를 보유하고 있습니다. 이제 첫 번째 행은 $a$ and the only이 표현식에서 첫 번째 $ =` 대신 두 개의 초기 지정을 삽입하여 생성됩니다 .

print $_=("."x80)=~s/(.{$=})./\1@/r=~s/(.{$a})./\1"/r=~s/(.{16})/\1\n/gr;

초기 필드가 생성되고 나중에 인쇄됩니다. ("."x80)80 개의 점으로 이루어진 문자열을 생성합니다. =~s/(.{$=})./\1@/r다음 대체 $=와 일 문자 @및 와 일 문자 . 받는 인해 수정 제자리에서 수정하려고하지만 수정 된 문자열을 반환하지 않는 그들이 이전 식에 적용 할 수있는, 그 이유입니다. 마지막으로 16 자마다 줄 바꿈을 삽입합니다. 이 필드는 특수 변수에 저장되며 이후 변수 에서 암시 적으로 사용할 수 있습니다.=~s/(.{$=})./\1@/r$a"r=~s/(.{16})/\1\n/gr$_

%r=qw(w s/.(.{16})@/@\1./s a s/.@/@./ s s/@(.{16})./.\1@/s d s/@./.@/);

이것은 다른 움직임에 대한 교체 규칙을 포함하는 해시를 만듭니다. 이것의 더 읽기 쉬운 버전은

%r = ( 'w' => 's/.(.{16})@/@\1./s',
       'a' => 's/.@/@./',
       's' => 's/@(.{16})./.\1@/s',
       'd' => 's/@./.@/' );

키는 이동의 문자이고 값은 해당 대체 규칙이 포함 된 문자열입니다.

while(/"/){print if eval"\$_=~$r{getc STDIN}"}

이것이 메인 루프입니다. 필드에 문자 while(/"/)가 아직 있는지 확인합니다 . 부적 위로 움직이면 캐릭터가 플레이어 캐릭터로 바뀌어 필드에서 사라집니다."$_

eval $r{getc STDIN}표준 입력에서 문자를 읽고 has에서 해당하는 대체 규칙을 찾아 필드에 %r적용 $_합니다. 교체가 실제로 만든 경우이 true로 평가 (즉, 키는 해시에서 발견되었다 이동이 가능했다, 불가능한 움직임은 대체 규칙에 일치하지 않습니다). 이 경우 print에 실행됩니다. 인수없이 호출되므로 $_, 즉 수정 된 필드를 인쇄 합니다.


1
가독성을 위해 줄 바꿈을 포함한다고해서 셀 수를 계산할 필요는 없습니다. 228 바이트를 봅니다. 또한이 질문의 특정 규칙에 따라 코드의 인쇄 부분이 바이트 수에 영향을 미치지 않습니다.
Dennis

@Dennis : 인쇄 부분은 지금 추가 한 설명을 참조하십시오. 코드에서 인쇄와 평가를 의미있게 분리 할 수 ​​없습니다. 나는 당신이 제안한대로 계산을 변경했습니다.
celtschk

인쇄 코드에 상태가 변경 되었습니까? 아니? 글쎄, 내 의견으로는, 인쇄 코드의 출력을 논리에 재사용한다고해서 벌칙을 부과해서는 안됩니다. 이동 코드 (고유합니다!)는 계산해야하지만 "표시 문자열"을 생성하는 코드는 계산하지 않아야합니다.
Yakk

@ Yakk : 내 코드의 어느 부분을 인쇄 코드로 간주합니까? (실제로 제 의견은 인쇄 코드를 계산에서 제외하는 것이 "생각 코드"가 무엇인지 항상 잘 정의되어 있지 않기 때문에 나쁜 생각이라고 생각합니다.)
celtschk

@celtschk ("."x80)=~s/(.{$=})./\1@/r=~s/(.{$a})./\1"/r=~s/(.{16})/\1\n/gr는 언뜻보기에 꽤 가깝지만 내 perl-fu는 녹슨 몇 년입니다. 나는 거기에서 국가 변화를 놓칠 수 있었다.
Yakk

2

C #을 256 248 234 227 226 225 바이트

NumLock을 켠 상태에서 NumPad 화살표를 사용하여 이동합니다.

명확성을 위해 들여 쓰기 및 주석 처리 :

using System;
class P{
    static void Main(){
        int a=0,b=0,c,d,e;
        var r=new Random();
        while(0<((c=r.Next(16))&(d=r.Next(5))));
        Draw(a,b,c,d); // Excluded from the score.
        while(a!=c|b!=d){
            e=Console.ReadKey().KeyChar-48;
            a+=e==4&a>0?-1:e==6&a<15?1:0;
            b+=e==8&b>0?-1:e==2&b<4?1:0;
            Draw(a,b,c,d); // Excluded from the score.
        }
    }
    // The following method is excluded from the score.
    static void Draw(int a, int b, int c, int d){
        Console.Clear();
        for (int y = 0; y < 5; y++)
        {
            for (int x = 0; x < 16; x++)
            {
                Console.Write(
                    x == a && y == b ? '@' :
                    x == c && y == d ? '"' :
                                       '.'
                );
            }
            Console.WriteLine();
        }
    }
}

1
C # int는 암시 적으로 0으로 초기화한다고 생각합니다. 또한 캐스팅이 문제가 아닌 경우 (현재 확인할 수 없음) 문자 리터럴을 int로 변환하거나 적어도 'a'에서 97 (나는 생각합니다)이지만 나머지는 세 자리입니다.

기본적으로 클래스 필드 만 초기화되므로이 경우 정적 필드로 선언해야합니다. 메소드 변수는 처음 사용하기 전에 초기화해야합니다. 문자 수가 적습니다. 4 대 7
Hand-E-Food

char을 int에 암시 적으로 캐스팅하는 팁에 대한 @tolos에게 감사드립니다! 더 좋은 방법은 ConsoleKey 열거 형 캐스트를 int로 사용하면 2 자리 값을 사용할 수 있습니다.
Hand-E-Food

기술적으로이 Main메서드를 호출 할 필요가 없으므로 Main다른 세 문자를 제거 할 수 있습니다.
Luaan

@Luaan, 당신이 착각했다고 생각합니다. C # 설명서 : msdn.microsoft.com/en-us/library/acy3edy3.aspx
Hand-E-Food

2

HTML + 자바 스크립트 (ES6), 점수 217

너무 느리지 만 아래 스 니펫에서 온라인으로 재생할 수 있습니다.

라인 6 (T.value ...)은 출력용이며 계산되지 않습니다 (단순화를 위해 텍스트 영역 열기 및 닫기 태그를 출력하더라도 계산했습니다)

임의성에 관해서 : 부적은 항상 그리드의 오른쪽 절반에 있으며 플레이어는 항상 왼쪽 절반에서 시작합니다.

게임을 시작하고 다시 시작하려면 textArea (확대 후)를 클릭하십시오.

<textarea id=T onclick='s()' onkeyup='m(event.keyCode)'></textarea>
<script>
R=n=>Math.random()*n|0,
s=e=>m(y=R(5),x=R(8),a=R(5)*17+R(8)+8),
m=k=>(x+=(x<15&k==39)-(x>0&k==37),y+=(y<4&k==40)-(y>0&k==38),p=y*17+x,
T.value=p-a?(t=[...('.'.repeat(16)+'\n').repeat(5)],t[a]='X',t[p]='@',t.join('')):t='Well done!'
)
</script>

EcmaScript 6 스 니펫 (Firefox 만 해당)

R=n=>Math.random()*n|0
s=e=>m(y=R(5),x=R(8),a=R(5)*17+R(8)+8)
m=k=>(
  x+=(x<15&k==39)-(x>0&k==37),
  y+=(y<4&k==40)-(y>0&k==38),
  p=y*17+x,
  T.value=p-a?(t=[...('.'.repeat(16)+'\n').repeat(5)],t[a]='"',t[p]='@',t.join('')):t='Well done!'
)
<textarea id=T onclick='s()' onkeyup='m(event.keyCode)'></textarea>

EcmaScript 5 스 니펫 (Chrome에서 테스트)

function R(n) { return Math.random()*n|0 }

function s() { m(y=R(5),x=R(8),a=R(5)*17+R(8)+8) }

function m(k) {
  x+=(x<15&k==39)-(x>0&k==37)
  y+=(y<4&k==40)-(y>0&k==38)
  p=y*17+x
  T.value=p-a?(t=('.'.repeat(16)+'\n').repeat(5).split(''),t[a]='"',t[p]='@',t.join('')):t='Well done!'
}
<textarea id=T onclick='s()' onkeyup='m(event.keyCode)'></textarea>


2

액션 스크립트 3 : 267 바이트

실제 사례는 온라인입니다

var a:int,p:int,t;function g(){var r=Math.random;while(p==a){a=r()*80;p=r()*80}addEventListener("keyDown",function(e){if(a==p)return;if(e.keyCode==87&&p>15)p-=16if(e.keyCode==83&&p<64)p+=16if(e.keyCode==65&&p%16>0)p--if(e.keyCode==68&&(p+1)%16>0)p++print()});print()}

게임 기능을 사용하는 완전한 (가독성을 위해 포함 된 공백) 프로그램은 다음과 같습니다.

package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.text.TextFormat;

    public class MiniRogue extends Sprite
    {
        var a:int, p:int, t;

        public function MiniRogue()
        {
            g();
        }

        function g(){
            var r=Math.random;
            while(p==a){
                a=r()*80;
                p=r()*80
            }
            addEventListener("keyDown",function(e){
                if(a==p)
                    return;
                if(e.keyCode==87&&p>15)
                    p-=16
                if(e.keyCode==83&&p<64)
                    p+=16
                if(e.keyCode==65&&p%16>0)
                    p--
                if(e.keyCode==68&&(p+1)%16>0)
                p++
                print()
            });
            print()
        }

        var old:int = -1;
        private function print():void {
            if (!t) {
                t = new TextField()
                t.defaultTextFormat = new TextFormat("_typewriter", 8)
                t.width=500;
                t.height=375;
                addChild(t)
            }
            var board:String = "";
            for (var i:int=0; i<80;i++) {
                if (i == p) {
                    board += "@";
                } else if (i == a) {
                    board += '"';
                } else {
                    board += ".";
                }
                if ((i + 1) % 16 == 0) {
                    board += "\n";
                }
            }
            if (a==p) {
                board += "Win!";
            }
            if (p == old) {
                board += "Bump!";
            }
            old = p;
            t.text = board;
        }
    }
}

2

자바 스크립트 : (307) 216

아래 스 니펫에서 재생할 수 있습니다! 왼쪽의 숫자는 콘솔 (적어도 하나는 크롬)이 행을 병합하지 않도록합니다.

코드를 실행하려면

  1. "실행 코드 스 니펫"을 누르십시오.
  2. ctrl-shift-j를 눌러 콘솔을여십시오.
  3. 결과 섹션을 클릭하십시오
  4. 화살표 키를 사용하여 재생

var x=y=2,m=Math,b=m.floor(m.random()*5),a=14,i,j,t,c=console,onload=d;function d(){c.clear();for(i=0;i<5;i++){t=i;for(j=0;j<16;j++){t+=(i==y&&j==x)?"@":(i==b&&j==a)?'"':".";if(a==x&&b==y)t=":)";}c.log(t);}}onkeydown=function(){switch(window.event.keyCode){case 37:if(x>0)x--;break;case 38:if(y>0)y--;break;case 39:if(x<15)x++;break;case 40:if(y<4)y++;break;}d();};

언 골프 :

var px=py=2,m=Math,ay=m.floor(m.random()*5),ax=14,i,j,t,c=console,onload=draw;
function draw() {
  c.clear();
  for(i=0;i<5;i++) {
    t=i;
    for(j=0;j<16;j++) {
      t+=(i==py&&j==px)?"@":
         (i==ay&&j==ax)?'"':".";
      if(ax==px&&ay==py)t=":)";
    }
    c.log(t);
  }
}
onkeydown=function() {
  switch (window.event.keyCode) {
    case 37:
      if(px>0)px--;
      break;
    case 38:
      if(py>0)py--;
      break;
    case 39:
      if(px<15)px++;
      break;
    case 40:
      if(py<4)py++;
      break;
  }
  draw();
};

편집 1 : 규칙을보다 신중하게 읽고 이에 따라 코드를 다시 작성하십시오.

  • 부적 y 값은 이제 무작위입니다
  • 플레이어는 더 이상 방을 벗어날 수 없습니다
  • 더 이상 draw 함수의 문자를 계산하거나 호출하지 않습니다.

1

SpecBAS - 428 402 (제외한 인쇄, 466 카운트 425)

Q / A / O / P를 사용하여 각각 위 / 아래 / 왼쪽 / 오른쪽으로 이동합니다.

라인 1에서 던전을 인쇄하는 라인은 무시할 수있는 유일한 라인이지만 골프 클럽도 약간 줄었습니다.

1 PRINT ("."*16+#13)*5
2 LET px=8: LET py=3
3 LET ax=INT(RND*16): LET ay=INT(RND*5): IF ax=px AND ay=py THEN GO TO 3
4 PRINT AT ay,ax;#34;AT py,px;"@": LET ox=px: LET oy=py: PAUSE 0: LET k$=INKEY$
5 LET px=px+(k$="p")-(k$="o")
6 IF px<0 THEN LET px=0
7 IF px>15 THEN LET px=15
8 LET py=py+(k$="a")-(k$="q")
9 IF py<0 THEN LET py=0
10 IF py>4 THEN LET py=4
11 PRINT AT oy,ox;"."
12 IF SCREEN$(px,py)<>#34 THEN GO TO 4

# 34에 대한 참조는 CHR $ (34)를 코드에 넣는 간단한 방법입니다.

@Thomas Kwa에게 감사드립니다. 플레이어 시작 위치가 무작위라는 것을 알지 못했습니다. 또한 별도의 IF 문을 사용하여 몇 문자를 제거했습니다.


덜 무작위 화 2 LET px=1: LET py=1: LET ax=2: LET ay=INT(RND*5)하고를 사용하여 일부 문자를 저장할 수도 있습니다 IF instead of ELSE IF.
lirtosiast

1

또 C를 # 221 171 170

다음은 C #에서 두 위치가 무작위 인 다른 방법입니다. 이 부분이 Hand-E-Food의 솔루션보다 7 바이트 더 길더라도 이것을 보여주고 싶었습니다.
Hand-E-Food의 답변은 Console.Read ()를 사용하자마자 더 짧을 것입니다.
Consol.Read의 단점은 필요한 Enter 키를 누르면 필드가 두 번 더 인쇄된다는 것입니다.
그러나 나는 (실제) 입력으로 만 인쇄해야한다고 생각하지 않습니다.

탐색은 Hand-E-Foods 솔루션과 같이 8426에 의해 수행됩니다.

using System;
class P
{
static void Main()
{
Func<int> n=new Random().Next;
int x=n()%16,y=n()%5,a=n()%16,b,m;
while(y==(b=n()%5));

while(x!=a|y!=b)
{
Printer.Print(a, b, x, y);  // Excluded from the score.
m=Console.Read()-48;
y+=m==8&y>0?-1:m==2&y<4?1:0;
x+=m==4&x>0?-1:m==6&x<15?1:0;
}
}
}


편집 : (새로운 솔루션을 추가하고 PrinterClass를 끝으로 이동)
Edit2 : (14에서 15로 변경하고 오른쪽 하단에서 시작하여 바이트를 저장했습니다)

Mauris의 기술을 적용하면 C #에서 171 바이트로 녹일 수 있습니다 (물론 이제 두 위치가 무작위로없는) :

using System;
class P
{
static void Main()
{
int p=79,a=new Random().Next()%p,m;
while(p!=a){
Printer.Print(p,a);  // Excluded from the score.
m=Console.Read()-48;
p+=m==4&p/5>0?-5:m==6&p/5<15?5:m==8&p%5>0?-1:m==2&p%5<4?1:0;
}
}
}

프린터 클래스는 거의 동일하며 새로운 인쇄 과부하입니다.

class Printer
{
    public static void Print(int ax, int ay, int px, int py)
    {
        Console.Write('\n');
        for (int y = 0; y < 5; y++)
        {
            for (int x = 0; x < 16; x++)
            {
                if (x == px && y == py)
                    Console.Write('@');
                else if (x == ax && y == ay)
                    Console.Write('"');
                else
                    Console.Write('.');
            }
            Console.Write('\n');
        }
    }

    public static void Print(int p, int a)
    {
        Print(p/5,p%5,a/5,a%5);
    }
}

1

루비, 185

여기에 Ruby 예제가 있습니다.
루비를 처음 접했을 때 누군가가 더 잘하는 법을 알고있을 것입니다 :)

프로그램이 그렇지 않으면 충돌하기 때문에 lineFeeds를 1로 계산했습니다 ...

탐색은 8462에 의해 수행됩니다. 입력 할 때마다 입력을 보내야합니다.

def display(ax,ay,px,py)
    puts
    for y in 0..4
        for x in 0..15
            if (x == px && y == py)
                print "@"
            elsif (x == ax && y == ay)
                print '"'
            else
                print '.'
            end
        end
        puts
    end
end


x=y=0
a=Random.rand(16) while y==(b=Random.rand(5))
while x!=a or y!=b
display(a,b,x,y)  # Excluded from the score.
m=gets.chomp.to_i
y-=m==8?1:0 if y>0
y+=m==2?1:0 if y<4
x-=m==4?1:0 if x>0
x+=m==6?1:0 if x<15
end

0

Q 기본, 103 바이트

챌린지 규칙에 따라 Show서브 프로그램은 바이트 수에 포함되지 않으며 Show p, q, a, b호출 도 없습니다 (다음 줄 바꾸기 포함).

b=1+TIMER MOD 9
1Show p, q, a, b
INPUT m
p=p-(m=2)*(p>0)+(m=4)*(p<4)
q=q-(m=1)*(q>0)+(m=3)*(q<15)
IF(p<>a)+(q<>b)GOTO 1


SUB Show (playerRow, playerCol, amuletRow, amuletCol)
CLS
FOR row = 0 TO 4
  FOR col = 0 TO 15
    IF row = playerRow AND col = playerCol THEN
      PRINT "@";
    ELSEIF row = amuletRow AND col = amuletCol THEN
      PRINT CHR$(34);    ' Double quote mark
    ELSE
      PRINT ".";
    END IF
  NEXT
  PRINT
NEXT
END SUB

이동하려면 숫자를 입력하고 Enter : 1를 눌러 왼쪽으로, 2위로, 3오른쪽으로, 4아래로 이동하십시오.

이 코드는 플레이어가 부적을 찾았을 때 게임 상태를 출력하지 않습니다. 그렇게하려면 명령문 Show p, q, a, b다음 에 다른 것을 추가하십시오 IF.

설명

하자 a, b하여 부적의 좌표와 표현 p, q플레이어의 좌표를. 플레이어는 (0, 0)에서 시작하고 부적은 현재 행의 1 자리를 기준으로 1에서 9 사이의 열을 포함하여 0 행에서 시작합니다.

나머지는 조건부와 함께 많은 수학입니다. 기억해야 할 중요한 점은 QBasic의 조건이 참 0, 거짓으로 돌아온다 -1는 것입니다. 플레이어 행 업데이트 문을 살펴 보겠습니다.

p=p-(m=2)*(p>0)+(m=4)*(p<4)

경우 m=2, 우리는에서 1을 뺀 이동 할 p만큼, p>0. 마찬가지로, 경우에 m=4, 우리는에 1을 추가하여 아래로 이동 할 p만큼, p<4. 곱하면 원하는 동작을 얻을 수 있습니다. 두 요소가 모두 같다면 -1, 그들의 제품은 1우리가 빼거나 더할 수있다 p. 조건부 중 하나가 0이면 제품은 0효과가 없습니다.

마찬가지로 플레이어가 부적을 찾았는지 여부를 판별하는 조건은 다음과 같습니다.

IF(p<>a)+(q<>b)GOTO 1

조건문 중 하나에 해당하는 경우, 그 합이 제로가 아닌 것 (하나 -1또는 -2) 따라서 truthy, 프로그램은 1 번 줄을 반환 p같음 aq동일 b모두 조건문이 될 것입니다, 0그 합이 될 수 있도록, 0제어 흐름이 도달 할 수 프로그램의 끝.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.