Pelota que rebota estilo 8 bits alrededor de un lienzo

20

Inspirado en este listado de la Guía del usuario de 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

Haga un programa similar en el idioma / plataforma que elija para hacer rebotar un objeto similar a una pelota alrededor de su terminal, pantalla, lienzo u otra área de visualización.

No tiene que imitar los gráficos PETSCII del C64 exactamente, de manera simple Oo osuficiente, ni tiene que usar el GOTOcomando si todavía existe en su idioma. Siempre que su bola comience en la parte superior de su lienzo y viaje en diagonal hasta que llegue al límite del lienzo, y luego rebote en consecuencia, de la siguiente manera:

  • Viajando hacia abajo y hacia la derecha y toca la parte inferior del área de la pantalla, rebota y continúa hacia la derecha;
  • Viaja hacia arriba y hacia la derecha y golpea el límite más a la derecha, y rebota hacia la izquierda y hacia arriba;
  • Viajando hacia la izquierda y hacia arriba y golpea la parte superior, rebota hacia la izquierda y hacia abajo;
  • Viajando hacia la izquierda y hacia abajo y llega al límite más a la izquierda, rebota hacia la derecha y hacia abajo;
  • Golpea cualquier esquina e invierte la dirección;

Entonces todos estamos bien.

Tampoco tiene que mover la bola 8 píxeles a la vez, como está sucediendo en la lista BÁSICA en el C64; puede mover un bloque de caracteres o un píxel a la vez, lo que considere más apropiado.

Para ver este listado BÁSICO funcionando, puede escribirlo con este emulador en línea Commodore 64 siempre que su navegador admita Flash.

Shaun Bebbers
fuente
2
Lienzo JavaScript. D'uh
Matthew Roh
No estoy seguro de cómo se llama una pantalla hoy en día. Solía ​​ver solo la pantalla y el área del borde a través de su televisor o VDU ​​... y ahora tiene terminales, ventanas, lienzos, stdout, etc. Todo es muy confuso para mí.
Shaun Bebbers
Sería mejor si tuviéramos un valor de tamaño de píxel constante.
Matthew Roh
44
¿Podemos asumir el tamaño de pantalla de 1x1 e imprimir o para siempre?
Matthew Roh
1
posible duplicado de la animación ASCII Ball in Box
Titus

Respuestas:

3

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

+2 bytes porque necesita una dirección de carga (no PIC debido a la auto modificación)

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

Demostración en línea

Uso: sys49152

Traté de reducir el tamaño (p. Ej., NO utilicé IRQ para medir el tiempo, sino estúpidos bucles vacíos), todavía es imposible alcanzar el nivel del golf básico C64 de Titus : oh, bueno. Pero parece menos parpadeante;)

Explicación: (vice desmontaje)

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 por diversión, aquí hay una variante más profesional que usa un sprite para la pelota y parpadea el borde cuando se golpea en 385 bytes (que contiene los datos del sprite que se usan en su lugar ):

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 

Demostración en línea - | - explore la fuente del ensamblador ca65

Comience y pare la pelota que rebota con sys49152.

  • Esto deja el C64 BASIC ejecutándose, eso se hace moviendo el espacio de direcciones VIC-II hacia arriba $C000, lo que requiere copiar el contenido de la pantalla y el juego de caracteres (fuente).
  • Se conecta al sistema IRQ y para evitar el parpadeo, cambia la fuente de este IRQ al chip de gráficos VIC-II, por lo que las actualizaciones siempre se realizan entre cuadros.
  • Glitches:
    1. RUN/STOP + RESTORE está roto, no lo intentes.
    2. Con el VIC-II como fuente de IRQ, el cursor parpadea un poco más lento y también TI$se retrasará.
    3. cuando se detiene mientras el borde está parpadeando (muy poco probable pero posible), permanece blanco; debe restaurarlo manualmente.
Felix Palmen
fuente
1
No es totalmente independiente, ¿verdad? Veo dos LDA absolutas y dos STA. Gran trabajo, no obstante!
Tito
Maldita sea, tienes razón: ¡olvidé la auto modificación! Actualizaré tan pronto como esté en la PC.
Felix Palmen
1
@Titus arreglado ... y solo por diversión, agregó una variante "mejor" :)
Felix Palmen
¿Has considerado empacar el sprite? (Hmm ... ¿usa el juego de caracteres ROM?) Y preferiría inc $d020más que jsr flash;) golpearse a sí mismo con una gran trucha ¡ Es maravilloso!
Titus
1
@Titus ahorraría 2 bytes, sí. En cuanto a la dirección de carga, es parte de un .prgarchivo válido y de mi meta pregunta aquí que tomo, tengo que incluirla ... probablemente podría omitirla si el código fuera independiente de la posición.
Felix Palmen
14

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

