8-бітний стиль підстрибує куля навколо полотна


20

Натхненний цим лістингом у Посібнику користувача 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

Створіть подібну програму на обраній вами мові / платформі, щоб підстрибувати кульковий предмет навколо вашого терміналу, екрана, полотна чи іншої області візуального відображення.

Вам не доведеться точно імітувати графіку PETSCII C64, просто, Oабо просто o, і не потрібно використовувати GOTOкоманду, якщо вона все ще існує на вашій мові. Поки ваш кулька починається у верхній частині полотна і рухається по діагоналі, поки він не досягне межі полотна, а потім відскакує відповідно таким чином:

  • Пересуваючись вниз і вправо і потрапляючи в нижню частину екрану, відскакує вгору і продовжує праворуч;
  • Подорожуючи вгору і вправо, вдаряє правий край, і відскакує вліво і вгору;
  • Подорожуючи вліво і вгору і б'є вгору, відскакує вліво і вниз;
  • Подорожуючи вліво і вниз і досягаючи самої лівої межі, відскакує праворуч і вниз;
  • Пробиває будь-який кут і повертає напрямок;

Тоді ми всі хороші.

Вам також не потрібно одночасно переміщувати 8-піксельну кулю, як це відбувається у списку BASIC на C64; Ви можете переміщати один блок символів або один піксель одночасно, що б ви не вважали найбільш підходящим.

Для того, щоб цей ОСНОВНИЙ перелік працював, ви можете ввести його за допомогою цього інтернет-емулятора Commodore 64, який надає веб-переглядачу Flash.


2
Полотно JavaScript. Д'ух.
Меттью Ро

Я не впевнений, що ви сьогодні називаєте екраном. У вас раніше телевізор або VDU переглядали лише екран і облямівку ... а тепер у вас є термінали, вікна, полотна, прокладки тощо ... для мене це все дуже заплутано.
Shaun Bebbers

Було б краще, якби ми мали значення постійного розміру пікселя.
Меттью Ро

4
Чи можемо ми припустити розмір екрана 1x1 та надрукувати o назавжди?
Меттью Ро

Відповіді:


3

Код машини 6502 (C64), 90 89 91 байт

+2 байти, оскільки йому потрібна адреса завантаження (а не PIC через самомодифікацію)

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

Демонстрація в Інтернеті

Використання: sys49152

Я дуже намагався зменшити розмір (наприклад, НЕ використовуючи IRQ для синхронізації, але замість дурних порожніх циклів), все ж неможливо досягти рівня гольфу C64 BASIC Titus : о, ну. Але це виглядає менш мерехтливим;)

Пояснення: (віце-розбирання)

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

Для задоволення, ось більш професійний варіант використання спрайту для м'яча та миготіння межі при попаданні в 385 байт (містить дані спрайту, які використовуються на місці ):

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 

Демо - Інтернет - перегляд джерела асемблера ca65

Почніть і зупиніть підстрибуючий м'яч sys49152.

  • Це залишає роботу C64 BASIC, це робиться шляхом переміщення адресного простору VIC-II до $C000, що вимагає копіювання вмісту екрана та набору символів (шрифту).
  • Він підключається до системи IRQ і, щоб уникнути мерехтіння, змінює джерело цього IRQ на графічний чіп VIC-II, тому оновлення завжди проводяться між кадрами.
  • Глюки:
    1. RUN/STOP + RESTORE зламано, не намагайся.
    2. З VIC-II як джерелом IRQ курсор блимає трохи повільніше і TI$ також відставатиме.
    3. при зупинці, коли межа прошивається (дуже малоймовірно, але можливо), вона залишається білою - її потрібно відновити вручну.

1
Це не зовсім незалежно, чи не так? Я бачу два абсолютні ЛДА та два ДПА. Хоча велика робота!
Тит

Чорт ти маєш рацію: o Я забув самозмінення! Я оновлюсь, як тільки я стану на ПК.
Фелікс Палмен

1
@Titus виправлено ... і просто заради задоволення додав "кращий" варіант :)
Фелікс Палмен

Ви думали про упаковку спрайту? (Хм ... користуйся ROM- шаблоном ?) І я вважаю inc $d020за краще jsr flash;) Ударив себе , головний загін Це дивовижно!
Тит

1
@Titus врятував би 2 байти, так. Що стосується адреси завантаження, вона є частиною дійсного .prgфайлу, і з мого мета-питання тут я берусь, я повинен включити його ... можливо, міг би залишити його, якщо код не залежав від позиції.
Фелікс Палмен

14

