キャンバスの周りの8ビットスタイルのバウンドボール


20

Commodore 64ユーザーズガイドのこのリストに触発された:

10 PRINT "{CLR/HOME}"
20 POKE 53280,7 : POKE 53281,13
30 X = 1 : Y = 1
40 DX = 1 : DY = 1
50 POKE 1024 + X + 40 * Y, 81
60 FOR T = 1 TO 10 : NEXT
70 POKE 1024 + X + 40 * Y, 32
80 X = X + DX
90 IF X <= 0 OR X >= 39 THEN DX = -DX
100 Y = Y + DY
110 IF Y <= 0 OR Y >= 24 THEN DY = -DY
120 GOTO 50

選択した言語/プラットフォームで同様のプログラムを作成して、端末、画面、キャンバス、またはその他の視覚表示領域の周りにボールのようなオブジェクトをバウンスします。

あなたは、C64のPETSCIIグラフィック正確に模倣するために、単純なを持っていないOか、oでしょう、また、あなたが使用する必要がありませんGOTO、それはまだあなたの言語に存在する場合、コマンドを。次のように、ボールがキャンバスの上部から開始し、キャンバスの制限に達するまで斜めに移動し、それに応じてバウンドする限り:

  • 下方向および右方向に移動して画面領域の下部に当たり、跳ね返って右方向に進みます。
  • 上下に移動して右端の境界に当たり、左右に跳ね返ります。
  • 上下に移動して上部に当たり、左右にバウンドします。
  • 左および下に移動して左端の境界に到達し、右および下にバウンドします。
  • 任意のコーナーをヒットし、方向を逆にします。

その後、私たちはすべて元気です。

C64のBASICリストにあるように、ボールを一度に8ピクセルずつ移動する必要もありません。一度に1つの文字ブロックまたは1つのピクセルのどちらか適切な方を移動できます。

このBASICリストが機能することを確認するには、ブラウザがFlashをサポートしている場合に、このオンラインCommodore 64エミュレータでそれを入力します。


2
JavaScriptキャンバス。ああ
マシュー

最近、スクリーンと呼んでいるものがわかりません。以前は、テレビやVDUで画面と境界領域だけを表示していましたが、今では端末、ウィンドウ、キャンバス、標準出力などがあります。
ショーンビバーズ

ピクセルサイズの値を一定にしておいた方が良いでしょう。
マシュー盧

4
1x1の画面サイズを想定して、永久にoを印刷できますか?
マシュー

回答:


3

6502マシンコード(C64)、90 89 91バイト

ロードアドレスが必要なため、+ 2バイト(自己修正のためPICではありません)

00 C0 20 44 E5 CA D0 FD C6 FC D0 F9 A2 20 86 FC A9 D8 85 9E A9 03 85 9F A4 CA
18 A5 9E 69 28 85 9E 90 02 E6 9F 88 10 F2 A4 C9 8A 91 9E C9 20 D0 08 E6 C9 E6
CA A2 51 10 D7 A5 C9 F0 04 C9 27 D0 08 AD 2F C0 49 20 8D 2F C0 A5 CA F0 04 C9
18 D0 B4 AD 31 C0 49 20 8D 31 C0 D0 AA

オンラインデモ

使用法: sys49152

TitusのゴルフC64 BASICのレベルに到達するのはまだ不可能であるため、サイズを減らすために一生懸命努力しました(たとえば、タイミングにIRQを使用せず、代わりに愚かな空のループ)。しかし、ちらつきが少ないように見えます;)

説明:(副分解)

00 C0       .WORD $C000         ; load address
20 44 E5    JSR $E544           ; clear screen
CA          DEX
D0 FD       BNE $C003           ; inner wait (256 decrements)
C6 FC       DEC $FC
D0 F9       BNE $C003           ; outer wait (32 decrements in zeropage)
A2 20       LDX #$20            ; wait counter and screen code for "space"
86 FC       STX $FC             ; store wait counter
A9 D8       LDA #$D8            ; load screen base address ...
85 9E       STA $9E             ; ... -40 (quasi row "-1") ...
A9 03       LDA #$03            ; ... into vector at $9e/$9f
85 9F       STA $9F
A4 CA       LDY $CA             ; load current row in Y
18          CLC                 ; clear carry flag
A5 9E       LDA $9E             ; add ...
69 28       ADC #$28            ; ... $28 (40 cols) to ...
85 9E       STA $9E             ; ... vector
90 02       BCC $C023
E6 9F       INC $9F             ; handle carry
88          DEY                 ; count rows down
10 F2       BPL $C018
A4 C9       LDY $C9             ; load current col in Y
8A          TXA                 ; copy screen code from X to A
91 9E       STA ($9E),Y         ; store at position of screen
C9 20       CMP #$20            ; screen code was "space"
D0 08       BNE $C037           ; if not, ball was drawn
E6 C9       INC $C9             ; next column   | opcodes are modified
E6 CA       INC $CA             ; next row      | here for directions
A2 51       LDX #$51            ; screen code for "ball"
10 D7       BPL $C00E           ; and back to drawing code
A5 C9       LDA $C9             ; load current column
F0 04       BEQ $C03F           ; if zero, change X direction
C9 27       CMP #$27            ; compare with last column (39)
D0 08       BNE $C047           ; if not equal, don't change X direction
AD 2F C0    LDA $C02F           ; load opcode for X direction
49 20       EOR #$20            ; toggle between ZP INC and DEC
8D 2F C0    STA $C02F           ; store back
A5 CA       LDA $CA             ; load current row
F0 04       BEQ $C04F           ; if zero, change Y direction
C9 18       CMP #$18            ; compare with last row (24)
D0 B4       BNE $C003           ; if not equal, don't change Y direction
AD 31 C0    LDA $C031           ; load opcode for Y direction
49 20       EOR #$20            ; toggle between ZP INC and DEC
8D 31 C0    STA $C031           ; store back
D0 AA       BNE $C003           ; -> main loop

