Balle rebondissante de style 8 bits autour d'une toile

20

Inspiré par cette liste du Guide de l'utilisateur du 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

Créez un programme similaire dans la langue / plate-forme de votre choix pour faire rebondir un objet semblable à une balle autour de votre terminal, écran, toile ou autre zone d'affichage visuel.

Vous n'avez pas à imiter exactement les graphiques PETSCII du C64, un simple Oou ofera l'affaire, ni à utiliser la GOTOcommande si elle existe toujours dans votre langue. Tant que votre balle commence au sommet de votre toile et se déplace en diagonale jusqu'à ce qu'elle atteigne une limite de toile, puis rebondit en conséquence, comme suit:

  • Déplacement vers le bas et à droite et frappe le bas de la zone d'écran, rebondit et continue à droite;
  • Voyager vers le haut et vers la droite et frappe la limite la plus à droite, et rebondit vers la gauche et vers le haut;
  • Voyager à gauche et en haut et frappe le haut, rebondit à gauche et en bas;
  • Voyager à gauche et en bas et atteint la limite la plus à gauche, rebondit à droite et en bas;
  • Frappe n'importe quel coin et inverse la direction;

Ensuite, nous sommes tous bons.

Vous n'avez pas non plus à déplacer la balle de 8 pixels à la fois, comme c'est le cas dans la liste BASIC du C64; vous pouvez déplacer un bloc de caractères ou un pixel à la fois, selon ce qui vous semble le plus approprié.

Pour voir cette liste BASIC fonctionner, vous pouvez la saisir avec cet émulateur en ligne Commodore 64 à condition que votre navigateur prenne en charge Flash.

Shaun Bebbers
la source
2
Toile JavaScript. D'uh.
Matthew Roh
Je ne sais pas ce que vous appelez un écran de nos jours. Vous aviez l'habitude d'avoir juste l'écran et la zone frontalière visualisés à travers votre téléviseur ou VDU ... et maintenant vous avez des terminaux, des fenêtres, des toiles, stdout etc ... tout cela est très déroutant pour moi.
Shaun Bebbers
Ce serait mieux si nous avions une valeur de taille de pixel constante.
Matthew Roh
4
Pouvons-nous supposer la taille d'écran de 1x1 et imprimer o pour toujours?
Matthew Roh
1
possible doublon de ASCII Ball in Box Animation
Titus

Réponses:

3

6502 code machine (C64), 90 89 91 octets

+2 octets car il a besoin d' une adresse de chargement (pas PIC à cause de l'auto-modification)

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

Démo en ligne

Usage: sys49152

J'ai essayé de réduire la taille (par exemple en n'utilisant pas d'IRQ pour le chronométrage mais des boucles vides stupides à la place), toujours impossible d'atteindre le niveau du C64 BASIC golfé de Titus : o oh, bien. Mais ça a l'air moins scintillant;)

Explication: (vice démontage)

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

Juste pour le plaisir, voici une variante plus professionnelle utilisant un sprite pour le ballon et faisant clignoter la bordure lorsqu'elle est frappée en 385 octets (contenant les données de sprite utilisées sur place ):

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 

Démo en ligne - | - Parcourir la source de l'assembleur ca65

Démarrez et arrêtez la balle qui rebondit avec sys49152.

  • Cela laisse le C64 BASIC en marche, ce qui se fait en déplaçant l'espace d'adressage VIC-II jusqu'à $C000, ce qui nécessite de copier le contenu de l'écran et le jeu de caractères (police).
  • Il se connecte à l'IRQ du système et pour éviter le scintillement, change la source de cet IRQ en puce graphique VIC-II, donc les mises à jour sont toujours effectuées entre les trames.
  • Défaillance:
    1. RUN/STOP + RESTORE est cassé, n'essayez pas.
    2. Avec le VIC-II comme source IRQ, le curseur clignote légèrement plus lentement et TI$sera également à la traîne.
    3. lors de l'arrêt alors que la bordure clignote (très peu probable mais possible), elle reste blanche - vous devez la restaurer manuellement.
