クラシックVCS ASCIIアドベンチャー


21

成長して、私の最初のコンソールゲームシステムはAtari 2600でした。私は子供の頃にとても楽しんだゲームのいくつかを常に愛しています。グラフィックの多くはまだ記憶に残るものであり、おそらく象徴的です。

これらのスプライトは非常に単純なビットマップで、幅が8ピクセルで、高さが可変であり、バイナリ表現はピクセルの配置です。

たとえば、16進バイト0x18、0x24、0x18は、次のような粗い円を描きます。

0x18: 00011000
0x24: 00100100
0x18: 00011000

8ピクセル幅はかなり小さなグラフィックスを作成するため(Atari 2600規格でも)、高さ、幅、またはその両方を2倍または4倍にして、同じ画像のより大きな(よりブロッキーでゆがんだ)バージョンを作成するのが一般的でした。通常、プレーヤーのスプライトとプレイフィールドの両方で、垂直または水平に反転されます。ゲームの戦闘はこれの良い例です。

課題は、これらのスプライトをASCII形式の「グラフィック」として表示するコードを作成することです。これには、スプライトを垂直、水平、またはその両方に伸縮する機能が含まれます。これは、完全なプログラムまたは呼び出し可能な関数の形式である必要があります。

入力:

  • それぞれがその行の水平ビットを表すバイトの配列。
  • 各方向のゼロ以外の整数値。水平および垂直は、その次元のスケーリング係数を表します。
  • 負の値は、ディメンションが軸に沿って反転されることを示します。

出力:

  • STDOUTまたは改行で区切られた文字列へのASCII表現。黒(0)ピクセルにはスペース文字を使用し、白(1)ピクセルには任意の印刷可能な非スペース文字を使用します。

テストデータ:

bmp1 = [ 0x06, 0x0F, 0xF3, 0xFE, 0x0E, 0x04, 0x04, 0x1E, 0x3F, 0x7F, 0xE3, 0xC3, 0xC3, 0xC7, 0xFF, 0x3C, 0x08, 0x8F, 0xE1, 0x3F ]
bmp2 = [ 0x07, 0xFD, 0xA7 ]
bmp3 = [ 0x00, 0x8E, 0x84, 0xFF, 0xFF, 0x04, 0x0E, 0x00 ]
bmp4 = [ 0x00, 0xFC, 0xFC, 0x38, 0x3F, 0x38, 0xFC, 0xFC]

注:上記の入力バイト配列の例は、16進数で提供されています。プラットフォームがバイト表現に16進リテラルを受け入れない場合、それらをネイティブのバイト等価リテラルに変換できます。

出力例:

f( bmp1, 1, 1 ) =>
--------
     XX 
    XXXX
XXXX  XX
XXXXXXX 
    XXX 
     X  
     X  
   XXXX 
  XXXXXX
 XXXXXXX
XXX   XX
XX    XX
XX    XX
XX   XXX
XXXXXXXX
  XXXX  
    X   
X   XXXX
XXX    X
  XXXXXX
--------

f( bmp1, -2, 1 ) =>
----------------
  XXXX          
XXXXXXXX        
XXXX    XXXXXXXX
  XXXXXXXXXXXXXX
  XXXXXX        
    XX          
    XX          
  XXXXXXXX      
XXXXXXXXXXXX    
XXXXXXXXXXXXXX  
XXXX      XXXXXX
XXXX        XXXX
XXXX        XXXX
XXXXXX      XXXX
XXXXXXXXXXXXXXXX
    XXXXXXXX    
      XX        
XXXXXXXX      XX
XX        XXXXXX
XXXXXXXXXXXX    
----------------

f( bmp2, 1, 2 ) =>
--------
     XXX
     XXX
XXXXXX X
XXXXXX X
X X  XXX
X X  XXX
--------

f( bmp2, 2, 1 ) =>
----------------
          XXXXXX
XXXXXXXXXXXX  XX
XX  XX    XXXXXX
----------------

f( bmp2, -2, -2 ) =>
----------------
XXXXXX    XX  XX
XXXXXX    XX  XX
XX  XXXXXXXXXXXX
XX  XXXXXXXXXXXX
XXXXXX          
XXXXXX          
----------------

f( bmp3, 1, -1 ) =>
--------

    XXX 
     X  
XXXXXXXX
XXXXXXXX
X    X  
X   XXX 

--------

f( bmp3, 3, 3 ) =>
------------------------



XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX         XXXXXXXXX   
XXX            XXX      
XXX            XXX      
XXX            XXX      
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX
               XXX      
               XXX      
               XXX      
            XXXXXXXXX   
            XXXXXXXXX   
            XXXXXXXXX   