楽しみのために、ここではボールにスプライトを使用し、385バイト(ヒットしたスプライトデータを含む)所定の場所で

00 C0 AD 15 D0 F0 30 A9 CC 85 FC A9 04 20 A2 C0 A9 97 8D 00 DD A9 15 8D 18 D0 
A9 00 8D 15 D0 8D 1A D0 A2 81 8E 0D DC A2 31 8E 14 03 A2 EA 8E 15 03 58 A6 D6 
4C F0 E9 A9 04 85 FC A9 CC 20 A2 C0 A2 31 86 01 A2 10 A9 D0 85 FC B1 FB C6 01 
91 FB E6 01 C8 D0 F5 E6 FC CA D0 F0 A9 37 85 01 A9 94 8D 00 DD A9 35 8D 18 D0 
8D 27 D0 A2 05 8E F8 CF A2 01 8E 15 D0 8E 1A D0 8E 12 D0 86 FD 86 FE A2 18 8E 
00 D0 A2 1B 8E 11 D0 A2 32 8E 01 D0 A2 7F 8E 0D DC AE 0D DC AE 20 D0 86 FB A2 
C1 8E 14 03 A2 C0 D0 8A 85 FE 8D 88 02 A9 00 85 FB 85 FD A2 04 A0 00 78 B1 FB 
91 FD C8 D0 F9 E6 FC E6 FE CA D0 F2 60 A6 FB 8E 20 D0 CE 19 D0 A5 FD F0 20 AD 
00 D0 18 69 04 8D 00 D0 90 03 EE 10 D0 C9 40 D0 2C AD 10 D0 29 01 F0 25 20 38 
C1 C6 FD F0 1E AD 00 D0 38 E9 04 8D 00 D0 B0 03 CE 10 D0 C9 18 D0 0C AD 10 D0 
29 01 D0 05 20 38 C1 E6 FD A5 FE F0 14 AD 01 D0 18 69 04 8D 01 D0 C9 E6 D0 19 
20 38 C1 C6 FE F0 12 AD 01 D0 38 E9 04 8D 01 D0 C9 32 D0 05 20 38 C1 E6 FE 4C 
31 EA A9 01 8D 20 D0 60 00 00 00 7E 00 03 FF C0 07 FF E0 1F FF F8 1F FF F8 3F 
FF FC 7F FF FE 7F FF FE FF FF FF FF FF FF FF FF FF FF FF FF 7F FF FE 7F FF FE 
3F FF FC 1F FF F8 1F FF F8 07 FF E0 03 FF C0 00 7E 00 00 00 00 

オンラインデモ -| -ca65アセンブラーソースの参照

で跳ねるボールを開始および停止しsys49152ます。

  • これにより、C64 BASICが実行されたままになります。これは、VIC-IIアドレス空間をに移動することによって行われ$C000、画面コンテンツと文字セット(フォント)をコピーする必要があります。
  • システムIRQにフックし、ちらつきを防ぐため、このIRQのソースをVIC-IIグラフィックチップに変更します。したがって、更新は常にフレーム間で行われます。
  • グリッチ:
    1. RUN/STOP + RESTORE 壊れている、試さないでください。
    2. VIC-IIをIRQソースとして使用すると、カーソルの点滅が少し遅くなり、 TI$同様に遅れます。
    3. 境界線が点滅しているときに停止すると(非常に可能性は低いが可能)、白のままになります。手動で復元する必要があります。

1
完全に独立しているわけではありませんか?2つの絶対LDAと2つのSTAが表示されます。それにもかかわらず、すばらしい仕事です!
タイタス

くそ、あなたは正しい:o自己修正を忘れてしまった!PCにアクセスしたらすぐに更新します。
フェリックスパルメン

1
@Titusが修正されました...そして楽しみのために、「より良い」バリアントを追加しました:)
Felix Palmen

スプライトの梱包を検討しましたか?(?うーん...文字セットROMを使用)とI'dが好むinc $d020以上jsr flash;)hitshimselfwithalargetrout It's素晴らしいです!
タイタス

1
@Titusは2バイト節約します、はい。ロードアドレスに関しては、それは有効な.prgファイルの一部であり、ここでのメタ質問から私はそれを含める必要があります...コードが位置に依存しない場合はおそらくそれを除外できます。
フェリックスパルメン

14

Bash + Unixユーティリティ、125 117バイト

for((x=y=u=v=1;;x+=u,y+=v,u=(x<1||x>=`tput cols`-1)?-u:u,v=(y<1||y>=`tput lines`-1)?-v:v)){
tput cup $y $x
sleep .1
}

サンプル実行のアニメーション:

Animation of sample run


6
まさに角を曲がった!:O
mbomb007

11

CP-1610アセンブリ、6764 62 DECLE = 78バイト

このコードは、Intellivisionで実行することを目的としています。MOB(モバイルオブジェクト用)として知られるハードウェアスプライトの1つを使用しています。

CP-1610オペコードは、「DECLE」として知られる10ビット値でエンコードされます。このプログラムの長さは62 DECLEで、4800ドルから483Dで終わります。