Animación de muestra de ejecución:

Animación de muestra de ejecución

Mitchell Spector
fuente
66
¡Llegó a la esquina exacta! : O
mbomb007
11

Conjunto CP-1610 , 6764 62 DECLEs = 78 bytes

Este código está destinado a ejecutarse en una Intellivision . Está utilizando uno de sus sprites de hardware, conocido como MOB (para Mobile Object).

Un código de operación CP-1610 está codificado con un valor de 10 bits, conocido como 'DECLE'. Este programa tiene una duración de 62 DECLE, que comienza en $ 4800 y termina en $ 483D.

Volcado hexadecimal + fuente

                            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

Salida

salida

Arnauld
fuente
10

HTML (Microsoft Edge / Internet Explorer), 81 bytes

Imagina que es 1998 con estas <marquee>etiquetas anidadas :

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

Probado en Microsoft Edge, aunque por lo que he leído, IE también debería ser compatible con las carpas. Decididamente no funciona en Chrome.

La configuración direction=upahorraría 2 bytes, pero rompería la regla de que la pelota tiene que comenzar en la parte superior del lienzo.

Jack Brounstein
fuente
Desafortunadamente, esta es una respuesta no válida ya que la pelota no viaja diagonalmente, como lo requiere el desafío.
El'endia Starman
¿Lo probaste en Microsoft Edge? Chrome no parece admitir el directionatributo.
Jack Brounstein
Eh, mis disculpas, funciona en Edge. Puedo confirmar que no funciona en Chrome y puedo dar fe de que sí funciona en Firefox e Internet Explorer. Tres de cada cuatro no es malo (y solo necesita uno para que esta respuesta sea válida). +1
El'endia Starman
1
+1 para marquee, ¡eso es bastante creativo!
Metoniem
Trabajó en Chrome para mí.
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

Traducción literal, no me sorprendería si hay trucos para hacerlo más pequeño.

La pantalla tiene 16x8 y está indexada en 1, por lo que las constantes son diferentes.

~ es la forma de SourceCoder de escribir el símbolo de negación.

gif de rebote O

Se ve más suave en el hardware.

harold
fuente
¿Estás seguro de que son 70 bytes? Parece menos que eso.
12Me21
@ 12Me21 ¿cuántos bytes cuenta? Obtengo 80 bytes si guardo esto en una calculadora y 10 bytes para un programa vacío que concuerda con mi recuento.
Harold
Oh, supongo que conté mal entonces.
12Me21
7

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

Esto supone un tamaño de pantalla de 80x25, pero puede ajustar fácilmente el rango reemplazando el "O"(79) en la última línea y el *64(24) en la segunda última línea (tenga en cuenta que la segunda última línea se ejecuta de derecha a izquierda). La velocidad también se puede ajustar reemplazando el "2"(50) en la última línea.

James Holderness
fuente
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);}}

Esto hace uso de las secuencias de escape ANSI para reubicar el cursor, que es el objeto que rebota alrededor de una 85 x 25pantalla de terminal. Guardar en un archivo llamado A.java.

Sin golf

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

Manifestación

Ejemplo

R. Kap
fuente
Este es el código de golf, por lo que querrás eliminarlo Thread.sleep(50). Y sus programas de golf y sin golf no coinciden.
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 cambiando el nombre de la fuente a una cadena vacía para predeterminarlo, alineando las comprobaciones de límites y solucionando el problema del límite inferior (que puede ver en el GIF). Arreglando eso que realmente guardó bytes.

-5 bytes cambiando a una sintaxis de desestructuración más sucinta y reduciendo la bola por un píxel.

Utiliza Quil .

Traté de cambiar al modo funcional, pero requirió mucho código extra y terminó siendo más 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))))

Pelota GIF

(Tenga en cuenta que la nueva versión no rebota temprano en la parte inferior de la pantalla como lo hace en el GIF).

Carcigenicate
fuente
Me acabo de dar cuenta de que tengo (+ 0 font-size)allí. Eso es vergonzoso. Lo arreglaré en la próxima versión. Debería salvarme como 5 bytes.
Carcigenicar
4

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

Sin golf:

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

Salida:

ingrese la descripción de la imagen aquí

rnso
fuente
1
Jugando racquetball con raqueta!
ckjbgames
¡Esa es buena!
rnso
"Racket" se deriva del lenguaje de programación "Scheme": ¡después de Scheme (un plan tortuoso) hay Racket (una estafa o estafa)!
rnso
@mso ¡Incluso mejor!
ckjbgames
3

Jalea, 37 bytes

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

Con algo de ayuda de esta respuesta para acertar y escapar de los caracteres correctamente. Actualmente rebota en una pantalla de 80x24, pero eso puede modificarse fácilmente en el código.

Las coordenadas en cada dirección pueden representarse como elementos de dos listas [0, 1,..., 24, 23,..., 1]y [0, 1,..., 80, 79,..., 1], llamémoslas Yy X, que se repiten infinitamente. Esta repetición infinita se puede emular usando indexación modular, usando en Jelly. Ejemplo: en la iiteración la pelota está en posición (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). La bola en movimiento es solo el cursor que se coloca en posición emitiendo iịYnuevas líneas y iịXespacios.

Manifestación

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

Explicación

“ñ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.
PidgeyUsedGust
fuente
2

SmileBASIC, 85 74 bytes

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

La posición de la pelota se puede modelar con 2 ondas triangulares, y la forma más corta que pude encontrar para producirlas en SmileBASIC fue arcsine (seno (x)). (el algoritmo que usa MOD fue más largo ya que SB usa en MODlugar de %)

12Me21
fuente
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 versión le muestra el tamaño del lienzo y también le da a la animación una sensación más pixelada:

Neil
fuente
2

Dyalog APL, 44 bytes

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

Explicación:

  • {... }⍨1 1: llama a la función dada con ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: almacenar ⍺+⍵en G, mostrar un 0en esa ubicación en la ⎕SMventana.
    • ⎕DL.1: espere 1/10 de segundo
    • ⊃1 G∨.≥G⎕SD: Verificación si Gestá en el ⎕SMlímite de la ventana ( 1≥Go G≥⎕SD, ⎕SDes la s Creen d IMENSIONES)
    • 1-2×: mapa [1,0]sobre [¯1,1], para voltear la dirección de viaje
    • ⍵×: multiplica la dirección de viaje actual por eso
    • G∇: recursión, deje que Gsea ​​la nueva ubicación ( ) y ⍵....sea ​​la nueva dirección ( ).
marinus
fuente
¿Se supone que esto debe abrir y cerrar terminales continuamente mientras se ejecuta? Es bastante difícil evitar que esto se ejecute una vez que se inicia, ya que el terminal se cierra y se vuelve a abrir cada décima de segundo (al menos en Windows).
ren
1
@wptreanor: arreglado
marinus
genial, excelente trabajo!
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));

rebota un capital Oen una cuadrícula de 40x25, comenzando en la esquina superior derecha;
imprime 99 líneas nuevas para borrar la pantalla.

Corre con -nr.

A^K= chr(10)= nueva línea
A^a= chr(32)= espacio

Titus
fuente
1
Hola Titus, soy yo otra vez. 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);. El módulo es falso en 0 y N y revierte la dirección. Lamentablemente, tenemos que iniciar $ d y $ e a -1, pero aún así obtener algunos ahorros. $x%79<=>.5También funciona para los mismos bytes.
Christoph
1
Hola @Christoph, bienvenido de nuevo. Extraño: cuando copié Tus cosas tenía 116 bytes en lugar de 110. Pero me inspiró a algo mucho más corto.
Titus
Definitivamente somos un buen equipo;) Algo extraño en la copia No tengo idea de por qué.
Christoph
2

Simons´ BASIC (C64), 66 65 bytes

Un byte guardado gracias @ShaunBebbers.

Solo necesito una línea aquí, porque Simons 'Basic tiene una función de módulo.
De hecho, esto requiere un C64 físico y un módulo BÁSICO de Simons
(o cualquier otra extensión BÁSICA que tenga una modfunción).

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

Escriba estos 69 caracteres:

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

{CLR}es PETSCII 147, que borra la pantalla. Use Shift + CLR / HOME para escribirlo.

bytecount

Cuando graba en el disco, se necesita 65 bytes, ya que los comandos se tokenized:
for, to, poke, abs, nexty gotoson un byte cada uno; modtoma dos bytes
Eso genera 59 bytes de código más 4 bytes para punteros y 2 bytes para el número de línea.