Felix Palmen
la source
1
Ce n'est pas totalement indépendant, n'est-ce pas? Je vois deux LDA absolus et deux STA. Excellent travail quand même!
Titus
Merde tu as raison: o J'ai oublié l'auto-modification! Je mettrai à jour dès que je serai sur le PC.
Felix Palmen
1
@Titus fixed ... et juste pour le plaisir, a ajouté une "meilleure" variante :)
Felix Palmen
Avez-vous pensé à emballer le sprite? (Hmm ... utilisez la ROM de jeu de caractères?) Et je préférerais inc $d020plus jsr flash;) hitshimselfwithalargetrout C'est merveilleux!
Titus
1
@Titus économiserait 2 octets, oui. Quant à l'adresse de chargement, elle fait partie d'un .prgfichier valide et de ma méta question ici je suppose que je dois l'inclure ... pourrait probablement le laisser de côté si le code était indépendant de la position.
Felix Palmen
14

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

Animation de l'exemple de course:

Animation de l'échantillon

Mitchell Spector
la source
6
Il a frappé le coin exact! : O
mbomb007
11

Ensemble CP-1610 , 6764 62 DECLEs = 78 octets

Ce code est destiné à être exécuté sur une Intellivision . Il utilise l'un de ses sprites matériels, connu sous le nom de MOB (pour Mobile Object).

Un opcode CP-1610 est codé avec une valeur de 10 bits, connue sous le nom de «DECLE». Ce programme dure 62 DECLEs, commençant à 4800 $ et se terminant à 483D $.

Vidage hexadécimal + source

                            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

Production

production

Arnauld
la source
10

HTML (Microsoft Edge / Internet Explorer), 81 octets

Imaginez que c'est 1998 avec ces <marquee>balises imbriquées :

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

Testé dans Microsoft Edge, mais d'après ce que j'ai lu, IE devrait également prendre en charge les chapiteaux. Décidément ne fonctionne pas dans Chrome.

Le réglage direction=uppermettrait d'économiser 2 octets, mais enfreindrait la règle selon laquelle la balle doit commencer en haut du canevas.

Jack Brounstein
la source
Malheureusement, cette réponse est invalide car le ballon ne se déplace pas en diagonale, comme l'exige le défi.
El'endia Starman
L'avez-vous essayé dans Microsoft Edge? Chrome ne semble pas prendre en charge l' directionattribut.
Jack Brounstein
Huh, mes excuses - cela fonctionne dans Edge. Je peux confirmer que cela ne fonctionne pas dans Chrome et je peux attester qu'il fonctionne dans Firefox et Internet Explorer. Trois sur quatre n'est pas mauvais (et vous n'en avez besoin que d'un pour que cette réponse soit valide). +1
El'endia Starman
1
+1 pour marquee, c'est assez créatif!
Metoniem
A travaillé dans Chrome pour moi.
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

Traduction assez littérale, je ne serais pas surpris s'il existe des astuces pour le réduire.

L'écran est 16x8 et indexé 1 donc les constantes sont différentes.

~ est le moyen SourceCoder d'écrire le symbole de négation.

gif de rebondir O

Il semble plus fluide sur le matériel.

Harold
la source
Êtes-vous sûr que c'est 70 octets? Cela ressemble à moins que ça.
12Me21
@ 12Me21 combien d'octets comptez-vous? J'obtiens 80 octets si j'enregistre ceci sur une calculatrice et 10 octets pour un programme vide qui correspond à mon compte.
harold
Oh, je suppose que j'ai mal compté alors.
12Me21
7

Befunge, 209 octets

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