16進ダンプ+ソース

                            ROMW  10            ; use 10-bit ROM
                            ORG   $4800         ; start program at address $4800

                    FRAME   EQU   $17E          ; frame #

                            ;; ------------------------------------------------ ;;
                            ;;  main entry point                                ;;
                            ;; ------------------------------------------------ ;;
                    main    PROC

4800 0001                   SDBD                ; load Interrupt Service Routine
4801 02B8 002B 0048         MVII  #isr,   R0    ; into R0

4804 0240 0100              MVO   R0,     $100  ; update ISR
4806 0040                   SWAP  R0
4807 0240 0101              MVO   R0,     $101

4809 02B9 0208              MVII  #$0208, R1    ; initialize R1 = X
480B 02BA 0108              MVII  #$0108, R2    ; initialize R2 = Y
480D 02BB 0001              MVII  #1,     R3    ; initialize R3 = DX
480F 009C                   MOVR  R3,     R4    ; initialize R4 = DY

4810 0002                   EIS                 ; enable interrupts

                            ;; ------------------------------------------------ ;;
                            ;;  main loop                                       ;;
                            ;; ------------------------------------------------ ;;
4811 0280 017E      @@loop  MVI   FRAME,  R0    ; R0 = current frame #

4813 0340 017E      @@spin  CMP   FRAME,  R0    ; wait for next frame
4815 0224 0003              BEQ   @@spin

4817 00D9                   ADDR  R3,     R1    ; X += DX

4818 0379 02A0              CMPI  #$2A0,  R1    ; reached right border?
481A 0204 0003              BEQ   @@updDx

481C 0379 0208              CMPI  #$208,  R1    ; reached left border?
481E 002F                   ADCR  PC

481F 0023           @@updDx NEGR  R3            ; DX = -DX

4820 00E2                   ADDR  R4,     R2    ; Y += DY

4821 037A 0160              CMPI  #$160,  R2    ; reached bottom border?
4823 0204 0003              BEQ   @@updDy

4825 037A 0108              CMPI  #$108,  R2    ; reached top border?
4827 002F                   ADCR  PC

4828 0024           @@updDy NEGR  R4            ; DY = -DY

4829 0220 0019              B     @@loop        ; loop forever

                            ENDP

                            ;; ------------------------------------------------ ;;
                            ;;  ISR                                             ;;
                            ;; ------------------------------------------------ ;;
                    isr     PROC

482B 01DB                   CLRR  R3            ; clear a bunch of STIC registers
482C 02BC 0020              MVII  #$20,   R4