Como referencia, consulte Mapeo del C64 y busque $800(Texto de programa BÁSICO).
(Puede encontrar el Área de memoria de la pantalla de video en $400.)

Descompostura

El programa realiza un bucle Ide 0 a 623 (= LCM de 48 y 78 menos 1). En el lazo

  • la pantalla se borra
  • I se asigna a 39..0..38 respectivamente 24..0..23
  • y el blob (PETSCII 81) se coloca en la posición correspondiente en la memoria de video
    (como lo hace el programa original).

Cuando finaliza el ciclo, el programa se reinicia saltando a la línea 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

Desafortunadamente, necesito dos líneas, porque incluso con todas las abreviaturas posibles, tomaría 83 caracteres, demasiados para usar el editor de líneas C64:

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

(Se podría usar un editor hexadecimal para crear una línea más larga, lo que lo convertiría en 73 bytes).

Titus
fuente
1
Los separadores de comando de comodoro son :y no;
Shaun Bebbers
1
Además, si comienza en la línea cero, simplemente puede usar gotoen su versión de dos líneas, ya que gotosin un número asume goto 0en BASIC 2
Shaun Bebbers
Si desea obtener más comandos en su lista C64 BASIC, ingréselo en un C128 en modo 128, guárdelo en el disco y cárguelo nuevamente en el modo C64, el C128 tiene un límite de 160 caracteres por defecto, por lo que esta barrera se puede romper utilizando las abreviaturas de palabras clave de Commodore.
Shaun Bebbers
@ShaunBebbers es bueno saberlo. Ha sido tan largo. También quería implementar esto en el código de la máquina ... tratando de resumir las rutinas del kernel; no estoy seguro de cuándo tengo que hacer una copia de seguridad de lo que registra; la lista completa del núcleo está en línea ; Simplemente no puedo tomar el tiempo para cavar más. ¿Te gustaría completar esto ?
Tito
Iba a hacer una versión MC, aunque creo que presentarla a mi propio desafío sería demasiado indulgente incluso para mí. La forma más rápida sería escribir el byte directamente en la pantalla de $0400a $07e7; o usa sprites. El uso de Kernal con $ffd2(acumulador de salida) funcionaría, ya que puede configurar la posición X e Y en el cursor con bastante facilidad (no recuerdo la llamada para eso), pero es posible que deba evitar la última posición del personaje en caso de que fuerce Un avance de línea.
Shaun Bebbers
1

Python 2, 176168 bytes

Esto supone un tamaño de terminal de 80x24. Definitivamente no es óptimo, pero soy nuevo en el golf, así que 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)

Gracias a R. Kap por sugerir el x% 79 <1 en lugar de x <1 o x> 79 y lo mismo para y.

Tristan Batchler
fuente
Puede guardar algunos bytes reemplazando x<1or x>78con x%79<0y y<1or y>22con y%23<1.
R. Kap
1

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

Sin golf:

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
            ]
        ]
    ]
]
draegtun
fuente
1

C 294 bytes

#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ón sin golf:

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

  }   

}

Explicación

  • Entonces, para comenzar con esto, tuve que ingresar graphics.ha mi /usr/includedirectorio. Por lo tanto, busqué y esto es lo que encontré. Es una implementación de Gráficos TurboC que usa SDL para Linux. También se podría usar OpenGL. En Windows, supongo que ya está instalado, no estoy seguro acerca de MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);inicializa el sistema y lo pone en modo gráfico, en este caso, el controlador de gráficos se detecta automáticamente. Por favor, consulte este enlace para más detalles.
  • xy yson coordenadas que determinan la posición de la pelota.
  • ay bson banderas, ase establece en cero cuando el xvalor cae por debajo de 60 y bse establece en cero cuando ycae por debajo de 60.
  • Las banderas se activan cuando xy yexceden los valores límite de la ventana, y las coordenadas se ajustan en consecuencia.
  • Puse un usleeppara que mi CPU no se estrese.
  • Normalmente se debe usar una closegraph()llamada para cerrar la ventana. Pero falta aquí.

Debe compilarse con la bandera del vinculador -lgraph

Funciona mejor en hardware real. :)

Bouncing Red Ball

Abel Tom
fuente
¿Son necesarias las declaraciones de importación para ejecutar este programa?
Kritixi Lithos
@ KritixiLithos Sí señor; ¡Actualizado! es necesario incluir graphics.h. Esta respuesta askubuntu.com/questions/525051/… fue útil.
Abel Tom
1

