Bola quicando no estilo de 8 bits em torno de uma tela


20

Inspirado por esta listagem no Commodore 64 Guia do usuário:

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

Faça um programa semelhante no idioma / plataforma escolhido para rebater um objeto parecido com uma bola ao redor do seu terminal, tela, tela ou outra área de exibição visual.

Você não precisa imitar exatamente os gráficos PETSCII do C64, um simples Oou o ofará, nem precisa usar o GOTOcomando se ele ainda existir no seu idioma. Desde que sua bola comece no topo da tela e viaje na diagonal até atingir o limite da tela, e depois salte conforme a seguinte:

  • Viajando para baixo e para a direita e atinge a parte inferior da área da tela, salta para cima e continua à direita;
  • Viajando para cima e para a direita e atinge o limite mais à direita e salta para a esquerda e para cima;
  • Viajando para a esquerda e para cima e atinge o topo, salta para a esquerda e para baixo;
  • Viajando para a esquerda e para baixo e atinge o limite mais à esquerda, salta para a direita e para baixo;
  • Atinge qualquer canto e inverte a direção;

Então estamos todos bem.

Você também não precisa mover 8 pixels de cada vez, como está acontecendo na listagem BASIC do C64; você pode mover um bloco de caracteres ou um pixel de cada vez, o que achar mais apropriado.

Para ver esta listagem BASIC funcionando, você pode digitá-la com este emulador online Commodore 64, desde que o seu navegador suporte Flash.


2
Tela JavaScript. D'uh.
Matthew Roh

Não tenho certeza do que você chama de tela hoje em dia. Você costumava ter apenas a área da tela e da borda visualizada através do seu aparelho de televisão ou VDU ... e agora você tem terminais, janelas, telas, stdout etc ... tudo isso é muito confuso para mim.
Shaun Bebbers

Seria melhor se tivéssemos um valor de tamanho de pixel constante.
Matthew Roh

4
Podemos assumir o tamanho da tela de 1x1 e imprimir o para sempre?
Matthew Roh

1
possível duplicata do ASCII Ball em Box Animation
Titus

Respostas:


3

Código da máquina 6502 (C64), 90 89 91 bytes

+2 bytes porque precisa de um endereço de carregamento (não PIC por causa da auto-modificação)

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

Demonstração online

Uso: sys49152

Eu tentei muito reduzir o tamanho (por exemplo, NÃO usar IRQs para cronometrar, mas estúpidos loops vazios), ainda é impossível atingir o nível do C64 BASIC jogado por Titus : ooh, bem. Mas parece menos cintilante;)

Explicação: (desmontagem de 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

Apenas por diversão, aqui está uma variante mais profissional, usando um sprite para a bola e piscando a borda quando atingida em 385 bytes (contendo os dados do sprite usados no local ):

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 

Demonstração online - | - procure a fonte do montador ca65

Comece e pare a bola quicando com sys49152.

  • Isso deixa o C64 BASIC em execução, movendo o espaço de endereço do VIC-II para cima $C000, o que requer a cópia do conteúdo da tela e do conjunto de caracteres (fonte).
  • Ele se conecta ao IRQ do sistema e, para evitar oscilações, altera a origem desse IRQ para o chip gráfico VIC-II, para que as atualizações sejam sempre feitas entre os quadros.
  • Falhas:
    1. RUN/STOP + RESTORE está quebrado, não tente.
    2. Com o VIC-II como fonte de IRQ, o cursor pisca um pouco mais devagar e TI$fica para trás também.
    3. ao parar enquanto a borda estiver piscando (muito improvável, mas possível), ela permanecerá branca - você precisará restaurá-la manualmente.

1
Não é totalmente independente, é? Eu vejo dois LDAs absolutos e dois STAs. Grande trabalho, no entanto!
Titus

Porra, você está certo: o Esqueci a auto-modificação! Vou atualizar assim que estiver no PC.
Felix Palmen

1
@Titus fixo ... e só por diversão, acrescentou um "melhor" variante :)
Felix Palmen

Você já pensou em empacotar o sprite? (Hmm ... utilizar o ROM charset?) E GOSTARIA preferem inc $d020mais jsr flash;) hitshimselfwithalargetrout IT'S maravilhosa!
Titus