Утиліти Bash + Unix, 125 117 байт

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 of sample run


6
Він потрапив у точний кут! : O
mbomb007

11

CP-1610 збірка, 6764 62 DECLE = 78 байт

Цей код призначений для запуску на Intellivision . Він використовує один зі своїх апаратних спрайтів, відомий як MOB (для мобільного об’єкта).

Опкод CP-1610 кодується з 10-бітовим значенням, відомим як "DECLE". Ця програма становить 62 DECLE, починаючи з $ 4800 і закінчуючи на $ 483D.

Шістнадцятковий дамп + джерело

                            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

Вихідні дані

output


10

HTML (Microsoft Edge / Internet Explorer), 81 байт

Притворіть 1998 рік із цими вкладеними <marquee>тегами:

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

Протестований у Microsoft Edge, хоча з того, що я читав, IE також повинен підтримувати схеми. Рішуче не працює в Chrome.

Налаштування direction=upдозволить заощадити 2 байти, але порушити правило, що м'яч повинен починатися вгорі полотна.


На жаль, це неправдива відповідь, оскільки м'яч не рухається по діагоналі, як того вимагає виклик.
El'endia Starman

Ви пробували це в Microsoft Edge? Схоже, Chrome не підтримує directionатрибут.
Джек Броунштейн

Так, вибачте - це працює в Edge. Я можу підтвердити, що він не працює в Chrome, і можу засвідчити, що він працює в Firefox та Internet Explorer. Три з чотирьох непогані (і для отримання відповіді вам потрібен лише один). +1
Старман Ельендії

1
+1 для marquee, це досить креативно!
Metoniem

Для мене працював у Chrome.
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

Досить дослівний переклад, я не здивуюсь, якщо є хитрощі, щоб зробити його меншим.

Екран 16x8 та 1-індексований, тому постійні різні.

~ є SourceCoder способом написання символу заперечення.

gif of bouncing O

На апаратному рівні це виглядає більш гладко.


Ви впевнені, що це 70 байт? Це виглядає менше, ніж це.
12Me21

@ 12Me21 скільки байтів ви рахуєте? Я отримую 80 байт, якщо я зберігаю це на калькуляторі та 10 байт для порожньої програми, яка погоджується з моїм рахунком.
Гарольд

О, я думаю, я тоді порахував неправильно.
12Me21

7

Befunge, 209 байт

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

Це передбачає розмір екрана 80x25, але ви можете легко налаштувати діапазон, замінивши "O"(79) на останньому рядку та *64(24) на другому останньому рядку (зауважте, що другий останній рядок виконується праворуч ліворуч). Швидкість можна також регулювати, замінивши "2"(50) в останньому рядку.


7

Java, 184 176 байт

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

Для цього використовується ANSI Escape Sequences для переміщення курсору, який є об'єктом, який підстрибує навколо 85 x 25дисплея терміналу. Збережіть у файлі з назвоюA.java .

Безумовно

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

Демо

Example


Це код гольфу, тому його потрібно буде видалити Thread.sleep(50). А ваші програми для гольфу та негромадян не відповідають.
Якоб

4

Clojure, 398 380 375 байт