------------------------

f( bmp4, -1, -1 ) =>
--------
  XXXXXX
  XXXXXX
   XXX  
XXXXXX  
   XXX  
  XXXXXX
  XXXXXX

--------

f( bmp4, 4, 2 ) =>
--------------------------------


XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXXXXXXXXXXXXXX
        XXXXXXXXXXXX            
        XXXXXXXXXXXX            
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
XXXXXXXXXXXXXXXXXXXXXXXX        
--------------------------------

注:上下の水平線は、出力の開始と終了を示しています。出力では必要ありませんが、示されているように、先頭および/または末尾に空の行(すべてゼロ/スペースで表される)が必要です。

注2:これらのテストビットマップは、Wikipediaで「公正使用」とタグ付けされたゲームスクリーンショットに基づいてインスピレーションを受け、再描画/コード化されました。

受賞基準

  • これはであるため、言語ごとのバイト単位の最短コードが優先されます。
  • 標準的な抜け穴は禁止されています。

6
「だれかがこのおかしなアヒルを私から遠ざけます!」- 強力なバート
AdmBorkBork

7
皮肉なことに、ここで最も賢いゴルフでも、Pongクローンよりも面白いものが必要な場合、Atari 2600のプログラマーが実際にやらなければならないほど賢くはありません。画面全体が一度に1行ずつレンダリングされ、 CPUはほとんどの時間をそのために費やしました。RAMが128バイトしかないため、スクリーンバッファーのような贅沢品を入れる余地はありませんでした...入手した5つのスプライト全体贅沢品でした。
Jeroen Mostert

入力を8ビットのバイナリ文字列のリスト、またはバイトが既にビットに展開されている同様の形式として取得できますか?
ルイスメンドー

@LuisMendo " プラットフォームがバイト表現に16進リテラルを受け入れない場合、ネイティブのバイト等価リテラルに変換できます。 "
Kevin Cruijssen

@KevinCruijssenそれがポイントです、私は同等のものとして受け入れられるものがわかりません。それはビットマップを直接入力するドアを開きますか?
ルイスメンドー

回答:



5

05AB1E27 26 バイト

εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»

入力を8ビットのバイナリ文字列のリストとして受け取り、1非スペース文字として出力します。

@MagicOctopusUrnのおかげで-1バイト。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

ε         # Map the (implicit) input-list to:
 S        #  Convert the binary-String to a list of characters
  ²Ä      #  Take the absolute value of the second input
    ×     #  And repeat each character that many times
     J    #  And then join it back together to a single string again
 ³Ä       #  Take the absolute value of the third input
   и      #  Repeat that string as a list that many times
 ²0i     #  If the second input is negative:
     í    #   Reverse each string in the list
]         # Close both the if-statement and (outer) map
³0i }    # If the third input is negative:
    R     #  Reverse the list of lists
      ˜   # Flatten the list of lists to a list of strings
0ð:       # Replace all 0s with spaces " "
   »      # And join the strings by newlines (which is output implicitly)

2-byterがなければならない0‹i...
マジックタコ壺

@MagicOctopusUrn 0‹実際には1バイトが必要です。.には1バイト>=0がありdます。ただし、負のimoをチェックするために1バイトも必要です。今は、0‹またはを使用していますd_
ケビンクルーイッセン

私が思いついたのは、„íR³²‚0‹Ï.V(完全なコードεε²Ä×}J³Äи0ð:}„íR³²‚0‹Ï.V˜»)改善だけではありませんが、それらのネガティブチェックの1つを取り除きます。
魔法のタコUr

1
また、εS²Ä×J³Äи²0‹ií]³0‹iR}˜0ð:»バイトを節約することもできます。2D配列を取得できる場合はS、25バイト全体を削除できます。
マジックタコOct

@MagicOctopusUrnもちろん、S²Ä×代わりにε²Ä×}。ありがとう!うーん、バイナリ入力を0と1のリストとして許可する場合、を省略することで追加のバイトを保存できますS。これが許可されているかどうかをOPに尋ねます。„íR³²‚0‹Ï.Vあなたのその他のコメントにもあなたが好きです。:)
ケビン・クルーッセン

3

MATL24 19バイト

B,!i|1&Y"2M0<?XP]Zc

入力は、10進数の配列、水平スケール、垂直スケールです。

オンラインでお試しください!

説明

B        % Implicit input: array of numbers. Convert to binary. Gives a zero-one
         % matrix, each row containing the binary expansion of a number