1
@ Titus economizaria 2 bytes, sim. Quanto ao endereço de carregamento, ele faz parte de um .prgarquivo válido e, da minha meta-pergunta aqui , eu tenho que incluí-lo ... provavelmente poderia deixá-lo de fora se o código fosse independente da posição.
Felix Palmen

14

Utilitários Bash + Unix, 125 117 bytes

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
}

Animação da amostra:

Animação da execução da amostra


6
Chegou ao canto exato! : O
mbomb007 21/02

11

Montagem CP-1610 , 6764 62 DECLEs = 78 bytes

Este código deve ser executado em um Intellivision . Ele está usando um de seus sprites de hardware, conhecido como MOB (para Mobile Object).

Um código de operação CP-1610 é codificado com um valor de 10 bits, conhecido como 'DECLE'. Este programa tem 62 DECLEs, começando em US $ 4800 e terminando em US $ 483D.

Despejo hexadecimal + 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

Saída

saída


10

HTML (Microsoft Edge / Internet Explorer), 81 bytes

Finja que é 1998 com estas <marquee>tags aninhadas :

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

Testado no Microsoft Edge, embora, pelo que li, o IE também deva dar suporte a tendas. Decididamente não funciona no Chrome.

A configuração direction=upeconomizaria 2 bytes, mas viole a regra de que a bola deve começar no topo da tela.


Infelizmente, esta é uma resposta inválida, pois a bola não viaja na diagonal, conforme exigido pelo desafio.
El'endia Starman

Você tentou no Microsoft Edge? O Chrome parece não suportar o directionatributo.
21317 Jack Brounstein

Minhas desculpas - ele funciona no Edge. Posso confirmar que não funciona no Chrome e posso atestar que funciona no Firefox e no Internet Explorer. Três em cada quatro não são ruins (e você só precisa de um para que esta resposta seja válida). +1
El'endia Starman

1
+1 para marquee, isso é bastante criativo!
Metoniem

Trabalhou no Chrome para mim.
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

Tradução literal, eu não ficaria surpreso se houver truques para torná-lo menor.

A tela é indexada em 16x8 e 1, portanto as constantes são diferentes.

~ é a maneira do SourceCoder de escrever o símbolo de negação.

gif de saltar O

Parece mais suave no hardware.


Tem certeza de que são 70 bytes? Parece menos do que isso.
precisa

@ 12Me21 quantos bytes você conta? Eu obtenho 80 bytes se eu salvar isso em uma calculadora e 10 bytes para um programa vazio que concorda com minha contagem.
Harold

Acho que contei errado então.
precisa

7

Anterior, 209 bytes

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

Isso assume um tamanho de tela de 80x25, mas você pode ajustar o intervalo facilmente substituindo o "O"(79) na última linha e o *64(24) na segunda última linha (observe que a segunda última linha é executada da direita para a esquerda). A velocidade também pode ser ajustada substituindo o "2"(50) na última linha.


7

Java, 184 176 bytes

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

Isso faz uso das seqüências de escape ANSI para realocar o cursor, que é o objeto que salta ao redor de uma 85 x 25tela do terminal. Salve em um arquivo chamado 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;
        }
    }
}

Demo

Exemplo


Isso é código de golfe, então você deseja remover Thread.sleep(50). E seus programas jogados e não jogados não correspondem.
Jakob

4

Clojure, 398 380 375 bytes

