Gaya bola memantul 8-bit di sekitar kanvas


20

Terinspirasi oleh daftar ini dari Panduan Pengguna 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

Buat program serupa dalam bahasa / platform yang Anda pilih untuk memantulkan objek yang mirip bola di sekitar terminal, layar, kanvas, atau area tampilan visual lainnya.

Anda tidak harus meniru grafik PETSCII C64 dengan tepat, sederhana Oatau oakan dilakukan, Anda juga tidak harus menggunakan GOTOperintah jika masih ada dalam bahasa Anda. Selama bola Anda mulai di atas kanvas Anda dan bergerak secara diagonal hingga menyentuh batas kanvas, dan kemudian memantul sesuai itu, sebagai berikut:

  • Bepergian ke bawah dan ke kanan dan menyentuh bagian bawah area layar, memantul ke atas dan terus ke kanan;
  • Bepergian ke atas dan ke kanan dan mengenai batas paling kanan, dan memantul ke kiri dan ke atas;
  • Bepergian ke kiri dan ke atas dan mengenai bagian atas, memantul ke kiri dan ke bawah;
  • Bepergian ke kiri dan ke bawah dan mencapai batas paling kiri, memantul ke kanan dan ke bawah;
  • Hit sudut mana pun dan membalikkan arah;

Maka kita semua baik-baik saja.

Anda tidak harus memindahkan bola 8-piksel sekaligus, seperti yang terjadi dalam daftar BASIC di C64; Anda dapat memindahkan satu blok karakter atau satu piksel pada satu waktu, mana yang menurut Anda paling tepat.

Untuk melihat listing BASIC ini berfungsi, Anda dapat mengetikkannya dengan emulator Commodore 64 online ini asalkan browser Anda mendukung Flash.


2
Kanvas JavaScript. Duh.
Matthew Roh

Saya tidak yakin apa yang Anda sebut layar saat ini. Anda dulu hanya memiliki layar dan area perbatasan dilihat melalui televisi atau VDU Anda ... dan sekarang Anda punya terminal, jendela, kanvas, stdout dll ... itu semua sangat membingungkan bagi saya.
Shaun Bebbers

Akan lebih baik jika kita memiliki nilai ukuran piksel yang konstan.
Matthew Roh

4
Bisakah kita menganggap ukuran layar 1x1 dan mencetak selamanya?
Matius Roh

1
kemungkinan duplikat ASCII Ball in Box Animation
Titus

Jawaban:


3

6502 kode mesin (C64), 90 89 91 byte

+2 byte karena memerlukan alamat pemuatan (bukan PIC karena modifikasi diri)

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

Demo online

Pemakaian: sys49152

Saya berusaha keras untuk mengurangi ukuran (mis. BUKAN menggunakan IRQ untuk pengaturan waktu tetapi loop kosong bodoh sebagai gantinya), masih mustahil untuk mencapai tingkat C64 BASIC golf Titus ' : o oh, well. Tapi kelihatannya kurang berkedip;)

Penjelasan: (wakil pembongkaran)

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

Hanya untuk bersenang-senang, inilah varian yang lebih profesional menggunakan sprite untuk bola dan mem-flash perbatasan ketika dipukul dalam 385 byte (berisi data sprite yang digunakan di tempat ):

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 

Demo online - | - Jelajahi sumber assembler ca65

Mulai dan hentikan bola memantul dengan sys49152.

  • Ini membiarkan C64 BASIC berjalan, itu dilakukan dengan memindahkan ruang alamat VIC-II ke atas $C000, yang mengharuskan menyalin isi layar dan set karakter (font).
  • Ini menghubungkan ke sistem IRQ dan untuk menghindari flicker, mengubah sumber IRQ ini ke chip grafis VIC-II, sehingga pembaruan selalu dilakukan antara frame.
  • Gangguan:
    1. RUN/STOP + RESTORE rusak, jangan coba-coba.
    2. Dengan VIC-II sebagai sumber IRQ, kursor berkedip sedikit lebih lambat dan TI$akan tertinggal juga.
    3. ketika berhenti ketika perbatasan di-flash (sangat tidak mungkin tetapi mungkin), tetap putih - Anda harus mengembalikannya secara manual.