(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 байт, змінивши ім'я шрифту в порожній рядок за замовчуванням, вклавши граничні чеки та виправляючи нижню межу (що ви можете побачити в GIF). Виправлення фактично збережених байтів.

-5 байт, змінивши на ситніший синтаксис руйнування і зменшивши кулю пікселем.

Використовує Quil .

Я намагався перейти у функціональний режим, але це вимагало багато додаткового коду і в кінцевому підсумку було дорожче.

(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

(Зауважте, нова версія не відскакує рано внизу екрану, як це робиться в GIF.)


Я щойно зрозумів, що маю (+ 0 font-size)там. Це бентежно. Я це виправлю в наступній версії. Слід врятувати мене, як 5 байт.
Carcigenicate

4

Ракетка 247 байт

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

Безголівки:

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

Вихід:

enter image description here


1
Гра в ракетбол з Ракеткою!
ckjbgames

Це добре!
rnso

"Ракетка" походить від мови програмування "Схема": після схеми (хитрого плану) з'являється Ракетка (афера або шахрайство)!
rnso

@mso Ще краще!
ckjbgames

3

Желе, 37 байт

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

З деякою допомогою цієї відповіді для отримання правильного циклу та втечі символів. В даний час він відскакує на екрані розміром 80x24, але це можна легко змінити в коді.

Координати в кожному напрямку можуть бути представлені як елементи двох списків [0, 1,..., 24, 23,..., 1]і [0, 1,..., 80, 79,..., 1], назвемо їх, Yі Xякі нескінченно повторюються. Це нескінченне повторення можна імітувати за допомогою модульної індексації - використовуючи в Jelly. Приклад: в iітерації м'яч знаходиться в положенні (X[i%|X|], Y[i%|Y|]) = (iịY, iịX). Рухомий м'яч - це просто курсор, який ставиться на місце, випромінюючи iịYнові рядки та iịXпробіли.

Демо

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

Пояснення

“ñ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 байт

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

Положення кулі можна змоделювати за допомогою двох трикутних хвиль, і найкоротшим способом, який я міг би знайти для них у SmileBASIC, був дуга (синус (x)). (алгоритм використання MOD був довшим, оскільки SB використовує MODзамість %)


2

CSS / HTML, 200 + 7 = 207 байт

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

Ця версія показує вам розмір полотна, а також надає анімації більш пікселізоване відчуття:


2

Діалог APL, 44 байти

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

Пояснення:

  • {... }⍨1 1: викликати задану функцію за допомогою ⍺ = ⍵ = 1 1
    • ⎕SM∘←0,G←⍺+⍵: Магазин ⍺+⍵в G, відобразити 0в цьому місці в⎕SM вікні.
    • ⎕DL.1: зачекайте 1/10 секунди
    • ⊃1 G∨.≥G⎕SDПеревірте, Gзнаходиться на ⎕SMкордоні вікна ( 1≥Gабо G≥⎕SD, ⎕SDє s Creen d imensions)
    • 1-2×: карта [1,0]на[¯1,1] , щоб перевернути напрямок руху
    • ⍵×: помножте поточний напрямок руху на це
    • G∇: рекурсія, нехай Gбуде нове місце ( ) та ⍵....буде новий напрямок ( ).

Це повинно бути постійно відкривати та закривати термінали під час роботи? Це досить важко зупинити це від запуску після його запуску, оскільки термінал закривається і знову відкривається кожні десяту частину секунди (принаймні в Windows).
рен

1
@wptreanor: фіксований
Мерінус

класно, відмінна робота!
рен

2

PHP, 112 97 94 103 102 байт

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

відскакує капітал Oна сітці розміром 40х25, починаючи з правого верхнього кута;
друкує 99 нових рядків, щоб очистити екран.

Бігайте з -nr.

A^K= chr(10)= новий рядок
A^a= chr(32)= пробіл


1
Привіт Титу, це я знову. 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);. Модуль помилковий при 0 і N і повертає напрямок. На жаль, ми маємо закликати $ d і $ e до -1, але все-таки отримуємо певні заощадження. $x%79<=>.5також працює для тих же байтів.
Крістоф

1
Привіт @Christoph ласкаво просимо назад. Дивно: коли я копіював ваш матеріал, він мав 116 байт замість 110. Але це надихнуло мене на щось набагато коротше.
Тіт

Ми, безумовно, хороша команда;) Дивна річ у копіюванні, я не маю поняття, чому.
Крістоф

2

Simons BASIC (C64), 66 65 байт

Один байт збережено завдяки @ShaunBebbers.

Тут мені потрібен лише один рядок, тому що Simons´ Basic має модульну функцію.
Для AfaIk для цього потрібен фізичний C64 та модуль BASIC Simons
(або будь-яке інше розширення BASIC, яке має modфункцію).

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

Введіть ці 69 символів:

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

{CLR}є PETSCII 147, який очищає екран. Використовуйте Shift + CLR / HOME, щоб ввести його.

рахунковий рахунок

При збереженні на диск, він займає 65 байт, так як команди лексеми:
for, to, poke, abs, nextі gotoодин байт кожен; modзаймає два байти.
Це складає 59 байт коду плюс 4 байти для покажчиків і 2 байти для номера рядка.