(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 bytes, alterando o nome da fonte para uma string vazia para padronizá-la, alinhando as verificações de limite e corrigindo o problema de limite inferior (que você pode ver no GIF). Corrigindo os bytes realmente salvos.

-5 bytes, mudando para uma sintaxe de destruição mais sucinta e diminuindo a bola em um pixel.

Usa Quil .

Tentei mudar para o modo funcional, mas exigiu muito código extra e acabou sendo mais caro.

(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

(Observe que a nova versão não salta mais cedo na parte inferior da tela, como ocorre no GIF.)


Acabei de perceber que tenho (+ 0 font-size)lá. É embaraçoso. Vou consertar isso na próxima versão. Deve me salvar como 5 bytes.
Carcigenicate

4

Raquete 247 bytes

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

Saída:

insira a descrição da imagem aqui


1
Jogando raquete com raquete!
Ckjbgames

Essa é boa!
rnso

"Raquete" é derivado da linguagem de programação "Esquema": depois de Esquema (um plano desonesto), há Raquete (uma farsa ou fraude)!
rnso

@mso Ainda melhor!
Ckjbgames

3

Geléia, 37 bytes

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

Com alguma ajuda desta resposta para obter o loop e os caracteres de escape corretos. Atualmente, ele salta em uma tela de 80x24, mas isso pode ser facilmente modificado no código.

Os coordenados em cada direção podem ser representados como elementos de duas listas [0, 1,..., 24, 23,..., 1]e [0, 1,..., 80, 79,..., 1], vamos chamá-los Ye X, que são infinitamente repetidos. Essa repetição infinita pode ser emulada usando indexação modular - usando no Jelly. Exemplo: na iiteração, a bola está na posição (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). A bola em movimento é apenas o cursor que é colocado em posição emitindo iịYnovas linhas e iịXespaços.

Demo

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

Explicação

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

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

A posição da bola pode ser modelada com duas ondas triangulares, e a maneira mais curta que consegui produzi-las no SmileBASIC foi o arco-seno (seno (x)). (o algoritmo usando MOD foi mais longo, pois o SB usa em MODvez de %)


2

CSS / HTML, 200 + 7 = 207 bytes

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

Esta versão mostra o tamanho da tela e também dá à animação uma sensação mais pixelizada:


2

Dyalog APL, 44 bytes

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

Explicação:

  • {...}⍨1 1 : chame a função fornecida com ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: armazenar ⍺+⍵em G, exibir um 0naquele local no⎕SM janela.
    • ⎕DL.1: aguarde 1/10 de segundo
    • ⊃1 G∨.≥G⎕SD: Verificação se Gestá no ⎕SMlimite da janela ( 1≥Gou G≥⎕SD, ⎕SDé o s creen d imensions)
    • 1-2×: mapear [1,0]para[¯1,1] , para inverter a direção da viagem
    • ⍵×: multiplique a direção atual da viagem por essa
    • G∇: recursão, Gseja o novo local ( ) e ⍵....a nova direção ( ).

Supõe-se que ele abra e feche terminais continuamente enquanto ele é executado? É muito difícil impedir a execução assim que o terminal é fechado, pois o terminal fecha e reabre a cada décimo de segundo (pelo menos no Windows).
21717 ren

1
@wptreanor: fixed
marinus

legal, excelente trabalho!
ren

2

PHP, 112 97 94 103 102 bytes

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

Orecupera um capital em uma grade de 40x25, começando no canto superior direito;
imprime 99 novas linhas para limpar a tela.

Corra com -nr.

A^K= chr(10)= nova linha
A^a= chr(32)= espaço


1
Oi Titus, sou eu de novo. 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);. O módulo é falso em 0 e N e reverte a direção. Infelizmente, temos que iniciar $ d e $ e para -1, mas ainda conseguimos algumas economias. $x%79<=>.5também funciona para os mesmos bytes.
Christoph

1
Hey @Christoph bem vindo de volta. Estranho: quando eu copiei o seu material, ele tinha 116 bytes em vez de 110. Mas isso me inspirou a algo muito mais curto.
Titus

Definitivamente, somos uma boa equipe;) Coisa estranha na cópia, não tenho idéia do porquê.
Christoph

2

BASIC de Simons (C64), 66 65 bytes

Um byte salvo agradeceu @ShaunBebbers.

Eu preciso de apenas uma linha aqui, porque o Simons´ Basic tem uma função de módulo.
Afinal, isso requer um C64 físico e um módulo BASIC de Simons
(ou qualquer outra extensão BASIC que tenha uma modfunção).

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

Digite estes 69 caracteres:

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

{CLR}é o PETSCII 147, que limpa a tela. Use Shift + CLR / HOME para digitar.

bytecount

Quando guardadas em disco, que leva de 65 bytes, porque os comandos são tokenized:
for, to, poke, abs, nexte gotosão um byte de cada; modleva dois bytes.
Isso gera 59 bytes de código mais 4 bytes para ponteiros e 2 bytes para o número da linha.