1
Itu tidak sepenuhnya independen, bukan? Saya melihat dua LDA absolut dan dua STA. Meskipun demikian, kerja bagus!
Titus

Sialan kau benar: o Aku lupa modifikasi diri! Saya akan memperbarui segera setelah saya menggunakan PC.
Felix Palmen

1
@Titus memperbaiki ... dan hanya untuk bersenang-senang, menambahkan varian "lebih baik" :)
Felix Palmen

Sudahkah Anda mempertimbangkan mengemas sprite? (Hmm ... menggunakan charset ROM?) Dan baik aku lebih memilih inc $d020lebih jsr flash;) hitshimselfwithalargetrout IT'S mengagumkan!
Titus

1
@Itus akan menghemat 2 byte, ya. Adapun alamat muat, itu bagian dari .prgfile yang valid dan dari pertanyaan meta saya di sini saya ambil saya harus memasukkannya ... mungkin bisa meninggalkannya jika kode itu posisi independen.
Felix Palmen

14

Utilitas Bash + Unix, 125 117 byte

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
}

Animasi contoh dijalankan:

Animasi contoh dijalankan


6
Itu mencapai sudut yang tepat! : O
mbomb007

11

Perakitan CP-1610 , 6764 62 DECLEs = 78 byte

Kode ini dimaksudkan untuk dijalankan pada Intellivision . Ini menggunakan salah satu sprite perangkat kerasnya, yang dikenal sebagai MOB (untuk Mobile Object).

Sebuah opcode CP-1610 dikodekan dengan nilai 10-bit, yang dikenal sebagai 'DECLE'. Program ini panjangnya 62 DECLE, mulai dari $ 4800 dan berakhir pada $ 483D.

Sumber dump + heksadesimal

                            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

Keluaran

keluaran


10

HTML (Microsoft Edge / Internet Explorer), 81 byte

Berpura-puralah tahun 1998 dengan <marquee>tag bersarang ini :

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

Diuji di Microsoft Edge, meskipun dari apa yang saya baca IE juga harus tetap mendukung marque. Jelas tidak bekerja di Chrome.

Pengaturan direction=upakan menghemat 2 byte, tetapi melanggar aturan bahwa bola harus dimulai di bagian atas kanvas.


Sayangnya, ini adalah jawaban yang tidak valid karena bola tidak bergerak secara diagonal, seperti yang dipersyaratkan oleh tantangan.
El'endia Starman

Apakah Anda mencobanya di Microsoft Edge? Chrome sepertinya tidak mendukung directionatribut.
Jack Brounstein

Huh, permintaan maaf saya - ini berhasil di Edge. Saya dapat mengonfirmasi bahwa itu tidak berfungsi di Chrome, dan saya dapat membuktikan bahwa itu berfungsi di Firefox dan Internet Explorer. Tiga dari empat tidak buruk (dan Anda hanya perlu satu agar jawaban ini valid). +1
El'endia Starman

1
+1 untuk marquee, itu cukup kreatif!
Metoniem

Bekerja di Chrome untuk saya.
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

Terjemahan literal, saya tidak akan terkejut jika ada trik untuk membuatnya lebih kecil.

Layar 16x8 dan 1-diindeks sehingga konstanta berbeda.

~ adalah cara SourceCoder untuk menulis simbol negasi.

gif memantul O

Itu terlihat lebih halus pada perangkat keras.


Apakah Anda yakin ini 70 byte? Sepertinya kurang dari itu.
12Me21

@ 12Me21 berapa byte yang Anda hitung? Saya mendapatkan 80 byte jika saya menyimpannya di kalkulator dan 10 byte untuk program kosong yang sesuai dengan hitungan saya.
Harold

Oh, kurasa aku salah menghitung.
12Me21

7

Befunge, 209 byte

>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_^