482E 0263           @@clear MVO@  R3,     R4    ; (including background color,
482F 037C 0032              CMPI  #$32,   R4    ; border color, etc.)
4831 0226 0004              BLE   @@clear

4833 0259                   MVO@  R1,     R3    ; update X register of MOB #0
4834 0242 0008              MVO   R2,     $8    ; update Y register of MOB #0
4836 02BB 017E              MVII  #$017E, R3    ; update A register of MOB #0
4838 0243 0010              MVO   R3,     $10   ; (using a yellow "O")

483A 0298                   MVI@  R3,     R0    ; increment frame #
483B 0008                   INCR  R0
483C 0258                   MVO@  R0,     R3

483D 00AF                   JR    R5            ; return from ISR

                            ENDP

出力

output


10

HTML(Microsoft Edge / Internet Explorer)、81バイト

これらのネストされた<marquee>タグで1998年のふりをします。

<marquee behavior=alternate direction=down><marquee behavior=alternate width=99>O

Microsoft Edgeでテストしましたが、私が読んだIEでもマーキーをサポートする必要があります。決定的にChrome では動作しませ

設定direction=upすると2バイト節約されますが、キャンバスの上部からボールを​​開始するという規則に違反します。


残念ながら、チャレンジで要求されているように、ボールは斜めに移動しないため、これは無効な答えです。
エレンディアスターマン

Microsoft Edgeで試しましたか?Chromeはこのdirection属性をサポートしていないようです。
ジャックブラウンスタイン

申し訳ありませんが、それはEdgeで機能します。Chromeで機能しないことを確認でき、FirefoxとInternet Explorerで機能することを証明できます。4つのうち3つは悪くありません(この答えが有効になるためには1つだけが必要です)。+1
エルエンディアスターマン

1
+1 marquee、それはかなり創造的です!
メトニエム

私のためにChromeで働いていました。
ckjbgames

8

TI-BASIC、71 70

1->A
1->B
1->C
1->D
While 1
ClrHome
Output(B,A,0
A+C->A
B+D->B
If A<2 or A>15
~C->C
If B<2 or B>7
~D->D
End

まったく文字通りの翻訳ですが、小さくするコツがあっても驚かないでしょう。

画面は16x8で、インデックスが1なので、定数は異なります。

~ 否定記号を記述するSourceCoderの方法です。

gif of bouncing O

ハードウェア上ではより滑らかに見えます。


これは70バイトですか?それ以下に見えます。
12Me21

@ 12Me21あなたは何バイトを数えますか?これを計算機に保存すると80バイト、空のプログラムに10バイトを保存すると、カウントに一致します。
ハロルド

ああ、私は間違って数えたと思います。
12Me21

7

Befunge、209バイト

>10120130pppp>"l52?[J2["39*,,,,39*,,,,,,v
v+56/+55\%+55:+1g01*83-"6!"7\-"6!?"8-*86<
>00g1+:55+%\55+/"+!6"-48*,68>*#8+#6:#,_v$
v:+g03g01p02+-\g02*2!-*64\*2!:p00:+g02g<$
>10p:!2*\"O"-!2*30g\-+30p"2"::**>:#->#1_^

これは画面サイズが80x25であることを前提としていますが"O"、最後の行の(79)と最後*64から2番目の行の(24)を置き換えることで、範囲を簡単に調整できます(最後から2番目の行は右から左に実行されることに注意してください)。速度は"2"、最後の行の(50)を置き換えることでも調整できます。


7

Java、184 176バイト

class A{public static void main(String[]a)throws Exception{for(int X=1,Y=1,x=1,y=1;;System.out.print("\033["+X+";"+Y+"H"),Thread.sleep(50),X+=x=X%25<1?-x:x,Y+=y=Y%85<1?-y:y);}}

これは、ANSIエスケープシーケンスを使用してカーソルを再配置します。カーソルは、85 x 25端末ディスプレイの周りで跳ね返るオブジェクトです。という名前のファイルに保存しますA.java

非ゴルフ

class Terminal_Bouncing_Ball {
    public static void main(String[] args) throws InterruptedException {
        int X = 0, Y = 0, dx = 1, dy = 1;
        while (true) {
            System.out.print(String.format("\033[%d;%dH",X,Y));
            Thread.sleep(50);
            dx = (X < 1) ? 1 : (X > 71) ? -1 : dx;
            dy = (Y < 1) ? 1 : (Y > 237) ? -1 : dy;
            X += dx;
            Y += dy;
        }
    }
}

デモ

Example


これはコードゴルフなので、を削除する必要がありますThread.sleep(50)。そして、あなたのゴルフとゴルフなしのプログラムは一致しません。
ヤコブ

4

Clojure、398 380 375バイト

(ns g(:require[quil.core :as q]))(def w 1e3)(def h 1e3)(def f 100)(def b(atom{:x f :y f :n 1 :m 1}))(q/defsketch . :size[w h]:setup #(do(q/text-font(q/create-font""f))(q/fill 255 255 255)):draw #(let[s 9{x :x y :y n :n m :m}@b c(+ x(* n s))u(+ y(* m s))](q/background 0 0 0)(reset! b{:x c :y u :n(if(< 0 c(- w f))n(* -1 n)):m(if(<(+ 0 f)u h)m(* -1 m))})(q/text"O"(:x @b)(:y @b))))

フォント名をデフォルトの空の文字列に変更し、境界チェックをインライン化し、下部の境界の問題を修正することで-18バイト(GIFで確認できます)。実際に保存されたバイトを修正します。

-5バイト。より簡潔な構造化構文に変更し、ボールをピクセル単位で縮小します。

Quilを使用します。

私は機能モードに切り替えようとしましたが、多くの余分なコードが必要になり、最終的にはより高価になりました。

(ns bits.golf.ball-bounce
  (:require [quil.core :as q]))

(def width 1000)
(def height 1000)

(def font-size 100)

; Mutable state holding the properties of the ball. n and m are the directions on the x and y axis.
(def ball (atom {:x 300 :y 600 :n 1 :m 1}))

(q/defsketch b
  :size [width height] ; Window size

  :setup #(do
            (q/text-font (q/create-font "Arial" font-size)) ; Set the font
            (q/fill 255 255 255)) ; And the text color

  :draw
  #(let [speed 9
         ; Deconstruct the state
         {:keys [x y n m]} @ball
         next-x (+ x (* n speed))
         next-y (+ y (* m speed))

         ; I'm adding/subtracting the font-size so it stays in the window properly
         x-inbounds? (< 0 next-x (- width font-size))
         y-inbounds? (< (+ 0 font-size) next-y height)]

     ; Wipe the screen so the ball doesn't smear
     (q/background 0 0 0)

     ; Reset the state
     (reset! ball
             {:x next-x
              :y next-y
              :n (if x-inbounds? n (* -1 n))
              :m (if y-inbounds? m (* -1 m))})

     ; Draw the ball
     (q/text "O" (:x @ball) (:y @ball))))

Ball Bouncing GIF

(新しいバージョンは、GIFのように画面の下部に沿って早くバウンスしないことに注意してください。)


(+ 0 font-size)はそこにいることに気づきました。それは恥ずかしいです。次のバージョンで修正します。5バイトくらい節約できます。
発癌性

4

ラケット247バイト

(let*((w 500)(h(* w 0.6))(x 100)(y 0)(d 10)(e d)(G(λ(t)(set! x(+ x d))(when(or(> x w)(< x 0))
(set! d(* d -1)))(set! y(+ y e))(when(or(> y h)(< y 0))(set! e(* e -1)))
(underlay/xy(rectangle w h"solid""white")x y(circle 10"solid""black")))))(animate G))

ゴルフをしていない:

(require 2htdp/image
         2htdp/universe) 

(let* ((wd 500)            ; define variables and their initial values
       (ht 300)
       (x 100)
       (y 0)
       (dx 10)
       (dy 10)

       (imgfn              ; define function to draw one frame; called repeatedly by animate fn; 
        (λ (t)             ; t is number of ticks till now- sent by animate fn; ignored here;

                           ; update location (x and y values):
          (set! x (+ x dx))
          (when (or (> x wd) (< x 0))
            (set! dx (* dx -1)))             ; invert direction at edges
          (set! y (+ y dy))
          (when (or (> y ht) (< y 0))
            (set! dy (* dy -1)))             ; invert direction at edges

                           ; draw image: 
          (underlay/xy
           (rectangle wd ht "solid" "white") ; draw background
           x y                               ; go to location (x,y)
           (circle 10 "solid" "black")       ; draw ball
          ))))

  (animate imgfn))         ; animates the images created by imgfn (default rate 28 times/sec)