Для довідки див. " Складання карти C64 та пошук" $800(Текст програми BASIC).
(Ви можете знайти область пам'яті відеоекрану за адресою$400 .)

зламатися

Програма циклічно Iвід 0 до 623 (= LCM 48 і 78 мінус 1). У петлі

  • екран очищений
  • I відображається відповідно до 39..0..38 24..0..23
  • і крапка (PETSCII 81) ставиться у відповідне місце у відеопам'яті
    (як це робить оригінальна програма).

Коли цикл виконаний, програма перезапускається, переходячи до рядка 0.

C64 BASIC, 77 76 байт

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

На жаль, мені потрібні два рядки, тому що навіть при всіх можливих скороченнях знадобиться 83 символи - занадто багато, щоб використовувати редактор рядків C64:

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

(Шестнадцятковий редактор міг би бути використаний для створення більш тривалого рядка - для цього було б 73 байти.)


1
Роздільники команд Commodore є :і ні;
Shaun Bebbers

1
Крім того, якщо ви почнете з нуля рядка, ви можете просто використовувати gotoу своїй gotogoto 0
дволінійній

Якщо ви хочете отримати більше команд у вашому списку C64 BASIC, введіть його в C128 в режимі 128, збережіть його на диску і завантажте його в режим C64, C128 за замовчуванням має обмеження 160 символів, щоб цей бар'єр можна було розбити використовуючи скорочення ключових слів Commodore
Shaun Bebbers

@ShaunBebbers приємно знати. Це було так довго. Я також хотів реалізувати це в машинному коді ... намагаючись резюмувати підпрограми ядра; не впевнений, коли мені потрібно створити резервну копію реєстрів; повний перелік ядра онлайн ; Я просто не можу витратити час, щоб копати далі. Ви хотіли б це завершити ?
Тит

Я збирався зробити MC-версію, хоча думаю, що подати її на власний виклик було б надто поблажливо навіть для мене. Найшвидшим способом було б записати байт безпосередньо на екран від $0400до $07e7; або використовувати спрайт. Використання Kernal з $ffd2(акумулятор виводу) спрацювало б так, як ви можете досить просто встановити позиції X і Y на курсорі (я не пам’ятаю виклик для цього), але, можливо, вам доведеться уникати останньої позиції символу, якщо це змусить лінійний канал.
Shaun Bebbers

1

Пітон 2, 176 168 байт

Це передбачає розмір терміналу 80x24. Однозначно не оптимально, але я новачок у гольфі, так так.

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)

Завдяки Р. Капу за те, що він запропонував x% 79 <1 замість x <1or x> 79 та ditto для y.


Ви можете зберегти кілька байтів, замінивши x<1or x>78на x%79<0і y<1or y>22на y%23<1.
Р. Кап

1

Rebol / Вид, 284 266 байт

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

Безголівки:

rebol []

p: 3x9     ;; starting position
d: [3 3]   ;; direction

view layout [
    b: box blue 99x99 effect [
        draw [
            circle p 2
        ]
    ]

    rate :0.01 feel [
        engage: func [f a e] [
            if a = 'time [
                case/all [
                    p/x < 2  [d/1: abs d/1]
                    p/y < 2  [d/2: abs d/2]
                    p/x > 98 [d/1: negate d/1]
                    p/y > 98 [d/2: negate d/2]
                ]
                p/x: p/x + d/1
                p/y: p/y + d/2
                show b
            ]
        ]
    ]
]

1

C 294 байт

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

Негольована версія:

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

  }   

}

Пояснення

  • Отже, щоб почати з цього, мені довелося потрапити graphics.hдо свого /usr/includeкаталогу. Тому я шукав і це те, що я знайшов. Це реалізація TurboC Graphics за допомогою SDL для Linux. Можна також використовувати OpenGL. У Windows, я думаю, він уже встановлений, не впевнений у MacOS.
  • void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);ініціалізує систему та переводить її у графічний режим, в цьому випадку графічний драйвер виявляється автоматично. Будь ласка, перейдіть за цим посиланням для отримання більш детальної інформації.
  • xі yє координатами, що визначають положення кулі.
  • aі bє прапорами, aвстановлюється в нуль, коли xзначення опускається нижче 60 іb встановлюється в нуль, колиy падає нижче 60.
  • Прапорці перемикаються, коли x іy перевищують граничні значення вікна, а координати відповідно скориговані.
  • Я поставив usleep так, щоб мій процесор не піддавався стресу.
  • closegraph()Щоб закрити вікно, зазвичай потрібно використовувати дзвінок. Але цього тут немає.

Повинно бути складений за допомогою прапора лінкера -lgraph

Він працює більш гладко на реальному обладнання. :)

Bouncing Red Ball


Чи потрібні заяви про імпорт для запуску цієї програми?
Kritixi Lithos

@KritixiLithos Так, сер; Оновлено! вам потрібно включити graphics.h. Ця відповідь askubuntu.com/questions/525051/… була корисною.
Абель Том

1

MATL , 42 байти

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

Для цього використовується екран та символ 70 × 16 O. Якщо ви зачекаєте кілька відскоків, ви побачите, як м'яч вдаряється в кут.

Спробуйте в MATL Online!