Ini mengasumsikan ukuran layar 80x25, tetapi Anda dapat dengan mudah mengubah rentang dengan mengganti "O" (79) pada baris terakhir dan *64(24) pada baris terakhir kedua (perhatikan bahwa baris terakhir kedua dijalankan dari kanan ke kiri). Kecepatan juga dapat disesuaikan dengan mengganti "2"(50) pada baris terakhir.


7

Jawa, 184 176 byte

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);}}

Ini memanfaatkan Sequence Escape ANSI untuk memindahkan kursor, yang merupakan objek yang memantul di sekitar 85 x 25tampilan terminal. Simpan dalam file bernama A.java.

Tidak disatukan

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;
        }
    }
}

Demo

Contoh


Ini kode golf, jadi Anda ingin menghapus Thread.sleep(50). Dan program golf dan ungolfed Anda tidak cocok.
Jakob

4

Clojure, 398 380 375 byte

(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 byte dengan mengubah nama font menjadi string kosong ke default, inlining pemeriksaan batas, dan memperbaiki masalah batas bawah (yang dapat Anda lihat di GIF). Memperbaiki byte yang sebenarnya disimpan.

-5 byte dengan mengubah sintaksis penataan yang lebih ringkas dan menyusutkan bola dengan piksel.

Menggunakan Quil .

Saya mencoba beralih ke mode fungsional, tetapi membutuhkan banyak kode tambahan dan akhirnya menjadi lebih mahal.

(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

(Catatan, versi baru tidak terpental di awal bagian bawah layar seperti di GIF.)


Saya baru sadar saya ada (+ 0 font-size)di sana. Itu memalukan. Saya akan memperbaikinya di versi berikutnya. Haruskah saya menghemat 5 byte.
Carcigenicate

4

Racket 247 byte

(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))

Tidak Terkumpul:

(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)

Keluaran:

masukkan deskripsi gambar di sini


1
Bermain raket dengan Racket!
ckjbgames

Itu bagus!
rnso

"Racket" berasal dari bahasa pemrograman "Scheme": setelah Scheme (rencana licik) ada Racket (scam atau penipuan)!
rnso

@Mso Bahkan lebih baik!
ckjbgames

3

Jelly, 37 byte

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

Dengan bantuan dari jawaban ini untuk mendapatkan loop dan karakter melarikan diri dengan benar. Saat ini memantul di sekitar layar 80x24, tetapi itu dapat dengan mudah dimodifikasi dalam kode.

Koordinat di setiap arah dapat direpresentasikan sebagai elemen dari dua daftar [0, 1,..., 24, 23,..., 1]dan [0, 1,..., 80, 79,..., 1], sebut saja Ydan X, yang diulang tanpa batas. Pengulangan tanpa batas ini dapat ditiru menggunakan pengindeksan modular - menggunakan di Jelly. Contoh: dalam iiterasi bola berada di posisi (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). Bola yang bergerak hanyalah kursor yang diletakkan pada posisinya dengan memancarkan iịYgaris dan iịXspasi baru.

Demo

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

Penjelasan

“ñ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 byte

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

Posisi bola dapat dimodelkan dengan 2 gelombang segitiga, dan cara terpendek yang dapat saya temukan untuk memproduksinya di SmileBASIC adalah arcsine (sinus (x)). (Algoritma menggunakan MOD lebih lama sejak SB menggunakan MODbukan %)


2

CSS / HTML, 200 + 7 = 207 byte

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

Versi ini menunjukkan kepada Anda ukuran kanvas dan juga memberikan animasi nuansa yang lebih teranimasi:


2

Dyalog APL, 44 byte

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

Penjelasan:

  • {... }⍨1 1: panggil fungsi yang diberikan dengan ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: simpan ⍺+⍵di G, tampilkan a0 di lokasi itu di ⎕SMjendela.
    • ⎕DL.1: tunggu 1/10 detik
    • ⊃1 G∨.≥G⎕SD: periksa apakah Gada di ⎕SMbatas jendela ( 1≥Gatau G≥⎕SD, ⎕SDapakah s creen d imensions)
    • 1-2×: peta [1,0]ke[¯1,1] , untuk membalikkan arah perjalanan
    • ⍵×: kalikan arah perjalanan saat ini dengan itu
    • G∇: rekursi, misalkan Gmenjadi lokasi baru ( ) dan ⍵....menjadi arah baru ( ).

Apakah ini seharusnya membuka dan menutup terminal secara terus-menerus saat beroperasi? Sangat sulit untuk menghentikan ini dari berjalan setelah dimulai, karena terminal ditutup dan dibuka kembali setiap sepersepuluh detik (setidaknya pada Windows).
ren

1
@wptreanor: diperbaiki
marinus

keren, kerja bagus!
ren

2

PHP, 112 97 94 103 102 byte

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));