出力:

enter image description here


1
ラケットでラケットボールをプレイ!
ckjbgames

それは良いものです!
rnso

「ラケット」は「Scheme」プログラミング言語に由来します。Scheme(不正な計画)の後にRacket(詐欺または詐欺)があります!
rnso

@msoさらに良い!
ckjbgames

3

ゼリー、37バイト

“ñc‘Ọ24ḶŒḄṖ⁸ị⁷x⁸µ80ḶŒḄṖ⁸ị⁶x⁸‘œS.1
Ç1¿

この答えからいくつかの助けを借りてループとエスケープ文字を正しくするための。現在、80x24の画面で跳ね返っていますが、コードで簡単に変更できます。

各方向の座標は二つのリストの要素として表すことができる[0, 1,..., 24, 23,..., 1][0, 1,..., 80, 79,..., 1]、のは、それらを呼ぼうYX無限に繰り返されます。この無限の繰り返しは、Jellyで使用するモジュラーインデックスを使用してエミュレートできます。例:i番目の反復では、ボールは位置にあり(X[i%|X|], Y[i%|Y|]) = (iịY, iịX)ます。移動するボールは、iịY改行とiịXスペースを放出することで所定の位置に置かれるカーソルです。

デモ

https://i.gyazo.com/b8eac64097cb6d3a18185877c2f4c945.gif

説明

“ñc‘Ọ24ḶŒḄṖ⁸ị⁷x⁸µ80ḶŒḄṖ⁸ị⁶x⁸‘œS.1        Monadic helper link - argument i.
                                         Resets the terminal, prints Y[i] newlines,
                                         X[i] spaces and returns i + 1.
“ñc‘                                     Set the output to [27, 99]
    Ọ                                    Convert to characters and print (\x1bc)
                                          -> Cursor is at position (0,0)
     24Ḷ                                 Lowered range of 24. Yields [0,...,23].
        ŒḄ                               Bounce. Yields [0,...,23,22,...,0].
          Ṗ                              Pop. Yields [0,...,23,22,...,1] = Y.
           ⁸ị                            Modular index i (⁸) into Y. The current
                                         value is the Y coordinate, y.
              x                          Repeat y times
             ⁷                           the newline character ('\n').
               ⁸                         Output that (y times '\n') and continue
                                         with value i.
                                          -> Cursor is at position (0, y)
                µ                        Monadic chain separation.
                 80ḶŒḄṖ                  Same as above, but this time yielding X.
                       ⁸ị                Modular index i into X, yielding the
                                         value for x.
                          x              Repeat x times
                         ⁶               the whitespace character.
                           ⁸             Output that (x times ' ') and continue
                                         with value i.
                                         -> Cursor is at position (x, y), the
                                            final position.
                             œS.1        Wait 0.1 seconds.
                            ‘            Return i + 1.

Ç1¿                                      Main (niladic) link.
 1¿                                      While true.
Ç                                        Call the helper link. The first time
                                         there is no argument and i will be [],
                                         which is cast to 0 when used as integer
                                         (e.g. try ‘¶Ç). After that, the previous
                                         return value (i + 1) is used.

2

SmileBASIC、85 74バイト

SPSET.,9M=MAINCNT
SPOFS.,ASIN(SIN(M/5))*122+192,112+71*ASIN(SIN(M/3))EXEC.

ボールの位置は2つの三角波でモデル化することができ、SmileBASICでそれらを生成するための最短の方法はarcsine(sine(x))でした。(MODを使用するアルゴリズムは、SBがのMOD代わりに使用するため、より長くなりました%


2

CSS / HTML、200 + 7 = 207バイト

p{position:relative}a{position:absolute;animation:infinite linear alternate;animation-name:x,y;animation-duration:7.9s,2.3s}@keyframes x{from{left:0}to{left:79ch}}@keyframes y{from{top:0}to{top:24em}}
<p><a>O

このバージョンは、キャンバスのサイズを表示し、アニメーションをより奇抜な感じにします。


2

Dyalog APL、44バイト

{⎕SM∘←0,G←⍺+⍵⋄G∇⍵×1-2×⊃1 G∨.≥G⎕SD⊣⎕DL.1}⍨1 1

説明:

  • {... }⍨1 1:given =⍵= 1で指定された関数を呼び出します1
    • ⎕SM∘←0,G←⍺+⍵:に保存⍺+⍵G、ウィンドウの0その場所にを表示し⎕SMます。
    • ⎕DL.1:1/10秒待つ
    • ⊃1 G∨.≥G⎕SD次の場合チェックがGである⎕SMウィンドウ境界(1≥GまたはG≥⎕SD⎕SDあるS creen D imensions)
    • 1-2×:にマップ[1,0][¯1,1]、進行方向を反転します
    • ⍵×:現在の移動方向にそれを掛ける
    • G∇:再帰、G新しい場所()および⍵....新しい方向()にします。

これは、実行中に端末を連続的に開閉することになっていますか?端末が1/10秒ごとに閉じて再び開くため(少なくともWindowsの場合)、起動してからこれを停止することは非常に困難です。
レン

1
@wptreanor:修正済み
マリヌス

クールで素晴らしい作品です!
レン

2

PHP、112の 97 94 103 102バイト

for(;;usleep(1e5),$i%=624)echo($r=str_repeat)(A^K,99),$r(A^a,abs($i%78-39)),O,$r(A^K,abs($i++%48-24));

O右上隅から開始して、40x25グリッドで資本をバウンスします。
画面をクリアするために99個の改行を印刷します。

で実行し-nrます。

A^K= chr(10)=改行
A^a= chr(32)=スペース


1
こんにちは、タイタス​​です。for($d=$e=-1;;usleep(1e5))echo($r=str_repeat)(A^K,99),$r(A^a,$x+=$d*=$x%79?1:-1),O,$r(A^K,$y+=$e*=$y%24?1:-1);。モジュロは0およびNで偽であり、方向を逆にします。悲しいことに、$ dと$ eを-1に初期化する必要がありますが、それでもいくらか節約できます。$x%79<=>.5同じバイトでも機能します。
クリストフ

1
@Christophさん、おかえりなさい。奇妙なことに、あなたのものをコピーすると、110バイトではなく116バイトになりました。
タイタス

私たちは間違いなく良いチームです;)コピーに関する奇妙なこと理由はわかりません。
クリストフ