Розмір екрана можна легко змінити в коді. Відповідна частина -8E70 , яка штовхає 8, подвоює її і штовхає70 . Наприклад, для екрана розміром 80 × 25 замініть на 5W80, який натискає 5, квадратикує і натискає 80(або замінює 25 80, але для цього потрібен ще один байт).

Також додавання tD в кінці коду показує поточне положення в режимі реального часу (вертикальне, потім горизонтальне,1 1 лівий верхній). Наприклад, для 80×18екрана,

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

Спробуйте також!

Пояснення

Для цього використовується нескінченна петля. Позиція зберігається в буфері обмінуH як вектор 1 × 2, а напрямок зберігається у буфері обміну Iяк вектор 1 × 2 із записами1 або-1 .

Кожна ітерація очищає екран, визначає матрицю пробілів, пише an O відповідну позицію і відображає її. Потім положення та напрямок потрібно оновити.

Позиція 1заснована на основі, і таким чином краї екрану є 1максимальним розміром екрана. Отже, якщо розмір екрана модульної позиції дає 0або 1в першому, або в другому компонентах, це означає, що ми досягли відповідно вертикального чи горизонтального краю, цей компонент вектора напряму заперечується. Після цього новий напрямок додається до поточної позиції для отримання нової позиції.


1

Ось перелік 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

Приємний перший запис DrlB - ви можете включити кількість байтів. Я припускаю, що це буде працювати на будь-яких Speccy, включаючи машини 16K?
Shaun Bebbers

Привіт, це 201 байт, ви можете опустити перші 4 рядки, але тоді ви отримаєте просто підстрибуючий символ "а", але це заощадить 64 байти. Я спробую оптимізувати. Це взагалі нічого не
фантазує

Гаразд, мені вдалося скоротити його до 185, трохи ущільнивши лінії, не опускаючи графіку кулі. Це трохи менш читабельно, але це швидше.
DrIB

1

C + прокльони, 190 байт

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

Пояснення:

#include<curses.h>
w;h;x;y;d;
main(e)
{
    initscr();
    curs_set(0);
    getmaxyx(stdscr,h,w);

    // initialize distances to 1 (e is 1 when called without arguments)
    // wait for 1/5 second, then write space character at current pos
    for(d=e;;usleep(20000),mvaddch(y,x,32))
    {
        // advance current pos and write ball character (`0`)
        mvaddch(y+=d,x+=e,48);

        // check and change direction:
        if(!y||y>h-2)d=-d;
        if(!x||x>w-2)e=-e;

        // trigger output to screen:
        refresh();
    }
}

1

Lua ( LÖVE 2D ), 130 байт

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

Луа - це не найкраща мова, коли мова йде про код гольфу, але ось ви йдете! Варто згадати кілька моментів:

  • За замовчуванням розмір полотна становить 800 х 600. Його можна змінити у файлі конфігурації, але я не бачив обмежень щодо розміру, тому я залишив його таким, яким є.

  • love.draw()є функцією малювання LÖVE, і вона має заздалегідь задану назву. Альтернативні функції LÖVE, які можна було б використовувати, - love.update(dt)і love.run()- перша буде довше в байтах, а остання буде коротшою, так, але без вбудованого нескінченного циклу. Таким чином, draw()здається, тут найкраща наша ставка.

  • Вищеописана версія використовує love.graphics.pointsдля малювання кулі. Хоча коротше, я не впевнений, що це дозволено. Ось GIF, як він працює:

Animated screenshot - point

Як ви бачите (а може і не можете), на екрані рухається один піксель. Хоча це економить байти, це не найвищий результат.

Тому я зробив альтернативне 131 байтне рішення :

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

Цей використовується love.graphics.print- який друкує текст - і 0як куля, що робить його набагато більш помітним і привабливим.

Animated screenshot - zero


1

CHIP-8, 36 34 28 байт

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

Тут немає жодних фантазійних хитрощів ...

Потрібен інтерпретатор, який правильно малює спрайти (на кадрі може бути намальований лише один спрайт, що уповільнює програму достатньо, щоб ви могли її бачити).

Відео низької якості


0

ZX Spectrum BASIC - 179 байт

Ось вона просто трохи згущена. Це 179 байт з включеною графікою з кулькою

  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

Будь ласка, подивіться на розмітку, яка використовується для відповідей, також за допомогою символу, oабо O, можливо, ви зможете зберегти кілька байт у символічному списку; ви також можете редагувати попередні відповіді, коли ви вдосконалили рішення, а не повторно відповідали на те саме питання
Shaun Bebbers
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.