memantulkan modal Opada kisi 40x25, mulai dari sudut kanan atas;
mencetak 99 baris baru untuk menghapus layar.

Jalankan dengan -nr .

A^K= chr(10)= baris baru
A^a= chr(32)= spasi


1
Hai Titus, ini aku lagi. 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);. Modulo salah pada 0 dan N dan membalikkan arah. Sayangnya kita harus init $ d dan $ e ke -1 tetapi masih mendapatkan penghematan. $x%79<=>.5juga bekerja untuk byte yang sama.
Christoph

1
Hai @Christoph selamat datang kembali. Aneh: ketika saya menyalin barang-barang Anda memiliki 116 byte, bukan 110. Tapi itu mengilhami saya untuk sesuatu yang jauh lebih pendek.
Titus

Kami benar-benar tim yang bagus;) Hal aneh dalam penyalinan saya tidak tahu kenapa.
Christoph

2

BASIC Simons (C64), 66 65 byte

Satu byte disimpan, terima kasih @ShaunBebbers.

Saya hanya perlu satu baris di sini, karena Simons 'Basic memiliki fungsi modulo.
Namun, ini membutuhkan C64 fisik dan modul BASIC Simons
(atau ekstensi BASIC lainnya yang memiliki modfungsi).

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

Ketikkan 69 karakter ini:

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

{CLR} aku s PETSCII 147, yang membersihkan layar. Gunakan Shift + CLR / HOME untuk mengetiknya.

bytecount

Ketika disimpan ke disk, dibutuhkan 65 byte, karena perintahnya tokenized:
for , to, poke, abs, nextdan gotoadalah salah satu byte setiap; modmembutuhkan dua byte.
Itu membuat 59 byte kode ditambah 4 byte untuk pointer dan 2 byte untuk nomor baris.

Untuk referensi, lihat Memetakan C64 dan mencari $800(BASIC Program Text).
(Anda dapat menemukan Area Memori Layar Video di$400 .)

kerusakan

Program loop Idari 0 hingga 623 (= LCM 48 dan 78 minus 1). Dalam lingkaran

  • layar dihapus
  • I dipetakan menjadi 39..0..38 masing-masing 24..0..23
  • dan gumpalan (PETSCII 81) diletakkan pada posisi yang sesuai dalam memori video
    (seperti program aslinya).

Ketika loop selesai, program dimulai kembali dengan melompat ke baris 0.

C64 BASIC, 77 76 byte

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

Sayangnya saya perlu dua baris, karena walaupun dengan semua singkatan yang mungkin akan membutuhkan 83 karakter - terlalu banyak untuk menggunakan editor baris C64:

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

(Sebuah hex editor dapat digunakan untuk membuat garis yang lebih panjang - yang akan membuatnya menjadi 73 byte.)


1
Pemisah perintah Commodore adalah :dan tidak;
Shaun Bebbers

1
Juga jika Anda mulai dari baris nol, Anda cukup menggunakan gotodalam versi dua-liner Anda, karena gototanpa angka mengasumsikan goto 0pada BASIC 2
Shaun Bebbers

Jika Anda ingin mendapatkan lebih banyak perintah pada daftar BASIC C64 Anda, masukkan ke dalam C128 dalam mode 128, simpan ke disk dan muat kembali ke mode C64, C128 memiliki batas karakter 160 secara default sehingga penghalang ini dapat dipecah oleh menggunakan singkatan kata kunci Commodore.
Shaun Bebbers