Para referência, consulte Mapeando o C64 e procure por $800(Texto do Programa BASIC).
(Você pode encontrar a área de memória da tela de vídeo em $400.)

demolir

O programa faz um loop Ide 0 a 623 (= LCM de 48 e 78 menos 1). No loop

  • a tela é limpa
  • I é mapeado para 39..0..38 respectivamente 24..0..23
  • e o blob (PETSCII 81) é colocado na posição correspondente na memória de vídeo
    (como o programa original).

Quando o loop é concluído, o programa é reiniciado pulando para a linha 0.

C64 BASIC, 77 76 bytes

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

Infelizmente, preciso de duas linhas, porque mesmo com todas as abreviações possíveis, seriam necessários 83 caracteres - muitos para usar o editor de linha C64:

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

(Um editor hexadecimal pode ser usado para criar uma linha mais longa - o que tornaria 73 bytes.)


1
Separadores de comandos Commodore são :e não;
Shaun Bebbers

1
Além disso, se você começar na linha zero, você pode simplesmente usar gotoem sua versão de dois forro, como gotosem um número assume goto 0em BASIC 2
Shaun Bebbers

Se você deseja obter mais comandos na sua lista do C64 BASIC, insira-o no C128 no modo 128, salve-o em disco e carregue-o novamente no modo C64, o C128 tem um limite de 160 caracteres por padrão, para que essa barreira possa ser quebrada por usando abreviações de palavras-chave do Commodore.
Shaun Bebbers

@ShaunBebbers é bom saber. Faz tanto tempo. Eu também queria implementar isso no código da máquina ... tentando recapitular as rotinas do kernel; não tenho certeza quando tenho que fazer backup do que registra; a lista completa do kernel está online ; Eu simplesmente não aguento tempo para cavar mais. Deseja concluir isso ?
Titus

Eu ia fazer uma versão do MC, embora eu ache que a submissão ao meu próprio desafio seria indulgente mesmo para mim. A maneira mais rápida seria escrever o byte diretamente na tela de $0400para $07e7; ou use sprites. Usar o Kernal com $ffd2(acumulador de saída) funcionaria, pois você pode definir as posições X e Y no cursor com bastante facilidade (não me lembro da chamada para isso), mas talvez você precise evitar a posição do último caractere, caso isso o force um avanço de linha.
Shaun Bebbers

1

Python 2, 176 168 bytes

Isso pressupõe um tamanho de terminal de 80x24. Definitivamente não é o ideal, mas eu sou novo no golfe, então sim.

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)

Agradecemos a R. Kap por sugerir x% 79 <1 em vez de x <1 ou x> 79 e o mesmo para y.


Você pode salvar alguns bytes substituindo x<1or x>78por x%79<0e y<1or y>22por y%23<1.
R. Kap

1

Rebol / Vista, 284266 bytes

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

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

Versão não destruída:

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

  }   

}

Explicação

  • Então, para começar, eu tive que entrar graphics.hno meu /usr/includediretório. Portanto, eu procurei e é isso que eu encontrei. É uma implementação de TurboC Graphics usando SDL para Linux. Pode-se também usar o OpenGL. No Windows, acho que já está instalado, não tenho certeza sobre o MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);inicializa o sistema e coloca-o no modo gráfico; nesse caso, o driver gráfico é detectado automaticamente. Por favor, consulte este link para mais detalhes.
  • xe ysão coordenadas que determinam a posição da bola.
  • ae bsão sinalizadores, aé definido como zero quando o xvalor cai abaixo de 60 e bé definido como zero quandoy cai abaixo de 60.
  • As bandeiras são alternadas quando xey excedem os valores limites da janela, e as coordenadas são ajustadas de acordo.
  • Coloquei um usleeppara que minha CPU não fique estressada.
  • Normalmente, deve-se usar uma closegraph()chamada para fechar a janela. Mas está faltando aqui.

Deve ser compilado com o sinalizador de vinculador -lgraph

Ele roda mais suave em hardware real. :)

Saltando bola vermelha


As instruções de importação são necessárias para executar este programa?
Kritixi Lithos

@KritixiLithos Sim senhor; Atualizada! você precisa incluir graphics.h. Esta resposta askubuntu.com/questions/525051/… foi útil.
Abel Tom

