Palla che rimbalza in stile 8 bit attorno a una tela


20

Ispirato da questo elenco dalla Guida per l'utente di 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

Crea un programma simile nella lingua / piattaforma prescelta per far rimbalzare un oggetto simile a una palla attorno al tuo terminale, schermo, tela o altra area di visualizzazione.

Non devi imitare esattamente la grafica PETSCII del C64, un semplice Oo olo farà, né devi usare il GOTOcomando se esiste ancora nella tua lingua. Finché la palla inizia nella parte superiore della tela e viaggia in diagonale fino a raggiungere un limite di tela, quindi rimbalza di conseguenza, come segue:

  • Viaggiando verso il basso e verso destra e colpisce la parte inferiore dell'area dello schermo, rimbalza su e continua a destra;
  • Viaggia su e a destra e colpisce il limite più a destra, e rimbalza a sinistra e in alto;
  • Viaggiare a sinistra e su e colpisce la cima, rimbalza a sinistra e in basso;
  • Viaggiando a sinistra e in basso e raggiunge il limite più a sinistra, rimbalza a destra e in basso;
  • Colpisce qualsiasi angolo e inverte la direzione;

Allora stiamo tutti bene.

Non devi nemmeno spostare la palla di 8 pixel alla volta, come sta succedendo nell'elenco BASIC sul C64; puoi spostare un blocco di caratteri o un pixel alla volta, a seconda di quale ritieni più appropriato.

Per vedere questo elenco BASIC funzionare, puoi digitarlo con questo emulatore Commodore 64 online a condizione che il tuo browser supporti Flash.


2
Tela JavaScript. D'uh.
Matthew Roh,

Non sono sicuro di come chiami uno schermo al giorno d'oggi. Prima vedevi solo lo schermo e l'area di confine attraverso il tuo televisore o VDU ​​... e ora hai terminali, finestre, tele, stdout ecc ... è tutto molto confuso per me.
Shaun Bebbers,

Sarebbe meglio se avessimo un valore di dimensione pixel costante.
Matthew Roh,

4
Possiamo assumere le dimensioni dello schermo di 1x1 e stampare per sempre?
Matthew Roh,

1
possibile duplicato di ASCII Ball in Box Animation
Titus

Risposte:


3

6502 codice macchina (C64), 90 89 91 byte

+2 byte perché ha bisogno di un indirizzo di caricamento (non PIC a causa di auto-modifica)

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

Uso: sys49152

Ho cercato di ridurre le dimensioni (ad es. NON usando IRQ per il cronometraggio, ma invece stupidi loop vuoti), ancora impossibile raggiungere il livello del C64 BASIC da golf di Titus : o oh, beh. Ma sembra meno sfarfallio;)

Spiegazione: (smontaggio vice)

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

Solo per divertimento, ecco una variante più professionale che utilizza uno sprite per la palla e lampeggia il bordo quando viene colpito in 385 byte (contenente i dati di sprite utilizzati in posizione ):

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 - | - sfoglia la fonte dell'assemblatore ca65

Inizia e ferma la palla che rimbalza con sys49152.

  • Questo lascia il C64 BASIC in esecuzione, fatto spostando lo spazio degli indirizzi VIC-II su $C000, il che richiede la copia del contenuto dello schermo e del set di caratteri (font).
  • Si collega al sistema IRQ e, per evitare lo sfarfallio, cambia l'origine di questo IRQ nel chip grafico VIC-II, quindi gli aggiornamenti vengono sempre effettuati tra i frame.
  • glitch:
    1. RUN/STOP + RESTORE è rotto, non provarci.
    2. Con VIC-II come sorgente IRQ, il cursore lampeggia leggermente più lentamente e TI$resterà indietro.
    3. quando ci si ferma mentre il bordo è lampeggiato (molto improbabile ma possibile), rimane bianco - è necessario ripristinarlo manualmente.

1
Non è totalmente indipendente, vero? Vedo due LDA assolute e due STA. Ottimo lavoro comunque!
Tito

Accidenti hai ragione: o ho dimenticato l'auto-modifica! Mi aggiorno non appena sono sul PC.
Felix Palmen,

1
@Titus risolto ... e solo per divertimento, aggiunta una variante "migliore" :)
Felix Palmen,