2

Simons´ BASIC(C64)、66 65バイト

@ShaunBebbersに感謝します。

Simons Basicにはモジュロ関数があるため、ここでは1行だけが必要です。
AfaIk、これには物理的なC64とSimonsのBASICモジュール
(またはmod機能を持つ他のBASIC拡張モジュール)が必要です。

0fori=0to623:print"{CLR}":poke1024+40*abs(mod(i,48)-24)+abs(mod(i,78)-39),81:next:goto

次の69文字を入力します。

0fOi=0TO623:?"{CLR}":pO1024+40*aB(mod(i,48)-24)+aB(mod(i,78)-39),81:nE:gO

{CLR}あるPETSCII画面をクリア147。Shift + CLR / HOMEを使用して入力します。

バイトカウント

:ディスクに保存する場合は、コマンドがトークン化されているため、65バイトを取る
fortopokeabsnextおよびgoto各バイト一つです。mod2バイトかかります。
これにより、59バイトのコードに加えて、ポインター用に4バイト、行番号用に2バイトが作成されます。

参照については、C64のマッピング$800(BASIC Program Text)の検索を参照してください。
(ビデオ画面のメモリ領域は、次の場所にあります$400ます。)

壊す

プログラムIは0から623にループします(= LCM 48および78マイナス1)。ループの中

  • 画面がクリアされます
  • I それぞれ39..0..38 24..0..23にマッピングされます
  • また、ブロブ(PETSCII 81)は、ビデオメモリ内の対応する位置に配置されます
    (元のプログラムと同様)。

ループが完了すると、プログラムは行0にジャンプして再起動されます。

C64 BASIC、77 76バイト

0fori=0to623:print"{CLR}"
1poke1024+40*abs(i-48*int(i/48)-24)+abs(i-78*int(i/78)-39),81:next:goto

残念ながら、2行が必要です。すべての省略形を使用しても83文字かかるため、C64行エディターを使用するには多すぎます。

0fOi=0to623:?"{CLR}":pO1024+40*aB(i-48*int(i/48)-24)+aB(i-78*int(i/78)-39),81:nE:gO

(16進エディターを使用して長い行を作成できます。これにより、73バイトになります。)


1
コモドールコマンドの区切りはあり:ませんし、;
ショーンBebbers

1
また、ライン0から開始する場合、BASIC 2gotogotogoto 0
Shaun Bebbers

C64 BASICリストでさらにコマンドを取得したい場合は、128モードでC128に入力し、ディスクに保存してC64モードにロードし直します。C128にはデフォルトで160文字の制限があるため、 Commodoreキーワードの略語を使用します。
ショーンビーバーズ

@ShaunBebbers知って嬉しい。お久しぶりですね。また、マシンコードでこれを実装したいと考えていました... どのレジスタをバックアップする必要があるのか​​わかりません。完全なカーネルリストはオンラインです。さらに時間をかけて掘り下げることはできません。これを完了ますか?
タイタス

私はMCバージョンを作成するつもりでしたが、自分自身のチャレンジにそれを提出するのは私にとってもやりがいがあると思います。最速の方法は、バイトを画面に直接書き込む$0400こと$07e7です。またはスプライトを使用します。Kernal with $ffd2(output accumulator)を使用すると、カーソルのX位置とY位置を簡単に設定できます(そのための呼び出しは覚えていません)が、強制的に最後の文字位置を回避する必要がある場合があります改行。
ショーンビーバーズ

1

Python 2、176 168バイト

これは、80x24の端末サイズを想定しています。間違いなく最適ではありませんが、私はゴルフを始めたばかりです。

import time;x=y=d=e=1
while 1:
 m=[[' 'for i in' '*80]for j in' '*24];x+=d;y+=e;m[y][x]='O';time.sleep(.1)
 if x%79<1:d=-d
 if y%23<1:e=-e 
 for r in m:print''.join(r)

R. Kap、x <1またはx> 79の代わりにx%79 <1を提案し、yについても同様に感謝します。


あなたは置き換えることによって、数バイトを保存することができますx<1or x>78x%79<0してy<1or y>22y%23<1
R.カップ

1

Rebol / View、284 266バイト