Cela suppose une taille d'écran de 80x25, mais vous pouvez facilement modifier la plage en remplaçant le "O"(79) sur la dernière ligne et le *64(24) sur l'avant-dernière ligne (notez que l'avant-dernière ligne est exécutée de droite à gauche). La vitesse peut également être ajustée en remplaçant le "2"(50) sur la dernière ligne.

James Holderness
la source
7

Java, 184 176 octets

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

Cela utilise les séquences d'échappement ANSI pour déplacer le curseur, qui est l'objet qui rebondit autour d'un 85 x 25écran de terminal. Enregistrez dans un fichier nommé A.java.

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

Démo

Exemple

R. Kap
la source
Il s'agit du code golf, vous voudrez donc le supprimer Thread.sleep(50). Et vos programmes golfés et non golfés ne correspondent pas.
Jakob
4

Clojure, 398 380 375 octets

(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 octets en changeant le nom de la police en une chaîne vide pour la définir par défaut, en soulignant les vérifications des limites et en corrigeant le problème de limite inférieure (que vous pouvez voir dans le GIF). Correction des octets réellement enregistrés.

-5 octets en passant à une syntaxe de déstructuration plus succincte et en rétrécissant la boule d'un pixel.

Utilise Quil .

J'ai essayé de passer en mode fonctionnel, mais cela nécessitait beaucoup de code supplémentaire et a fini par être plus cher.

(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

(Remarque, la nouvelle version ne rebondit pas tôt le long du bas de l'écran comme elle le fait dans le GIF.)

Carcigenicate
la source
Je viens de réaliser que j'y suis (+ 0 font-size). C'est embarrassant. Je corrigerai cela dans la prochaine version. Devrait me sauver comme 5 octets.
Carcigenicate
4

Raquette 247 octets

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

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

Production:

entrez la description de l'image ici

rnso
la source
1
Jouer au racquetball avec une raquette!
ckjbgames
C'en est une bonne!
rnso
"Racket" est dérivé du langage de programmation "Scheme": après Scheme (un plan sournois) il y a Racket (une arnaque ou une escroquerie)!
rnso
@mso Encore mieux!
ckjbgames
3

Gelée, 37 octets

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

Avec un peu d'aide de cette réponse pour obtenir la bonne boucle et les caractères d'échappement. Actuellement, il rebondit dans un écran 80x24, mais cela peut être facilement modifié dans le code.

Les coördinates dans chaque direction peuvent être représentés comme des éléments de deux listes [0, 1,..., 24, 23,..., 1]et [0, 1,..., 80, 79,..., 1], appelons-les Yet X, qui sont répétés à l'infini. Cette répétition infinie peut être émulée à l'aide d'une indexation modulaire - à l'aide de Jelly. Exemple: lors de la iitération, la balle est en position (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). La balle en mouvement n'est que le curseur qui se met en place en émettant des iịYnouvelles lignes et des iịXespaces.

Démo

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

Explication

“ñ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
la source
2

SmileBASIC, 85 74 octets

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

La position de la balle peut être modélisée avec 2 ondes triangulaires, et le moyen le plus court que j'ai pu trouver pour les produire dans SmileBASIC était l'arc sinus (sinus (x)). (l'algorithme utilisant MOD était plus long puisque SB utilise à la MODplace de %)

12Me21
la source
2

CSS / HTML, 200 + 7 = 207 octets

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

Cette version vous montre la taille de la toile et donne également à l'animation une sensation plus pixélisée:

Neil
la source
2

Dyalog APL, 44 octets

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

Explication:

  • {...}⍨1 1 : appeler la fonction donnée avec ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: stocker ⍺+⍵dans G, afficher un 0à cet endroit dans le⎕SM fenêtre.
    • ⎕DL.1: attendez 1 / 10e de seconde
    • ⊃1 G∨.≥G⎕SD: Contrôle si Gest à la ⎕SMlimite de la fenêtre ( 1≥Gou G≥⎕SD, ⎕SDest le s creen d imensions)
    • 1-2×: carte [1,0]sur[¯1,1] , pour inverser le sens de la marche
    • ⍵×: multipliez le sens de déplacement actuel par celui
    • G∇: récursivité, Gsoit le nouvel emplacement ( ) et ⍵....la nouvelle direction ( ).
marinus
la source
Est-ce censé ouvrir et fermer les terminaux en continu pendant son fonctionnement? Il est assez difficile d'empêcher cela de s'exécuter une fois qu'il est démarré, car le terminal se ferme et rouvre tous les dixièmes de seconde (au moins sous Windows).
ren
1
@wptreanor: fixed
marinus
cool, excellent travail!
ren
2

PHP, 112 97 94 103 102 octets

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

fait rebondir un capital Osur une grille de 40x25, en commençant par le coin supérieur droit;
imprime 99 nouvelles lignes pour effacer l'écran.

Courez avec -nr.

A^K= chr(10)= nouvelle ligne
A^a= chr(32)= espace

Titus
la source
1
Salut Titus, c'est encore moi. 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);. Le modulo est faux à 0 et N et inverse la direction. Malheureusement, nous devons initier $ d et $ e à -1, mais nous réalisons tout de même quelques économies. $x%79<=>.5fonctionne également pour les mêmes octets.
Christoph
1
Salut @Christoph, bon retour. Étrange: quand j'ai copié vos trucs, il contenait 116 octets au lieu de 110. Mais cela m'a inspiré quelque chose de beaucoup plus court.
Titus
Nous sommes définitivement une bonne équipe;) Chose étrange sur la copie, je ne sais pas pourquoi.
Christoph
2

BASIC Simons (C64), 66 65 octets

Un octet enregistré grâce à @ShaunBebbers.

Je n'ai besoin que d'une ligne ici, car Simons´ Basic a une fonction modulo.
AfaIk, cela nécessite un C64 physique et un module BASIC de Simons
(ou toute autre extension BASIC ayant une modfonction).

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

Tapez ces 69 caractères:

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

{CLR}est PETSCII 147, qui efface l'écran. Utilisez Shift + CLR / HOME pour le saisir.

bytecount

Lors de l' enregistrement sur le disque, cela prend 65 octets, car les commandes sont tokenizés:
for, to, poke, abs, nextet gotosont chacun un octet; modprend deux octets.
Cela fait 59 octets de code plus 4 octets pour les pointeurs et 2 octets pour le numéro de ligne.

Pour référence, voir Mappage du C64 et recherchez $800(Texte du programme BASIC).
(Vous pouvez trouver la zone de mémoire de l'écran vidéo sur$400 .)

panne

Le programme boucle Ide 0 à 623 (= LCM de 48 et 78 moins 1). Dans la boucle

  • l'écran est effacé
  • I est mappé à 39..0..38 respectivement 24..0..23
  • et le blob (PETSCII 81) est placé à la position correspondante dans la mémoire vidéo
    (comme le fait le programme d'origine).

Lorsque la boucle est terminée, le programme est redémarré en sautant à la ligne 0.

C64 BASIC, 77 76 octets

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

Malheureusement, j'ai besoin de deux lignes, car même avec toutes les abréviations possibles, il faudrait 83 caractères - trop pour utiliser l'éditeur de ligne C64:

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

(Un éditeur hexadécimal pourrait être utilisé pour créer une ligne plus longue - ce qui en ferait 73 octets.)

Titus
la source
1
Les séparateurs de commandement du Commodore sont :et non;
Shaun Bebbers
1
De plus, si vous commencez à la ligne zéro, vous pouvez simplement utiliser gotodans votre version à deux lignes , car gotosans un nombre suppose goto 0sur BASIC 2
Shaun Bebbers
Si vous souhaitez obtenir plus de commandes sur votre liste C64 BASIC, saisissez-la dans un C128 en mode 128, enregistrez-la sur le disque et chargez-la en mode C64, le C128 a une limite de 160 caractères par défaut afin que cette barrière puisse être franchie par en utilisant les abréviations des mots clés Commodore.
Shaun Bebbers
@ShaunBebbers agréable à savoir. Ça fait tellement longtemps. Je voulais également implémenter cela dans le code machine ... en essayant de récapituler les routines du noyau; Je ne sais pas quand je dois sauvegarder quels registres; la liste complète du noyau est en ligne ; Je ne peux tout simplement pas prendre le temps de creuser davantage. Souhaitez-vous compléter ceci ?
Titus
J'allais faire une version MC, bien que je pense que la soumettre à mon propre défi serait trop indulgente même pour moi. Le moyen le plus rapide serait d'écrire l'octet directement sur l'écran de $0400à $07e7; ou utilisez des sprites. L'utilisation du Kernal avec $ffd2(accumulateur de sortie) fonctionnerait car vous pouvez définir les positions X et Y sur le curseur assez facilement (je ne me souviens pas de l'appel pour cela), mais vous devrez peut-être éviter la dernière position du caractère au cas où cela forcerait un saut de ligne.
Shaun Bebbers
1

Python 2, 176 168 octets

Cela suppose une taille de terminal de 80x24. Certainement pas optimal mais je suis nouveau au golf alors oui.

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)

Merci à R. Kap d'avoir suggéré le x% 79 <1 au lieu de x <1 ou x> 79 et idem pour y.

Tristan Batchler
la source
Vous pouvez économiser quelques octets en remplaçant x<1or x>78par x%79<0et y<1or y>22par y%23<1.
R. Kap
1

Rebol / View, 284 266 octets

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

Non 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
la source
1

C 294 octets

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

Version non golfée:

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

  }   

}

Explication

  • Donc, pour commencer, je devais entrer graphics.hdans mon /usr/includerépertoire. Par conséquent, j'ai cherché et cela que j'ai trouvé. Il s'agit d'une implémentation TurboC Graphics utilisant SDL pour Linux. On pourrait également utiliser OpenGL. Dans Windows, je suppose qu'il est déjà installé, pas sûr de MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);initialise le système et le met en mode graphique, dans ce cas, le pilote graphique est automatiquement détecté. Veuillez vous référer à ce lien pour plus de détails.
  • x et y sont des coordonnées qui déterminent la position de la balle.
  • aet bsont des indicateurs, aest mis à zéro lorsque la xvaleur tombe en dessous de 60 et best mis à zéro lorsquey tombe en dessous de 60.
  • Les drapeaux sont basculés lorsque xety dépassent les valeurs limites de la fenêtre, et les coordonnées sont ajustées en conséquence.
  • Je mets un usleeppour que mon CPU ne soit pas stressé.
  • Il faut normalement utiliser un closegraph()appel pour fermer la fenêtre. Mais il manque ici.

Doit être compilé avec l'indicateur de l'éditeur de liens -lgraph

Il fonctionne plus facilement sur du vrai matériel. :)

Bouncing Red Ball

Abel Tom
la source
Les instructions d'importation sont-elles nécessaires pour exécuter ce programme?
Kritixi Lithos
@KritixiLithos Oui monsieur; Mis à jour! vous devez inclure graphics.h. Cette réponse askubuntu.com/questions/525051/… était utile.
Abel Tom
1

MATL , 42 octets

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

Cela utilise un écran et un caractère 70 × 16 O . Si vous attendez quelques rebonds, vous verrez la balle frapper un coin.

Essayez MATL en ligne!

La taille de l'écran peut être facilement modifiée dans le code. La partie pertinente est 8E70, qui la pousse 8, la double et la pousse 70. Par exemple, pour un écran 80 × 25, remplacez par 5W80, qui le pousse 5, le met au carré et le pousse 80(ou le remplace par 25 80, mais cela nécessite un octet de plus).

De plus, l'ajout tDà la fin du code montre la position actuelle en temps réel (vertical, puis horizontal, en 1 1haut à gauche). Par exemple, pour un 80×18écran,

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

Essayez-le aussi!

Explication

Cela utilise une boucle infinie. La position est conservée dans le presse-papiers en Htant que vecteur 1 × 2 et la direction est conservée dans le presse-papiers en Itant que vecteur 1 × 2 avec les entrées 1ou -1.

Chaque itération efface l'écran, définit une matrice d'espaces, écrit un O à la position appropriée et l'affiche. Ensuite, la position et la direction doivent être mises à jour.

La position est 1basée sur, et donc les bords de l'écran sont 1et la taille maximale de l'écran. Donc, si la taille de l'écran modulo de position donne 0ou 1dans les première ou deuxième composantes, ce qui signifie que nous avons atteint un bord vertical ou horizontal respectivement, cette composante du vecteur de direction est annulée. Après cela, la nouvelle direction est ajoutée à la position actuelle pour obtenir la nouvelle position.

Luis Mendo
la source
1

Voici la liste 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
la source
Belle première entrée DrlB - pourriez-vous s'il vous plaît inclure un nombre d'octets. Je suppose que cela fonctionnera sur n'importe quel Speccy, y compris les machines 16K?
Shaun Bebbers
Salut, c'est 201 octets, vous pouvez omettre les 4 premières lignes, mais vous obtenez juste un caractère "a" rebondissant, mais cela vous fait économiser 64 octets. Je vais essayer d'optimiser. Cela n'a rien d'extraordinaire et fonctionnera sur n'importe quel modèle Spectrum :)
DrIB
Ok, j'ai réussi à le réduire à 185 en condensant un peu les lignes sans laisser tomber le graphisme de la balle. C'est un peu moins lisible mais c'est plus rapide.
DrIB
1

C + curses, 190 octets

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

Explication:

#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
la source
1

Lua ( LÖVE 2D ), 130 octets

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'est pas la meilleure langue en matière de golf de code, mais c'est parti! Quelques points à noter:

  • La taille par défaut du canevas est 800 x 600. Elle peut être modifiée dans le fichier de configuration, mais je n'ai vu aucune restriction de taille, je l'ai donc laissée telle quelle.

  • love.draw()est la fonction de dessin de LÖVE et elle a un nom prédéterminé. Les autres fonctions LÖVE qui pourraient être utilisées seraient love.update(dt)et love.run()- la première étant plus longue, en octets, et la seconde étant plus courte, oui, mais sans boucle infinie intégrée. Ainsi, draw()semble être notre meilleur pari ici.

  • La version ci-dessus utilise love.graphics.pointspour tirer la balle. Bien que plus court, je ne suis pas sûr que ce soit autorisé. Voici un GIF de son fonctionnement:

Capture d'écran animée - point

Comme vous pouvez le voir (ou peut-être pas), un seul pixel se déplace sur l'écran. Bien que cela économise des octets, ce n'est pas le résultat le plus satisfaisant.

J'ai donc fait une solution alternative de 131 octets :

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

Celui-ci utilise love.graphics.print- qui imprime du texte - et un 0comme une balle, ce qui le rend beaucoup plus visible et attrayant.

Capture d'écran animée - zéro

Matheus Avellar
la source
1

CHIP-8, 36 34 28 octets

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

Pas de tours de fantaisie ici ...

Nécessite un interprète qui dessine correctement les sprites (un seul sprite peut être dessiné par image, ce qui ralentit suffisamment le programme pour que vous puissiez le voir).

Vidéo de faible qualité

12Me21
la source
0

ZX Spectrum BASIC - 179 octets

Ici, c'est juste un peu condensé. C'est 179 octets avec les graphiques de balle inclus

  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
la source
Veuillez regarder le balisage utilisé pour les réponses, également en utilisant le caractère oou Ovous pourrez peut-être enregistrer quelques octets dans la liste symbolique; vous pouvez également modifier les réponses précédentes lorsque vous avez amélioré les solutions, plutôt que de répondre à nouveau à la même question
Shaun Bebbers