,        % Do twice
  !      %   Transpose
  i      %   Input: number
  |      %   Absolute value
  1&Y"   %   Repeat each row that many times
  2M     %   Push the latest input again
  0<     %   Is it negative?
  ?      %   If so:
    XP   %     Flip vertically
  ]      %   End
  Zc     %   Convert each nonzero into '#'. Zeros are displayed as space
         % Implicit end. Implicit display

3

Dyalog APL、46 42 33バイト

' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]

オンラインでお試しください!

-9 ngnに感謝!


それぞれ->削減:{' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⍺,⊂⍉⍵⊤⍨8/2]}' #'[⊃{⌽⍣(0>⍺)⊢(|⍺)/⍉⍵}/⎕,⊂⍉⎕⊤⍨8/2]
dfn-

短い:' #'[⍉⊃{⊖⍣(0>⍺)⍉⍵/⍨|⍺}/⎕,⊂⎕⊤⍨8/2]。ところで、2番目のテストの出力は元のソリューションでは逆になっているように見えます
ngn

@ngnありがとう!2番目の例の入力は、質問の2番目のテストケースに一致するように逆にする必要があります。
dzaima

3

プロローグ(SWI)、252バイト

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).

オンラインでお試しください!

説明

N+E+R:-N<1,R=[];N-1+E+S,R=[E|S].   Make `R` a list containing `E` repeated `N` times
       N<1,R=[]                    If `N<1`, let `R` be the empty list
       N-1+E+S                     Else recurse with `N-1`, `E` and `S`
           R=[E|S]                 Let `R` be a new list with `E` as head and `S` as tail
N*E*R:-R=E,E=[];N<0,reverse(E,F),-N*F*R;[H|T]=E,N+H+S,N*T*U,append(S,U,R).
                                   Let `R` be a list
                                   with each element in `E` repeated `N` times
                                   e.g. 2*[3, 6] -> [3, 3, 6, 6]
       R=E,E=[]                    Let `R` be `E` if `E` is the empty list
       N<0,reverse(E,F)            Else if `N<0`, let `F` be the reverse of `E`
           -N*F*R                  Recurse with `-N`, `F` and `R`
       [H|T]=E                     Else let `H` be the head and `T` be the tail of `E`
           N+H+S                   Let `S` be `N+H+S` (our function, not addition)
           N*T*U                   Recurse with `N`, `T` and `U`
           append(S,U,R)           let `R` be the concatenation of `S` and `U`
N/E/R:-N<1,R=[];(E<N,D=E,F=32;D=E-N,F=35),N/2/D/C,R=[F|C].
                                   Make `R` the binary representation of `E`
                                   with `N` as the value of the current bit
                                   where 0 and 1 are space and hash respectively
    N<1,R=[]                       If `N<1` let `R` be the empty list
    (
        E<N,D=E,F=32               If `E<N` the bit isn't set, so `D=E`, `F=space`
        D=E-N,F=35                 Else `D=E-N`, `F=hash`
    )
        N/2/D/C                    Recurse with `N/2`, `D` and `C`
        R=[F|C]                    Let `R` be a new list with `F` as head and `C` as tail
[H|T]^X^Y^R:-128/H/A,X*A*B,Y*[[10|B]]*C,append(C,D),(T=[],R=D;T^X^Y^S,append(D,S,R)).
                                   Make `R` the result,
                                   with inputs being the list `[H|T]`
                                   and the scales `X` and `Y`
   128/H/A                         Let `A` be the binary representation of `H` (8 bits)
   X*A*B                           Let `B` be `A` with each element repeated `X` times
   Y*[[10|B]]*C                    Let `C` be `B` with a newline prepended,
                                   repeated `Y` times
   append(C,D)                     Let `D` be `C` flattened by one level (joining lines)
   (
       T=[],R=D                    If `T` is empty, let `R` be `D` 
       T^X^Y^S                     Else recurse with `T`, `X`, `Y` and `S`
           append(D,S,R)           Let `R` be the concatenation of `D` and `S`
   )

2

、28バイト

FθE↔ζ⭆⮌↨ι²×§ Xμ↔ηF›η⁰‖F‹ζ⁰‖↓

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

Fθ

バイトのリストをループします。

E↔ζ

垂直スケーリングファクターにマップし、出力ラインを乗算します。

⭆⮌↨ι²×§ Xμ↔η

入力を基数2に変換し、それを逆にし、数字をスペースにマップしてからX、各文字に水平スケーリング係数を掛けます。

F›η⁰‖

水平方向の倍率が正の場合、反射して画像を正しい方向に戻します。

F‹ζ⁰‖↓