Hai pensato di imballare lo sprite? (Hmm ... usa la ROM set di caratteri?) E preferirei inc $d020finita jsr flash;) hithimselfwithalargetrout È meraviglioso!
Tito,

1
@Titus risparmierebbe 2 byte, sì. Per quanto riguarda l'indirizzo di caricamento, fa parte di un .prgfile valido e dalla mia meta domanda qui prendo devo includerlo ... probabilmente potrei lasciarlo fuori se il codice fosse indipendente dalla posizione.
Felix Palmen,

14

Utilità 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
}

Animazione della corsa di esempio:

Animation of sample run


6
Ha colpito l'angolo esatto! : O
mbomb007,

11

Gruppo CP-1610 , 6764 62 DECLE = 78 byte

Questo codice deve essere eseguito su un Intellivision . Sta usando uno dei suoi sprite hardware, noto come MOB (per Mobile Object).

Un codice operativo CP-1610 è codificato con un valore di 10 bit, noto come "DECLE". Questo programma è lungo 62 DECLE, a partire da $ 4800 e termina a $ 483D.

Dump esadecimale + fonte

                            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

Produzione

output


10

HTML (Microsoft Edge / Internet Explorer), 81 byte

Fai finta che sia il 1998 con questi <marquee>tag nidificati :

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

Testato in Microsoft Edge, anche se da quello che ho letto IE dovrebbe anche supportare i tendoni. Decisamente non funziona in Chrome.

L'impostazione direction=upsalverebbe 2 byte, ma infrange la regola che la palla deve iniziare nella parte superiore dell'area di disegno.


Sfortunatamente, questa è una risposta non valida poiché la palla non viaggia in diagonale, come richiesto dalla sfida.
El'endia Starman,

L'hai provato in Microsoft Edge? Chrome non sembra supportare l' directionattributo.
Jack Brounstein,

Chiedo scusa, funziona con Edge. Posso confermare che non funziona in Chrome e posso attestare che funziona in Firefox e Internet Explorer. Tre su quattro non è male (e ne hai solo uno perché questa risposta sia valida). +1
El'endia Starman,

1
+1 per marquee, è abbastanza creativo!
Metoniem,

Ha funzionato in Chrome per me.
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

Una traduzione abbastanza letterale, non sarei sorpreso se ci fossero dei trucchi per ridurla.

Lo schermo è 16x8 e 1 indicizzato, quindi le costanti sono diverse.

~ è il modo SourceCoder per scrivere il simbolo di negazione.

gif of bouncing O

Sembra più fluido sull'hardware.


Sei sicuro che questo sia 70 byte? Sembra meno di quello.
ME21

@ 12Me21 quanti byte conti? Ottengo 80 byte se lo salvo su una calcolatrice e 10 byte per un programma vuoto che concorda con il mio conteggio.
Harold,

Oh, immagino di aver contato male allora.
Mee

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

Ciò presuppone una dimensione dello schermo di 80x25, ma è possibile modificare facilmente l'intervallo sostituendo il "O"(79) sull'ultima riga e il *64(24) sull'ultima riga (si noti che la seconda ultima riga viene eseguita da destra a sinistra). La velocità può anche essere regolata sostituendo il "2"(50) sull'ultima riga.


7

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

Questo utilizza ANSI Escape Sequences per riposizionare il cursore, che è l'oggetto che rimbalza attorno al 85 x 25display di un terminale. Salva in un file denominato A.java.

Ungolfed

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

dimostrazione

Example


Questo è il golf del codice, quindi ti consigliamo di rimuoverlo Thread.sleep(50). E i tuoi programmi golf e non golf non corrispondono.
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 modificando il nome del carattere in una stringa vuota per impostazione predefinita, allineando i controlli del limite e risolvendo il problema del limite inferiore (che è possibile vedere nella GIF). Correzione dei byte effettivamente salvati.

-5 byte cambiando in una sintassi destrutturante più succinta e restringendo la palla di un pixel.

Usa Quil .

Ho provato a passare alla modalità funzionale, ma richiedeva molto codice aggiuntivo e alla fine è diventato più costoso.