rebol[]p: 3x9 d:[3 3]view layout[b: box blue 99x99 effect[draw[circle p 2]]rate :0.01 feel[engage: func[f a e][if a = 'time[case/all[p/x < 2[d/1: abs d/1]p/y < 2[d/2: abs d/2]p/x > 98[d/1: negate d/1]p/y > 98[d/2: negate d/2]]p/x: p/x + d/1 p/y: p/y + d/2 show b]]]]

ゴルフをしていない:

rebol []

p: 3x9     ;; starting position
d: [3 3]   ;; direction

view layout [
    b: box blue 99x99 effect [
        draw [
            circle p 2
        ]
    ]

    rate :0.01 feel [
        engage: func [f a e] [
            if a = 'time [
                case/all [
                    p/x < 2  [d/1: abs d/1]
                    p/y < 2  [d/2: abs d/2]
                    p/x > 98 [d/1: negate d/1]
                    p/y > 98 [d/2: negate d/2]
                ]
                p/x: p/x + d/1
                p/y: p/y + d/2
                show b
            ]
        ]
    ]
]

1

C 294バイト

#include<graphics.h> f(){int d=0;g,x,y,a=0,b=0;initgraph(&d,&g,NULL);x=30;y=30;while(1){x+=6;y+=7;if(y<60)b=0;if(x<60)a=0;if((y>getmaxy()-40)) b=!b;if((x>getmaxx()-40))a=!a;if(b){y-=18;x+=3;}if(a){x-=15;y+=2;}usleep(10000);setcolor(4);cleardevice();circle(x, y,30);floodfill(x,y,4);delay(45);}}

ゴルフされていないバージョン:

#include<graphics.h>
void f()
{
 int d=DETECT,g,x,y,r=30,a=0,b=0;
 initgraph(&d,&g,NULL);
 x=30;
 y=30;

 while(1)
 {
   x+=6;
   y+=7;

   if(y<60)
     b=0;
   if(x<60)
     a=0;     

   if((y>getmaxy()-40))
        b=!b;

   if((x>getmaxx()-40))
        a=!a;

    if(b)
    {       
        y-=18;
        x+=3;
    }

    if(a)
    {       
       x-=15;
       y+=2;               
    } 
    usleep(10000);
    setcolor(RED);
    cleardevice();
    circle(x,y,r);
    floodfill(x,y,RED);
    delay(45);

  }   

}

説明

  • そのため、これを開始するためgraphics.hに、/usr/includeディレクトリにアクセスする必要がありました。したがって、私は検索し、これは私が見つけたものです。Linux用のSDLを使用したTurboC Graphicsの実装です。OpenGLを使用することもできます。Windowsでは、MacOSについては不明ですが、既にインストールされていると思います。
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);システムを初期化し、グラフィックモードにします。この場合、グラフィックドライバーは自動的に検出されます。詳細については、このリンクを参照してください。
  • x そして yボールの位置を決定する座標です。
  • aそしてbフラグは、あるa場合にゼロに設定されxた値が60以下に低下するとbゼロときに設定されていますy
  • フラグは次の場合に切り替えxられますy、ウィンドウの境界値を超えると、座標はそれに応じて調整されます。
  • usleepCPUにストレスがかからないようにaを配置しました。
  • 通常はclosegraph()、ウィンドウを閉じるために呼び出しを使用する必要があります。しかし、ここにはありません。

リンカーフラグを使用してコンパイルする必要があります -lgraph

実際のハードウェアでよりスムーズに実行されます。:)

Bouncing Red Ball


このプログラムを実行するにはインポートステートメントが必要ですか?
クリチキシリトス

@KritixiLithosはい。更新しました!を含める必要がありますgraphics.h。この回答askubuntu.com/questions/525051/…は役に立ちました。
アベルトム

1

MATL、42バイト

1thXH_XI`Xx8E70hZ"79HZ}&(DH4M\1>EqI*XIH+XH

これは、70×16のスクリーンとキャラクターを使用しOます。数回のバウンスを待つと、ボールがコーナーに当たるのがわかります。

MATL Onlineでお試しください!

画面サイズはコードで簡単に変更できます。関連する部分はで8E70、これをプッシュ8、ダブル、プッシュし70ます。たとえば、80×25の画面の場合は5W80、を押して5、2乗し、押します80(またはで置き換えますが25 80、もう1バイト必要です)。

また、tDコードの最後に追加すると、現在の位置がリアルタイムで表示されます(垂直、次に水平1 1が左上)。例として、80×18画面の場合、

1thXH_XI`Xx9E80hZ"79HZ}&(DH4M\1>EqI*XIH+XHtD

それも試してみてください!

説明

これは無限ループを使用します。位置はH1×2ベクトルIとしてクリップボードに保持され、方向はエントリ1またはを持つ1×2ベクトルとしてクリップボードに保持されます-1

各反復は画面をクリアし、スペースのマトリックスを定義Oし、関連する位置に書き込み、表示します。次に、位置とディレクティオを更新する必要があります。

位置は- 1ベースであるため、画面の端は1最大画面サイズになります。位置モジュロ画面サイズが与えそうである場合0、または1我々がそれぞれ縦または横エッジに到達したことを意味第一または第二の成分のいずれかで、方向ベクトルの成分がネゲートされます。その後、新しい方向を現在の位置に追加して、新しい位置を取得します。


1