垂直スケーリング係数が負の場合、垂直に反映します。


それはどんなバイトを保存するだろうが、私はちょうど興味がないこと:なぜあなたは使用しなかったFFor代わりに)¿Ifチェックのため)?
ケビンクルーイッセン

1
@KevinCruijssen木炭簡潔モードではelseが暗示されるため、使用できるのifはブロック内の最後のステートメントである場合のみです。
ニール

ああ、それを知らなかった。したがって、Ifここで2つを使用すると、実際If ... Else If ...には2つのルーズの代わりになりますIf。うーん、知っておくといい。
ケビンクルーイッセン


2

Common Lisp、157バイト

(lambda(l x y)(dolist(i(if(< y 0)(reverse l)l))(dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))(princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))(princ"
"))))

オンラインでお試しください!

説明

(lambda(l x y)                           ; Lambda with parameters `l`, `x`, `y`
    (dolist
        (i                               ; For `i` in the list  
            (if(< y 0)(reverse l)l)      ; The reverse of `l` if `y<0` else `l`
        )
        (dotimes(j(abs y))(dotimes(n 8)(dotimes(k(abs x))
                                         ; Do `y` times, for `n` from 0 to 7, do `x` times
        (princ(if(logbitp(if(< x 0)n(- 7 n))i)"#"" "))))
                                         ; If `x<0` and the `n`th bit is 1
                                         ; or `x>0` and the `7-n`th bit is 1
                                         ; print "#", else print " "
        (princ"
")                                       ; After every `y` loop, print a newline
        )
    )
)

2

Tcl、192バイト

proc f {l x y} {lmap i [if $y<0 {lreverse $l} {lindex $l}] {time {lmap n {0 1 2 3 4 5 6 7} {time {puts -nonewline [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]} [expr abs($x)]};puts {}} [expr abs($y)]}}

オンラインでお試しください!

proc f {l x y}                           Define a function `f` with arguments `l`, `x`, `y`
{lmap i                                  For each `i` in
    [if $y<0 {lreverse $l} {lindex $l}]  The reverse of `l` if `y<0` else `l`
    {
        time {                           Do `abs(y)` times
            lmap n {0 1 2 3 4 5 6 7} {   For `n` from 0 to 7
                time {                   Do `abs(x)` times
                    puts -nonewline      Print without newline
                         [expr $i&1<<($x<0?$n:7-$n)?{#}:{ }]
                                         If `x<0` and the `n`th bit is 1 or
                                         `x>0` and the `7-n`th bit is 1
                                         then return "#" else return " "
                } [expr abs($x)]
            };
            puts {}                      Print a newline
        } [expr abs($y)]
    }
}

2

8088マシンコード、IBM PC DOS、 77 71バイト

組み立て済み:

B402 84FF 7906 FD03 F14E F6DF 518A CFAC 5051 B108 8AF3 84F6 7902 F6DE
518A CEB2 2384 DB79 04D0 C8EB 02D0 C072 02B2 2050 CD21 58E2 FA59 E2E4
B20D CD21 B20A CD21 5958 E2CC 59E2 C5

リスト:

    PR_BMP  MACRO BMP, SZBMP, ZX, ZY
            LOCAL LOOP_Y, LOOP_Y2, LOOP_X, LOOP_X2, X_POS, X_NEG
B4 02   MOV  AH, 2          ; DOS display char function 
84 FF   TEST ZY, ZY         ; is Y scale negative?
79 06   JNS  LOOP_Y         ; if positive, start Y LOOP
FD      STD                 ; direction flag start from end
03 F1   ADD  BMP, CX        ; advance input byte array to end
4E      DEC  BMP            ; zero adjust index
F6 DF   NEG  ZY             ; make counter positive
     LOOP_Y:    
51      PUSH CX             ; save outer byte loop counter
8A CF   MOV  CL, ZY         ; set up repeat counter (Y scale factor)
AC      LODSB               ; load byte into AL
     LOOP_Y2:
50      PUSH AX             ; save original AL
51      PUSH CX             ; save outer loop
B1 08   MOV  CL, 8          ; loop 8 bits
8A F3   MOV  DH, ZX         ; DH is positive X scale used as counter
84 F6   TEST ZX, ZX         ; is X scale negative?
79 02   JNS  LOOP_X         ; if so, make counter positive
F6 DE   NEG  DH             ; compliment X counter 
    LOOP_X:
51      PUSH CX             ; save bit counter
8A CE   MOV  CL, DH         ; set repeat counter (X scale factor)
B2 23   MOV  DL, '#'        ; by default, display a #
84 DB   TEST ZX, ZX         ; is X scale negative?
79 04   JNS  X_POS          ; if so, rotate left 1 bit
D0 C8   ROR  AL, 1          ; else rotate right LSB into CF
EB 02   JMP  X_NEG          ; jump to examine CF
    X_POS:
D0 C0   ROL  AL, 1          ; rotate left MSB into CF
    X_NEG:
72 02   JC   LOOP_X2        ; is a 1?   
B2 20   MOV  DL, ' '        ; if not, display a space
    LOOP_X2:    
50      PUSH AX             ; save AL (since silly DOS overwrites it)
CD 21   INT  21H            ; display char
58      POP  AX             ; restore AL
E2 FA   LOOP LOOP_X2        ; loop repeat counter
59      POP  CX             ; restore bit counter
E2 E4   LOOP LOOP_X         ; loop bit counter
B2 0D   MOV  DL, 0DH        ; display CRLF
CD 21   INT  21H
B2 0A   MOV  DL, 0AH
CD 21   INT  21H
59      POP  CX             ; restore outer loop
58      POP  AX             ; restore original AL
E2 CC   LOOP LOOP_Y2        ; loop row display
59      POP  CX             ; restore byte counter
E2 C5   LOOP LOOP_Y         ; loop byte counter
    ENDM

これは、私が当初考えていたよりも、ASMですごいことになりました。複数の同時ループと多数のif / else分岐は確かに頭痛の種になります。

これは、テスト用の関数のようなパラメーターの受け渡しを可能にするため、MACROとして実装されます。

出力

XおよびYスケーリング係数の入力を求めて画面に描画するDOS用のテストプログラムを次に示します。デフォルトのDOSウィンドウは24行しかないため、ドラゴンのスケーリングが大きすぎると、上部を過ぎてスクロールします。

ここに画像の説明を入力してください

そして、ここに私たちの小さなドラゴン(アヒル)があります:

ここに画像の説明を入力してください

オンラインでお試しください!

DOSBoxまたはVirtualConsoles.comを使用して、次の手順でDOS VMでテストできます。

  1. VCS.ZIPをダウンロード(4つすべての実行可能ファイルを含む)
  2. https://virtualconsoles.com/online-emulators/DOS/にアクセスます
  3. ダウンロードしたZIPファイルをアップロードし、[開始]をクリックします
  4. 入力しPLANEKEYTANKまたはDRAGON



1

APL(Dyalog Extended)、23 バイトSBCS

dzaimaの方法

(v,h,B)vhB⎕IO←0

' x'⊇⍨∘⊃{⊖⍣(>⍺)⍉⍵/⍨|⍺}/

オンラインでお試しください!

{}/ 次の匿名ラムダを使用して、右から左に減らします。

|⍺ 左引数の大きさ(スケーリング係数)

⍵/⍨ それを使用して、正しい引数を水平に複製します

 転置

⊖⍣(…次の) 場合に反転:

  >⍺ スケーリング係数がゼロ未満です

 開示(テンソルランクを1から0に減らすために削減が含まれているため)

' x'⊇⍨ その行列を使用して文字列「x」から要素を選択します



1

T-SQL、216バイト

このMS-SQL Studio管理を実行する前に、CRTL-tを押してデータをテキストとして表示します。入力の要素数を超えるように高さを調整することはできません。

STRING_AGGの恐ろしい実装のため、高さ変数はMSSMでのみ機能します。MSは、連結される要素の順序を含めるための3番目のオプションパラメータを作成する必要がありました。

オンライン版は幅の調整のみをサポートできます。高さは、複数のスタッキングシェイプでファンキーな結果になります。

USE master
DECLARE @ table(v int,i int identity)
INSERT @ values
(0x06),(0x0F),(0xF3),(0xFE),(0x0E),(0x04),
(0x04),(0x1E),(0x3F),(0x7F),(0xE3),(0xC3),
(0xC3),(0xC7),(0xFF),(0x3C),(0x08),(0x8F),
(0xE1),(0x3F)
-- @  = width
-- @h = height
DECLARE @s INT=1,@h INT=1

SELECT iif(@s>0,reverse(x),x)FROM(SELECT
string_agg(replicate(iif(v&n=0,' ','X'),abs(@s)),'')x,i,j
FROM(values(1),(2),(4),(8),(16),(32),(64),(128))x(n)
,@,(SELECT top(abs(@h))i j FROM @)g GROUP BY i,j)f
ORDER BY i*@h

このスクリプトでは、オンラインバージョンでは正しい形状が表示されないため、補正のために若干の調整を行いました。 オンラインで試す

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.