(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

(Nota, la nuova versione non rimbalza presto nella parte inferiore dello schermo come nella GIF.)


Ho appena realizzato di averlo (+ 0 font-size)lì dentro. Questo è imbarazzante. Lo aggiusterò nella prossima versione. Dovrebbe salvarmi come 5 byte.
Carcigenicato,

4

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

Ungolfed:

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

Produzione:

enter image description here


1
Giocare a racquetball con la racchetta!
ckjbgames,

Bella questa!
anche il

"Racket" deriva dal linguaggio di programmazione "Scheme": dopo Scheme (un piano subdolo) c'è Racket (una truffa o truffa)!
anche il

@mso ancora meglio!
ckjbgames,

3

Gelatina, 37 byte

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

Con qualche aiuto da questa risposta per ottenere il loop e scappare i personaggi giusti. Attualmente rimbalza su uno schermo 80x24, ma può essere facilmente modificato nel codice.

I coordinate in ciascuna direzione possono essere rappresentati come elementi di due liste [0, 1,..., 24, 23,..., 1]e [0, 1,..., 80, 79,..., 1], chiamiamoli Ye X, che si ripetono all'infinito. Questa ripetizione infinita può essere emulata usando l'indicizzazione modulare - usando in Jelly. Esempio: nella iiterazione la palla è in posizione (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). La palla in movimento è solo il cursore che viene messo in posizione emettendo iịYnuove linee e iịXspazi.

dimostrazione

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

Spiegazione

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

La posizione della palla può essere modellata con 2 onde triangolari e il modo più breve che ho trovato per produrle in SmileBASIC è stato arcsine (seno (x)). (l'algoritmo che utilizza MOD era più lungo poiché SB utilizza MODinvece di %)


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

Questa versione mostra le dimensioni della tela e conferisce all'animazione un aspetto più pixellato:


2

Dyalog APL, 44 byte

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

Spiegazione:

  • {... }⍨1 1: chiama la funzione specificata con ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: memorizza ⍺+⍵in G, visualizza a 0in quella posizione nella ⎕SMfinestra.
    • ⎕DL.1: attendere 1/10 di secondo
    • ⊃1 G∨.≥G⎕SD: Controllo se Gè al ⎕SMlimite di finestra ( 1≥Go G≥⎕SD, ⎕SDè il s creen d imensioni)
    • 1-2×: mappa [1,0]su [¯1,1], per invertire la direzione del viaggio
    • ⍵×: moltiplica la direzione di marcia attuale per quella
    • G∇: ricorsione, Gsia la nuova posizione ( ) e ⍵....sia la nuova direzione ( ).

Questo dovrebbe aprire e chiudere continuamente i terminali mentre corre? È abbastanza difficile interrompere l'esecuzione dopo l'avvio, poiché il terminale si chiude e si riapre ogni decimo di secondo (almeno su Windows).
ren

1
@wptreanor: fixed
marinus,

fantastico, ottimo lavoro!
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));

rimbalza un capitale Osu una griglia 40x25, a partire dall'angolo in alto a destra;
stampa 99 nuove righe per cancellare lo schermo.

Corri con -nr.

A^K= chr(10)= newline
A^a= chr(32)= spazio


1
Ciao Titus, sono di nuovo io. 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);. Il modulo è falso su 0 e N e ripristina la direzione. Purtroppo dobbiamo iniziare $ d e $ e a -1 ma ottenere ancora qualche risparmio. $x%79<=>.5funziona anche per gli stessi byte.
Christoph,

1
Ciao @Christoph bentornato. Strano: quando ho copiato la tua roba aveva 116 byte anziché 110. Ma mi ha ispirato a qualcosa di molto più breve.
Tito,

Siamo sicuramente una buona squadra;) Strana cosa sulla copia non ho idea del perché.
Christoph,

2

BASIC di Simons (C64), 66 65 byte

Un byte salvato grazie a @ShaunBebbers.

Ho bisogno di una sola riga qui, perché Simons´s Basic ha una funzione modulo.
AfaIk, questo richiede un C64 fisico e un modulo BASIC di Simons
(o qualsiasi altra estensione BASIC che abbia una modfunzione).

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

Digita questi 69 caratteri:

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

{CLR}è PETSCII 147, che cancella lo schermo. Usa Shift + CLR / HOME per digitarlo.

ByteCount

Quando salvato su disco, richiede 65 byte, perché i comandi sono tokenized:
for, to, poke, abs, nextegoto sono un byte ciascuno; modrichiede due byte.
Ciò rende 59 byte di codice più 4 byte per i puntatori e 2 byte per il numero di riga.