1

MATL , 42 bytes

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

Isso usa uma tela e um personagem de 70 × 16 O. Se você esperar alguns saltos, verá a bola acertando um canto.

Experimente o MATL Online!

O tamanho da tela pode ser facilmente modificado no código. A parte relevante é 8E70, que empurra 8, dobra e empurra70 . Por exemplo, para uma tela de 80 × 25, substitua por 5W80, que empurra 5, esquadrinha e empurra 80(ou substitua por25 80 , mas isso requer mais um byte).

Além disso, adicionar tDno final do código mostra a posição atual em tempo real (vertical, depois horizontal, 1 1é superior esquerdo). Como exemplo, para um80×18 tela,

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

Experimente também!

Explicação

Isso usa um loop infinito. A posição é mantida na área de transferência Hcomo um vetor 1 × 2 e a direção é mantida na área de transferência Icomo um vetor 1 × 2 com entradas 1ou -1.

Cada iteração limpa a tela, define uma matriz de espaços, escreve um O na posição relevante e a exibe. Em seguida, a posição e o diretório precisam ser atualizados.

A posição é 1baseada e, portanto, as bordas da tela são 1e o tamanho máximo da tela. Portanto, se o tamanho da tela do módulo de posição fornecer 0ou 1no primeiro ou no segundo componentes, o que significa que atingimos uma aresta vertical ou horizontal, respectivamente, esse componente do vetor de direção será negado. Depois disso, a nova direção é adicionada à posição atual para obter a nova posição.


1

Aqui está a lista do 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

Boa primeira entrada DrlB - você poderia incluir uma contagem de bytes. Presumo que isso funcione em qualquer Speccy, incluindo máquinas de 16K?
Shaun Bebbers

Oi, isso é 201 bytes, você pode omitir as 4 primeiras linhas, mas então você obtém apenas um caractere "a", mas economiza 64 bytes. Vou tentar otimizar. Esta fantasia nada e irá funcionar em qualquer modelo Spectrum :)
drib

Ok, eu consegui reduzir para 185 condensando um pouco as linhas sem deixar cair os gráficos da bola. É um pouco menos legível, mas é mais rápido.
DrIB

1

Maldições C +, 190 bytes

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

Explicação:

#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 ( 2D ), 130 bytes

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 não é a melhor linguagem para codificar golfe, mas aqui está você! Alguns pontos que vale a pena mencionar:

  • O tamanho da tela padrão é 800 x 600. Ele pode ser alterado no arquivo de configuração, mas não vi nenhuma restrição de tamanho, então deixei como está.

  • love.draw()é a função de desenho de LÖVE e tem um nome predeterminado. Funções alternativas do LÖVE que poderiam ser usadas seriam love.update(dt)e love.run()- a primeira sendo mais longa, em bytes, e a segunda mais curta, sim, mas sem um loop infinito embutido. Assim, draw()parece ser a nossa melhor aposta aqui.

  • A versão acima usa love.graphics.pointspara desenhar a bola. Embora seja mais curto, não tenho certeza se é permitido. Aqui está um GIF de como ele é executado:

Captura de tela animada - point

Como você pode ver (ou talvez não possa), há um único pixel se movendo na tela. Enquanto isso economiza bytes, não é o resultado mais satisfatório.

Então, eu fiz uma solução alternativa de 131 bytes :

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

Este usa love.graphics.print- que imprime texto - e um 0como uma bola, tornando-o muito mais visível e atraente.

Captura de tela animada - zero


1

CHIP-8, 36 34 28 bytes

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

Não há truques sofisticados aqui ...

Requer um intérprete que desenhe sprites corretamente (apenas um sprite pode ser desenhado por quadro, o que torna o programa mais lento o suficiente para que você possa vê-lo).

Vídeo de baixa qualidade


0

ZX Spectrum BASIC - 179 bytes

Aqui está apenas um pouco condensado. São 179 bytes com os gráficos de bola incluídos

  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

Observe a marcação usada para obter respostas, também usando o caractere, oou Ovocê poderá salvar alguns bytes na lista simbólica; você também é capaz de editar respostas anteriores quando você tem soluções melhoradas, ao invés de re-responder a mesma pergunta
Shaun Bebbers
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.