@ShaunBebbers senang mengetahui. Sudah lama. Saya juga ingin menerapkan ini dalam kode mesin ... mencoba rekap pada rutinitas kernel; tidak yakin kapan saya harus membuat cadangan register apa; daftar kernel lengkap sedang online ; Saya tidak bisa meluangkan waktu untuk menggali lebih jauh. Apakah Anda ingin menyelesaikan ini ?
Titus

Saya akan membuat versi MC, meskipun saya pikir mengirimkannya ke tantangan saya sendiri akan terlalu memanjakan bahkan untuk saya. Cara tercepat adalah menulis byte langsung ke layar dari $0400ke $07e7; atau gunakan sprite. Menggunakan Kernal dengan $ffd2(keluaran akumulator) akan bekerja karena Anda dapat mengatur posisi X dan Y pada kursor dengan cukup mudah (saya tidak ingat panggilan untuk itu), tetapi Anda mungkin harus menghindari posisi karakter terakhir jika itu memaksa umpan baris.
Shaun Bebbers

1

Python 2, 176 168 Bytes

Ini mengasumsikan ukuran terminal 80x24. Jelas tidak optimal tapi saya baru bermain golf jadi ya.

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)

Terima kasih kepada R. Kap untuk menyarankan x% 79 <1, bukan x <1 atau x> 79 dan juga untuk y.


Anda dapat menyimpan beberapa byte dengan mengganti x<1or x>78dengan x%79<0dan y<1or y>22dengan y%23<1.
R. Kap

1

Rebol / Lihat, 284 266 byte

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]]]]

Tidak Terkumpul:

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 byte

#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);}}

Versi tidak disatukan:

#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);

  }   

}

Penjelasan

  • Jadi untuk memulai dengan ini, saya harus masuk ke direktori graphics.hsaya /usr/include. Karena itu, saya mencari dan ini yang saya temukan. Ini adalah implementasi TurboC Graphics menggunakan SDL untuk Linux. Anda juga bisa menggunakan OpenGL. Di windows, saya kira itu sudah diinstal, tidak yakin tentang MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);menginisialisasi sistem dan menempatkannya dalam mode grafis, dalam hal ini driver grafis terdeteksi secara otomatis. Silakan merujuk ke tautan ini untuk lebih jelasnya.
  • x dan y merupakan koordinat yang menentukan posisi bola.
  • adan badalah flag, adiatur ke nol ketika xnilainya turun di bawah 60 dan bdiatur ke nol saaty turun di bawah 60.
  • Bendera-bendera di-toggle kapan xdany melebihi nilai batas jendela, dan koordinat disesuaikan.
  • Saya menempatkan usleepagar CPU saya tidak stres.
  • Seseorang biasanya harus menggunakan closegraph()panggilan, untuk menutup jendela. Tapi itu hilang di sini.

Harus dikompilasi dengan bendera tautan -lgraph

Ini berjalan lebih lancar pada perangkat keras nyata. :)

Bola Merah Memantul


Apakah pernyataan impor diperlukan untuk menjalankan program ini?
Kritixi Lithos

@KritixiLithos Ya pak; Diperbarui! Anda harus memasukkan graphics.h. Jawaban ini askubuntu.com/questions/525051/… bermanfaat.
Abel Tom

1

MATL , 42 byte

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

Ini menggunakan layar dan karakter 70x16 O. Jika Anda menunggu beberapa bouncing, Anda akan melihat bola memukul sudut.

Coba di MATL Online!

Ukuran layar dapat dengan mudah dimodifikasi dalam kode. Bagian yang relevan adalah 8E70, yang mendorong 8, menggandakannya, dan mendorong 70. Misalnya, untuk layar 80 × 25 ganti dengan 5W80, yang mendorong 5, kuadratkan, dan mendorong 80(atau mengganti dengan 25 80, tetapi itu membutuhkan satu byte lagi).

Juga, menambahkan tDpada akhir kode menunjukkan posisi saat ini dalam waktu nyata (vertikal, kemudian horisontal, 1 1kiri atas). Sebagai contoh, untuk 80×18layar,

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