Per riferimento, vedere Mappatura del C64 e ricerca$800 (BASIC Program Text).
(È possibile trovare l'area di memoria dello schermo video su $400.)

abbattersi

Il programma scorre I passa da 0 a 623 (= LCM di 48 e 78 meno 1). Nel loop

  • lo schermo viene cancellato
  • I viene mappato a 39..0..38 rispettivamente 24..0..23
  • e il BLOB (PETSCII 81) viene messo nella posizione corrispondente nella memoria video
    (come fa il programma originale).

Al termine del ciclo, il programma viene riavviato saltando alla riga 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

Purtroppo ho bisogno di due righe, perché anche con tutte le possibili abbreviazioni occorrerebbero 83 caratteri, troppi per usare l'editor di linee C64:

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

(Un editor esadecimale potrebbe essere usato per creare una linea più lunga, che lo renderebbe 73 byte.)


1
I separatori del comando Commodore sono :e non;
Shaun Bebbers,

1
Inoltre, se inizi dalla riga zero, puoi semplicemente usare gotonella tua versione a due linee, come gotosenza un numero ipotizzato goto 0su BASIC 2
Shaun Bebbers,

Se vuoi ottenere più comandi sul tuo elenco BASIC C64, inseriscilo in un C128 in modalità 128, salvalo su disco e ricaricalo in modalità C64, il C128 ha un limite di 160 caratteri per impostazione predefinita, quindi questa barriera può essere superata da utilizzando le abbreviazioni delle parole chiave Commodore.
Shaun Bebbers,

@ShaunBebbers bello da sapere. È passato così tanto. Volevo anche implementarlo nel codice macchina ... cercando di ricapitolare le routine del kernel; non sono sicuro quando devo fare il backup di ciò che registra; l'elenco completo del kernel è online ; Non riesco proprio a dedicare del tempo a scavare ulteriormente. Vuoi completare questo ?
Tito,

Stavo per fare una versione MC, anche se penso che sottoporla alla mia sfida sarebbe troppo indulgente anche per me. Il modo più veloce sarebbe quello di scrivere il byte direttamente sullo schermo da $0400a $07e7; o usa gli sprite. L'uso di Kernal con $ffd2(accumulatore di output) funzionerebbe in quanto puoi impostare le posizioni X e Y sul cursore abbastanza facilmente (non ricordo la chiamata per quello), ma potresti dover evitare l'ultima posizione del carattere nel caso in cui forza un feed di riga.
Shaun Bebbers,

1

Python 2, 176 168 byte

Ciò presuppone una dimensione terminale di 80x24. Sicuramente non ottimale, ma sono nuovo al golf, quindi sì.

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)

Grazie a R. Kap per aver suggerito x% 79 <1 invece di x <1o x> 79 e idem per y.


È possibile salvare alcuni byte sostituendo x<1or x>78con x%79<0e y<1or y>22con y%23<1.
R. Kap,

1

Rebol / View, 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]]]]

Ungolfed:

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

Versione non golfata:

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

  }   

}

Spiegazione

  • Quindi, per iniziare, ho dovuto accedere graphics.halla mia /usr/includedirectory. Pertanto, ho cercato e questo è quello che ho trovato. È un'implementazione grafica TurboC che utilizza SDL per Linux. Si potrebbe anche usare OpenGL. In Windows, suppongo che sia già installato, non sono sicuro di MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);inizializza il sistema e lo mette in modalità grafica, in questo caso il driver grafico viene rilevato automaticamente. Si prega di fare riferimento a questo link per maggiori dettagli.
  • x e y sono coordinate che determinano la posizione della palla.
  • ae bsono flag, aè impostato su zero quando il xvalore scende al di sotto di 60 ed bè impostato su zero quandoy scende al di sotto di 60.
  • Le bandiere vengono attivate quando xey supera valori limite della finestra, e le coordinate sono adeguati.
  • Ho messo un usleepmodo che la mia CPU non si stressasse.
  • Si dovrebbe normalmente usare una closegraph()chiamata, per chiudere la finestra. Ma manca qui.

Deve essere compilato con il flag linker -lgraph

Funziona meglio su hardware reale. :)

Bouncing Red Ball


Le istruzioni di importazione sono necessarie per eseguire questo programma?
Kritixi Lithos,

@KritixiLithos Sì signore; Aggiornato! devi includere graphics.h. Questa risposta è stata utile askubuntu.com/questions/525051/… .
Abel Tom,