ZX Spectrumのリストは次のとおりです。

  10 FOR n=0 to 7
  20 READ a: POKE USR "a"+n, a
  30 NEXT n
  40 DATA 60,126,243,251,255,255,126,60
  50 LET x=10:LET y=10:LET vx=1: LET vy=1
  60 PRINT AT y,x;"\a"
  70 IF x<1 OR x>30 THEN LET vx=-vx
  80 IF y<1 OR x>20 THEN LET vy=-vy
  90 LET x=x+vx: LET y=y+vy
 100 PRINT AT y-vy,x-vx;" ": GO TO 60

素敵な最初のエントリDrlB-バイトカウントを含めてください。これは16Kマシンを含むSpeccyで動作すると思いますか?
ショーンビバーズ

こんにちは、これは201バイトです。最初の4行を省略できますが、バウンシングする「a」文字が表示されますが、64バイト節約できます。最適化を試みます。これはまったく空想ではなく、どのスペクトルモデルでも動作します:)
DrIB

わかりました。ボールのグラフィックを落とさずにラインを少し凝縮することで、185に削減することができました。ただし、読みやすさは少し劣りますが、高速です。
DrIB

1

C + curses、190バイト

#include<curses.h>
w;h;x;y;d;main(e){initscr();curs_set(0);getmaxyx(stdscr,h,w);for(d=e;;usleep(20000),mvaddch(y,x,32)){mvaddch(y+=d,x+=e,48);if(!y||y>h-2)d=-d;if(!x||x>w-2)e=-e;refresh();}}

説明:

#include<curses.h>
w;h;x;y;d;
main(e)
{
    initscr();
    curs_set(0);
    getmaxyx(stdscr,h,w);

    // initialize distances to 1 (e is 1 when called without arguments)
    // wait for 1/5 second, then write space character at current pos
    for(d=e;;usleep(20000),mvaddch(y,x,32))
    {
        // advance current pos and write ball character (`0`)
        mvaddch(y+=d,x+=e,48);

        // check and change direction:
        if(!y||y>h-2)d=-d;
        if(!x||x>w-2)e=-e;

        // trigger output to screen:
        refresh();
    }
}

1

ルアLÖVE2D)、130バイト

x,y,a,b=0,0,1,1
function love.draw()a=(x<0 or x>800)and-a or a
b=(y<0 or y>600)and-b or b
x=x+a
y=y+b
love.graphics.points(x,y)end

Luaはゴルフのコーディングに関しては最高の言語ではありませんが、ここに行きます!言及する価値があるいくつかのポイント:

  • デフォルトのキャンバスサイズは800 x 600です。設定ファイルで変更できますが、サイズの制限は見当たらないため、そのままにしました。

  • love.draw()LÖVEの描画関数であり、事前に定義された名前を持っています。オルタナティブ恋使用できる機能だろうlove.update(dt)love.run()-バイトで、最初ビーイング長く、後者は短いこと、はい、しかし、内蔵の無限ループなし。したがって、draw()ここでの最善策であるようです。

  • 上記のバージョンはlove.graphics.pointsボールを描くために使用します。短くなりますが、許可されているかはわかりません。実行方法のGIFは次のとおりです。

Animated screenshot - point

ご覧のように(またはできないかもしれません)、画面上を移動するピクセルは1つです。それはバイトを節約しますが、それは最も満足のいく結果ではありません。

だから私は代替の131バイトのソリューションを作りました:

x,y,a,b=0,0,1,1
function love.draw()a=(x<0 or x>795)and-a or a
b=(y<0 or y>595)and-b or b
x=x+a
y=y+b
love.graphics.print(0,x,y)end

これはlove.graphics.print、テキストを印刷する-とa 0をボールとして使用し、より見やすく魅力的なものにします。

Animated screenshot - zero


1

CHIP-8、36の 34 28バイト

FF29 'LDF I,vF //load digit sprite for the value of vF (should be 0)

4000 'SNE v0,0 //if x is 0...
6201 'LD v2,1 //set x velocity to 1
403C 'SNE v0,3C //if x is 3C...
62FF 'LD v2,FF //set x velocity to -1
4100 'SNE v1,0 //if y is 0...
6301 'LD v3,1 //set y velocity to 1
411B 'SNE v1,1B //if y is 1B...
63FF 'LD v3,FF //set y velocity to -1

D015 'DRW v0,v1,5 //draw sprite
D015 'DRW v0,v1,5 //draw sprite again to clear it.
8024 'ADD v0,v2 //add x velocity to x
8134 'ADD v1,v3 //add y velocity to y

1202 'JMP 202 //jump to second instruction

ここには派手なトリックはありません...

スプライトを正しく描画するインタープリターが必要です(フレームごとに1つのスプライトしか描画できません。これにより、プログラムが遅くなり、表示できなくなります)。

低品質のビデオ


0

ZX Spectrum BASIC-179バイト

ここでは少し凝縮されています。ボールグラフィックスを含む179バイト

  10 LET a=10: LET b=10: LET c=1: LET d=-1: FOR e=0 TO 7: READ f: POKE USR "a"+e, f: NEXT e
  20 DATA 60, 126,243,251,255,255,126,60
  30 PRINT AT b,a;"\a"
  40 IF a<1 OR a>30 THEN LET c=-c
  50 IF b<1 OR b>20 THEN LET d=-d
  60 LET a=a+c: LET b=b+d: PRINT AT b-d, a-c;" ": GO TO 30

文字を使用することによっても、マークアップの答えに使用をご覧くださいoまたはOシンボリックリストのいくつかのバイトを保存することができるかもしれ。あなたが改善ソリューションを持っているときにも、編集前の回答をすることができます、というよりも同じ質問を再度答える
ショーンBebbers
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.