Coba juga!

Penjelasan

Ini menggunakan infinite loop. Posisi disimpan di clipboard Hsebagai vektor 1 × 2, dan arah disimpan di clipboard Isebagai vektor 1 × 2 dengan entri 1atau -1.

Setiap iterasi membersihkan layar, mendefinisikan matriks ruang, menulis Opada posisi yang relevan, dan menampilkannya. Maka posisi dan pengarahan perlu diperbarui.

Posisi 1berbasis, dan dengan demikian tepi layar adalah 1dan ukuran layar maksimum. Jadi jika posisi ukuran layar modulo memberikan 0atau 1dalam komponen pertama atau kedua, yang berarti kita telah mencapai tepi vertikal atau horizontal masing-masing, komponen vektor arah dinegasikan. Setelah itu, arah baru ditambahkan ke posisi saat ini untuk mendapatkan posisi baru.


1

Berikut daftar 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

Entri pertama yang bagus DrlB - bisa tolong sertakan hitungan byte. Saya menganggap ini akan bekerja pada Speccy termasuk mesin 16K?
Shaun Bebbers

Hai, ini adalah 201 byte, Anda bisa menghilangkan 4 baris pertama tetapi kemudian Anda hanya mendapatkan karakter "a" yang memantul tetapi menghemat 64 byte. Saya akan mencoba mengoptimalkan. Ini tidak ada yang mewah sama sekali dan akan bekerja pada model Spectrum apa pun :)
DrIB

Ok saya sudah berhasil memotongnya menjadi 185 dengan mengkondensasi garis sedikit tanpa menjatuhkan bola grafis. Ini sedikit kurang mudah dibaca tetapi lebih cepat.
DrIB

1

Kutukan C +, 190 byte

#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();}}

Penjelasan:

#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

Lua ( LÖVE 2D ), 130 byte

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 bukan bahasa terbaik dalam hal kode golf, tapi ini dia! Beberapa poin yang layak disebutkan:

  • Ukuran kanvas default adalah 800 x 600. Dapat diubah dalam file konfigurasi, tetapi saya tidak melihat batasan ukuran, jadi saya membiarkannya apa adanya.

  • love.draw()adalah fungsi menggambar LÖVE dan memiliki nama yang telah ditentukan. Fungsi LÖVE alternatif yang dapat digunakan adalah love.update(dt)dan love.run()- yang pertama lebih panjang, dalam byte, dan yang terakhir lebih pendek, ya, tetapi tanpa loop tak terbatas bawaan. Jadi, draw()tampaknya menjadi taruhan terbaik kami di sini.

  • Versi di atas digunakan love.graphics.pointsuntuk menggambar bola. Meski lebih pendek, saya tidak yakin itu diizinkan. Berikut ini adalah GIF cara kerjanya:

Animated screenshot - point

Seperti yang Anda lihat (atau mungkin tidak bisa), ada satu piksel bergerak di layar. Sementara itu menghemat byte, itu bukan hasil yang paling memuaskan.

Jadi saya telah membuat solusi alternatif 131 byte :

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

Yang ini menggunakan love.graphics.print- yang mencetak teks - dan 0sebagai bola, membuatnya jauh lebih terlihat dan menarik.

Animated screenshot - zero


1

CHIP-8, 36 34 28 byte

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

Tidak ada trik mewah di sini ...

Membutuhkan juru bahasa yang menggambar sprite dengan benar (hanya satu sprite yang dapat ditarik per frame, yang memperlambat program sehingga Anda bisa melihatnya).

Video berkualitas rendah


0

ZX Spectrum BASIC - 179 byte

Ini dia hanya kental sedikit. Ini 179 byte dengan grafik bola disertakan

  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

Silakan lihat mark-up yang digunakan untuk jawaban, juga dengan menggunakan karakter oatau OAnda mungkin dapat menyimpan beberapa byte dalam daftar simbolis; Anda juga dapat mengedit jawaban sebelumnya ketika Anda memiliki solusi yang lebih baik, daripada menjawab ulang pertanyaan yang sama
Shaun Bebbers
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.