1

MATL , 42 byte

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

Questo utilizza uno schermo e un personaggio di 70 × 16 O. Se aspetti qualche rimbalzo vedrai la palla colpire un angolo.

Prova su MATL Online!

Le dimensioni dello schermo possono essere facilmente modificate nel codice. La parte rilevante è 8E70che spinge 8, raddoppia e spinge 70. Ad esempio, per uno schermo 80 × 25 sostituisci con 5W80, che lo spinge 5, lo quadra e lo spinge 80(o sostituisce da 25 80, ma che richiede un altro byte).

Inoltre, l'aggiunta tDalla fine del codice mostra la posizione corrente in tempo reale (verticale, quindi orizzontale, 1 1è in alto a sinistra). Ad esempio, per uno 80×18schermo,

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

Provalo anche tu!

Spiegazione

Questo utilizza un ciclo infinito. La posizione viene mantenuta negli Appunti Hcome vettore 1 × 2 e la direzione viene mantenuta negli Appunti Icome vettore 1 × 2 con voci 1o -1.

Ogni iterazione cancella lo schermo, definisce una matrice di spazi, ne scrive una Onella posizione pertinente e la visualizza. Quindi la posizione e il directio devono essere aggiornati.

La posizione è 1basata su, quindi i bordi dello schermo sono 1e la dimensione massima dello schermo. Quindi, se la dimensione dello schermo del modulo di posizione dà 0o 1nel primo o nel secondo componente, il che significa che abbiamo raggiunto un bordo verticale o orizzontale rispettivamente, quel componente del vettore di direzione viene negato. Successivamente, la nuova direzione viene aggiunta alla posizione corrente per ottenere la nuova posizione.


1

Ecco l'elenco di 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

Simpatica prima voce DrlB - potresti per favore includere un conteggio di byte. Suppongo che funzionerà su qualsiasi Speccy comprese le macchine 16K?
Shaun Bebbers,

Ciao, questo è 201 byte, potresti omettere le prime 4 righe ma poi ottieni solo un carattere "a" che rimbalza ma ti fa risparmiare 64 byte. Proverò a ottimizzare. Questo non è niente di speciale e funzionerà su qualsiasi modello di spettro :)
DrIB

Ok, sono riuscito a ridurlo a 185 condensando un po 'le linee senza far cadere la grafica della palla. È un po 'meno leggibile, ma è più veloce.
DrIB,

1

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

Spiegazione:

#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 non è la lingua migliore per quanto riguarda il codice golf, ma ecco qui! Alcuni punti da ricordare:

  • La dimensione di tela predefinita è 800 x 600. Può essere modificata nel file di configurazione, ma non ho visto alcuna limitazione di dimensione, quindi l'ho lasciata così com'è.

  • love.draw()è la funzione di disegno di LÖVE e ha un nome predeterminato. Le funzioni LÖVE alternative che potrebbero essere utilizzate sarebbero love.update(dt)e love.run()- il primo è più lungo, in byte, e il secondo è più corto, sì, ma senza un loop infinito incorporato. Quindi, draw()sembra essere la nostra migliore scommessa qui.

  • La versione precedente usa love.graphics.pointsper disegnare la palla. Anche se più corto, non sono sicuro che sia permesso. Ecco una GIF di come funziona:

Animated screenshot - point

Come puoi vedere (o forse non è possibile), sullo schermo è presente un singolo pixel. Sebbene ciò salvi i byte, non è il risultato più soddisfacente.

Quindi ho creato una soluzione alternativa da 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

Questo usa love.graphics.print- che stampa il testo - e una 0come una palla, rendendolo molto più visibile e accattivante.

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

Nessun trucco di fantasia qui ...

Richiede un interprete che disegna correttamente gli sprite (è possibile disegnare solo uno sprite per fotogramma, il che rallenta il programma abbastanza da consentirti di vederlo).

Video di bassa qualità


0

ZX Spectrum BASIC - 179 byte

Qui è solo un po 'condensato. Sono 179 byte con la grafica della palla inclusa

  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

Guarda il mark-up usato per le risposte, anche usando il carattere oo Opotresti essere in grado di salvare alcuni byte nell'elenco simbolico; sei anche in grado di modificare le risposte precedenti quando hai migliorato le soluzioni, piuttosto che rispondere alla stessa domanda
Shaun Bebbers
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.