MATL , 42 bytes

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

Utiliza una pantalla y un personaje de 70 × 16 O. Si espera algunos rebotes, verá que la pelota golpea una esquina.

¡Pruébelo en MATL Online!

El tamaño de la pantalla se puede modificar fácilmente en el código. La parte relevante es 8E70, que empuja 8, dobla y empuja 70. Por ejemplo, para una pantalla de 80 × 25, reemplace por 5W80, que empuja 5, cuadra y empuja 80(o reemplaza por 25 80, pero eso requiere un byte más).

Además, agregar tDal final del código muestra la posición actual en tiempo real (vertical, luego horizontal, 1 1es la esquina superior izquierda). Como ejemplo, para una 80×18pantalla,

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

¡Pruébalo también!

Explicación

Esto usa un bucle infinito. La posición se mantiene en el portapapeles Hcomo un vector 1 × 2, y la dirección se mantiene en el portapapeles Icomo un vector 1 × 2 con entradas 1o -1.

Cada iteración borra la pantalla, define una matriz de espacios, escribe un Oen la posición relevante y lo muestra. Entonces la posición y directio necesitan ser actualizados.

La posición se 1basa y, por lo tanto, los bordes de la pantalla 1y el tamaño máximo de la pantalla. Entonces, si el tamaño de la pantalla del módulo de posición proporciona 0o 1en el primer o segundo componente, lo que significa que hemos alcanzado un borde vertical u horizontal respectivamente, ese componente del vector de dirección se niega. Después de eso, la nueva dirección se agrega a la posición actual para obtener la nueva posición.

Luis Mendo
fuente
1

Aquí está la lista de 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
DrIB
fuente
Bonita primera entrada DrlB: ¿podría incluir un recuento de bytes? Supongo que esto funcionará en cualquier Speccy, incluidas las máquinas de 16K.
Shaun Bebbers
Hola, esto es 201 bytes, puedes omitir las primeras 4 líneas pero luego obtienes un carácter "a" que rebota pero te ahorra 64 bytes. Intentaré optimizar. Esto no es nada lujoso y funcionará en cualquier modelo Spectrum :)
DrIB
Ok, he logrado reducirlo a 185 condensando un poco las líneas sin dejar caer los gráficos de la bola. Sin embargo, es un poco menos legible pero más rápido.
DrIB
1

C + maldiciones, 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();}}

Explicación:

#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();
    }
}
Felix Palmen
fuente
1

Lua ( LÖVE 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 no es el mejor idioma cuando se trata de código de golf, ¡pero aquí tienes! Algunos puntos que vale la pena mencionar:

  • El tamaño de lienzo predeterminado es 800 x 600. Se puede cambiar en el archivo de configuración, pero no vi ninguna restricción de tamaño, así que lo dejé como está.

  • love.draw()es la función de dibujo de LÖVE y tiene un nombre predeterminado. Las funciones alternativas de LÖVE que podrían usarse serían love.update(dt)y love.run(), la primera más larga, en bytes, y la segunda más corta, sí, pero sin un bucle infinito incorporado. Por lo tanto, draw()parece ser nuestra mejor apuesta aquí.

  • La versión anterior se utiliza love.graphics.pointspara dibujar la pelota. Aunque más corto, no estoy seguro de que esté permitido. Aquí hay un GIF de cómo funciona:

Captura de pantalla animada - punto

Como puede ver (o quizás no puede), hay un solo píxel moviéndose en la pantalla. Si bien eso ahorra bytes, no es el resultado más satisfactorio.

Así que hice una solución 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

Éste usa love.graphics.print, que imprime texto, y a 0como una bola, lo que lo hace mucho más visible y atractivo.

Captura de pantalla animada - cero

Matheus Avellar
fuente
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

No hay trucos elegantes aquí ...

Requiere un intérprete que dibuje sprites correctamente (solo se puede dibujar un sprite por cuadro, lo que ralentiza el programa lo suficiente como para que pueda verlo).

Video de baja calidad

12Me21
fuente
0

ZX Spectrum BASIC - 179 bytes

Aquí solo se condensa un poco. Son 179 bytes con los gráficos de la pelota incluidos

  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
DrIB
fuente
Observe el marcado utilizado para las respuestas, también utilizando el carácter oo Opuede guardar algunos bytes en la lista simbólica; también puede editar respuestas anteriores cuando haya mejorado las soluciones, en lugar de volver a responder la misma pregunta
Shaun Bebbers