Найбільш компактний код для імітаційного вибуху


13

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

Хтось запрограмував тут просту систему частинок як ескіз обробки, і це досить здоровенно порівняно з тим, що, на мою думку, повинні бути спроможні виконати інші, якщо вони спробували. Але я був би дуже вражений, якби це хтось міг зробити те ж саме в c ++ і sdl, або навіть java чи c #.


2
"Рядок коду" - це показник, який відкриває багато неоднозначності, і це, звичайно, не [код-гольф], який є "число символів" або іноді "кількість байтів". Пов’язана дискусія з мета.
dmckee --- колишнє кошеня-модератор

4
BTW - Проблему, яку я піднімав вище, і досить неповну специфікацію - це речі, які можна було б корисно усунути, обговоривши це заздалегідь у чаті «Лабораторії головоломки» або « Пісочниці» на мета . Але, у будь-якому випадку, ласкаво просимо до CodeGolf.SE.
dmckee --- кошеня колишнього модератора

Оновлено запитання, замінив LOC кількістю символів.
Тодд Хопкінсон

1
так, якщо ви пишете C / C ++ / Java / будь-яку похідну C, ви можете написати всю ОС у 1 рядку коду
Nate Koppenhaver

Відповіді:


13

Пітон, 245 символів

import random,time
R=lambda:random.randrange(-999,999)/1e3
P=[(40+20j,R()+1j*R())for i in' '*20]
for i in' '*20:
 C=([' ']*80+['\n'])*40
 for p,v in P:C[int(p.real)+81*int(p.imag)]='*'
 print''.join(C);P=[(p+v,v*.95)for p,v in P];time.sleep(.1)

Це не вибух лемінгів, але, безумовно, +1 для стислості!
Тодд Хопкінсон

10

C #, WPF - 1523

Не страшенно серйозно; це була головним чином спроба, чи справді це спрацювало.

Що я тут роблю, - це використовувати ItemControl (меню, оскільки він коротший) у WPF для відображення частинок за допомогою прив'язки даних та шаблонів. Шаблон даних керує тим, як виглядають частинки (в даному випадку просте коло), а зв'язування даних контролює колір і положення частинок.

Кожна частинка має положення, колір та напрямок, які оновлюються таймером. Спочатку купа частинок утворюється в центрі вікна з (нормально розподіленими) випадковими напрямками. Ця колекція прив'язується до даних ItemControl, яка потім обробляє відображення частинок автоматично, щоразу, коли властивості оновлюються. Частинки трохи тягнуться вниз через гравітацію.

Це, правда, стало трохи довше. Але принаймні це виглядає приємно:

введіть тут опис зображення

Це, безумовно, можна скоротити, опустивши:

  • сила тяжіння, внаслідок чого частинки рівномірно розширюються на всі сторони;
  • нормальний розподіл для початкових векторів, внаслідок чого частинки розширюються в розрідженому «ящику»;
  • зміна яскравості, залишаючи частинки чорними.

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

Код розподіляється у трьох файлах, які тут надаються у форматованому вигляді для розбірливості:

App.xaml

<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" StartupUri="W.xaml"/>

W.xaml

<Window x:Class="W" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Menu Name="i">
        <Menu.ItemTemplate>
            <DataTemplate>
                <Ellipse Width="2" Height="2" Fill="#000" Opacity="{Binding O}">
                    <Ellipse.RenderTransform>
                        <TranslateTransform X="{Binding X}" Y="{Binding Y}"/>
                    </Ellipse.RenderTransform>
                </Ellipse>
            </DataTemplate>
        </Menu.ItemTemplate>
        <Menu.Template>
            <ControlTemplate>
                <ItemsPresenter/>
            </ControlTemplate>
        </Menu.Template>
        <Menu.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </Menu.ItemsPanel>
    </Menu>
</Window>

W.xaml.cs

using M = System.Math;
using T = System.Timers.Timer;
using System;
using System.ComponentModel;

partial class W
{
    int a;
    T t = new T(99);

    public W()
    {
        InitializeComponent();
        Height = Width = 500;
        var r = new Random();
        Func<double> n = () => 2 * (M.Sqrt(-2 * M.Log(r.NextDouble())) * M.Sin(6 * r.NextDouble()));
        var l = new System.Collections.Generic.List<P>();
        for (; a++ < 300; )
            l.Add(new P { X = 250, Y = 250, f = n(), g = n() });
        i.ItemsSource = l;
        t.Elapsed += delegate
        {
            foreach (P x in l)
            {
                x.X += x.f;
                x.Y += x.g += .2;
                x.O = M.Max(1 - M.Sqrt(M.Pow(250 - x.X, 2) + M.Pow(250 - x.Y, 2)) / 250, 0);
            }
        };
        t.Start();
    }
}

class P : System.Windows.ContentElement, INotifyPropertyChanged
{
    public double y, f, g;
    public double X { get; set; }
    public double O { get; set; }
    public double Y
    {
        get { return y; }
        set
        {
            y = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(""));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

1
+1 Чудовий приклад! Так само, як і класичні вибухові лемінги минулих днів. І я думаю, що це перемагає код обробки в початковому запитанні.
Тодд Хопкінсон

@icnivad: Я мушу визнати, що ескіз «Обробка» (я дивився лише на кінцевий результат, а не на код) був моїм натхненням для зовнішнього вигляду.
Joey

Гах! Я зараз перестаю займатися гольфом. Наразі в ньому є кілька приємних хитрощів (наприклад, PropertyChanged для всіх властивостей і лише для останнього, який встановлено). Зважаючи на те, що я почав перевищувати 2000 символів, я думаю, що зменшення на 500 знаків не надто погано. Це також стало досить повільним. DispatcherTimer працює набагато краще, ніж Таймер, але набагато довше. Можливо, я б спокусився перенести це в Silverlight і запустити його на своєму телефоні.
Joey

Я думаю, що це саме те, що потрібно перемогти за поєднання розміру коду та естетичної якості вибуху.
Тодд Хопкінсон

icnivad: пізніше переписатиму все, щоб намалювати прямо на растровій карті; значить, це повинно бути набагато коротше. 45% коду - XAML; значна частина коду полягає в можливості прив'язувати елементи інтерфейсу до властивостей частинок. Додайте до цього загальну багатослівність C #, і це набагато більш багатослівно, ніж потрібно.
Joey

7

постскрипт - 287 244 символів

currentpagedevice/q{exch def}def/PageSize get/z{dup 3 1 roll add exch 4 2 roll}def{2
div}forall/y/r{rand 2 27 exp div 8 sub}def q/x q[99{[x r y r]}repeat]50{dup{aload/t q
3 index 2 index 4 4 rectfill 1 sub z z t astore pop}forall showpage}repeat

бігати з gs -dNOPAUSE asplode.ps

Можна навіть роздрукувати його і зробити фліпбук


Чудово! Це красиво!
користувач невідомий

5

Javascript - 268 символів

Ось 1 розмірний, 2 частинка, вибух:

javascript:d=document;c=d.createElement('canvas');d.body.appendChild(c);g=c.getContext("2d");function e(x,y,m){g.arc(x,y,m,0,2*Math.PI,false);g.fill()}function s(a,b,v,t){c.width=c.width;e(50+t*v,50,b);e(50+t*b*v/(b-a),50,a-b);setTimeout(function(){s(a,b,v,t+1)},100)};s(9,5,1,0)

Щоб запустити його, відкрийте приблизно: порожню сторінку в хорошому веб-переглядачі, вставте в рядок URL-адреси і натисніть клавішу Enter. Ви можете змінити вибух, відредагувавши значення в кінці в s(10,5,1,0). Перше значення - розмір вибуханої частинки. Друге значення - це розмір частинки, яка вибухає з неї. Третє значення - швидкість вибухнула з нього частинки. Залиште "0" як є.


1
Це не працює в Safari 5.0.5 (показує щось, що трохи схоже на бейсбольну биту) або в Chrome 11.0.696.68 (показує два кульки, один трохи більший за інший, повільно рухаючись один від одного).
Марина

1
@marinus те, що відбувається в Chrome, те, що повинно відбуватися.
david4dev

Не можу змусити його працювати на FF4, IE8. :(
st0le

Добре я тестував його на Firefox 4.0.1 та Chromium 11.0.696.65. Зробіть позов, ви скопіювали весь сценарій - я можу легко пропустити кінцеву дужку при копіюванні.
david4dev

@ st0le IE8 не підтримує тег полотна , якщо ви не виконаєте брудні хитрощі: stackoverflow.com/questions/1332501/…
Крістіан Лупаску

4

APL ( 120 118)

Він має такий же вихід, як і запис Python (тобто він просто видає стани в символьній сітці). Тільки сітка 30х15, а початок частинок - 15х7.

⍎⊃,⌿(9⍴⊂'(⎕DL.1)⊢{{(A+2↑⍵),0.95×A←2↓⍵}¨⍵⊣⎕←'' ⍟''[1+(⍳15 30)∊2↑¨⌊⍵]}'),⊂',⌿⍉10 4⍴⍎''⍬'',420⍴'',(7 15,.01×99-?2⍴199)'''

2

JavaScript 502 500 496

Це поєднання відповідей Джої та david4dev (це безсоромна копія алгоритму Джої, реалізованого за допомогою Javascript / canvas ☺):

W=500;H=250;function r(){return 2*m.sqrt(-2*m.log(m.random()))*m.sin(6*m.random())}function n(){z=[];for(i=W;i;i--){s={};s.x=s.y=H;s.f=r();s.g=r();z.push(s)}}function w(){x.clearRect(0,0,W,W);z.forEach(function(a){a.x+=a.f;a.y+=a.g+=.2;x.fillStyle="rgba(0,0,0,"+m.max(1-m.sqrt(m.pow(H-a.x,2)+m.pow(H-a.y,2))/H,0)+")";x.fillRect(a.x,a.y,2,2)})}z=[];m=Math;d=document;c=d.createElement("canvas");c.width=c.height=W;d.body.appendChild(c);x=c.getContext("2d");n();setInterval(n,2e3);setInterval(w,10)

Попередній перегляд JSFiddle: http://jsfiddle.net/GVqFr/60/ (ви можете натиснути кнопку TidyUp, щоб добре відформатувати код)


@Qqwy Дякую за редагування!
Крістіан Лупаску

Я не експерт по JavaScript, але ви використовуєте константу 500дуже багато. Якщо ви можете визначити глобальну змінну a=500, ви можете зберегти кілька символів, замінивши всі 500на a.
Містер Лама

@GigaWatt ви праві; що також працювало 250.
Крістіан Лупаску

1

Баш 380

C="4443311177"
t=".-xxXMXxx-."
alias c='echo -e "\e[2J"'
g(){
echo -e "\e[1;$4\e[$2;$1H$3"
}
f(){
x=$1
y=$2
p=$((2-RANDOM%5))
q=$((2-RANDOM%5))
for i in {-5..5}
do
x=$((x+p))
y=$((y+q))
n=$((5+i))
c=$((5+i))
g $x $y ${t:n:1} 3${C:c:1}m 
w=$(printf "%04i\n" $((5*i*i)))
sleep ${w/0/0.}
g $x $y " " 3${C:c:1}m
done
}
e(){
c
for i in {1..10}
do
f $((COLUMNS/2)) $((LINES/2)) &
done
}

Виклик е як вибухнути.

оновлення: кольорова

t = текст, c = cls, g = gotoxy, f = fly, C = COLOR


1

C з SDL, 423 символів

Оскільки в первинному описі проблеми чітко згадувалося про SDL, я вважав, що минулий час було подано рішення про SDL. На жаль, назви функції та структури SDL не особливо стислі, тому ця програма трохи довга. Насправді я навіть не можу залишити це #include.

#include<math.h>
#include"SDL.h"
SDL_Surface*s;SDL_Event e;SDL_Rect p;int i,n;double q[256];main(){
SDL_Init(SDL_INIT_VIDEO);s=SDL_SetVideoMode(320,320,32,0);
for(srand(time(0));e.type-SDL_QUIT;n=-~n%64){
for(i=256*!n;i;q[--i]=rand()%65536*9.5874e-5);
for(SDL_FillRect(s,0,i=0);++i<256;SDL_FillRect(s,&p,-n*67372036))
p.x=160+cos(q[i])*q[i-1]*n,p.y=160+sin(q[i])*q[i-1]*n,p.w=p.h=1;
SDL_Flip(s);SDL_Delay(50);SDL_PollEvent(&e);}}

(Оскільки код вже настільки величезний, я залишив кілька зайвих бітів, щоб він збирався без попереджень. Я інколи пропускаю компіляцію без попереджень. Видалення їх дозволить заощадити приблизно 30 або більше символів.)

Анімація працює в нескінченному циклі. Закрийте вікно, щоб вийти з програми. Кожен вибух використовує новий набір випадкових частинок.

Я також хотів би зазначити номер 67372036у коді. Він з'являється у виразі для останнього аргументу у другому виклику до SDL_FillRect(). За кодом, вибух виводиться повністю в сірі. Злегка змінивши це число, додасть вибуху дуже тонкий, але приємний кольоровий ефект. Кількість 67372032забарвлює частинки на початку вибуху, а кількість 67372034забезпечує кольоровий ефект, коли вони зникають в кінці. Інші цифри можуть створювати менш тонкі кольоротворчі ефекти. Я закликаю вас спробувати їх.


1

Побачивши кілька інших чудових прикладів тут, я вирішив перейти і зробити функцію частинок, яка відповідає 140byt.es

Javascript, 282 символів

( 138 символів функцій частинок і 150 символів основного полотна для нанесення котла)

p=function(a,t,x,y,n,g,s,i,d){with(Math)for(i=n;i--;d=cos(i*sin(i*s)),a.globalAlpha=n/t/i,a.fillRect(x+t*sin(i)*d, y+t*cos(i)*d+t*g,2,2));};d=document;a=d.body.appendChild(d.createElement('canvas')).getContext('2d');t=setInterval("a.clearRect(0,0,300,150);p(a,t++, 50,50,1e3,.2,1)")

Тут є приклад JSFiddle

Здійснюючи код повністю процедурним, мені більше не потрібен жоден масив чи код присвоєння об'єктів, значно зменшуючи розмір. Здійснення процесуального ефекту також має деякі інші приємні побічні ефекти.

Код можна зменшити, опустивши гравітацію, насіння, кількість частинок тощо, але я думаю, що ці функції занадто приємно видаляти;).

Особливості

  • Конфігурується X, Y центр вибуху.
  • Налаштована кількість частинок
  • Гравітація у вертикальному напрямку: Нехай ваші частинки падають або летять вгору!
  • Насіннєве кожне насіння має свій власний вибух і щоразу показуватиме такий вибух на комп’ютерах.
  • Уповільнення, швидке перемотування вперед та грати вибухи Назад - це все можливо, завдяки процедурному способу створення ефекту.
  • Розмір: 138 байт.

Також перевірте це на GitHub , для коментованої версії.


0

Python з PyGame, 240 символів

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

Незайманий, з чого я почав:

import math
import random
import pygame
pygame.init()

screen = pygame.display.set_mode((800, 800))
particles = [(random.gauss(0,.5), random.uniform(0,6.28318)) for i in range(2000)]

for i in range(399):
    screen.fill((255,255,255))
    for speed, angle in particles:
        distance = i * speed
        x = 400 + distance * math.cos(angle)
        y = 400 + distance * math.sin(angle)
        screen.set_at((int(x), int(y)), (0,0,0))
    pygame.display.flip()

Після багато хакерства. Повноекранний режим для збереження деяких символів. Не використовуйте звук чи шрифти, тому я вважаю init()зайвим (це працює на мене).

import math as m,random,pygame
d,x,g=pygame.display,range(999),random.gauss
s,e=d.set_mode(),[(g(0,.2),g(0,9))for i in x]
for i in x:
 d.flip(),s.fill([255]*3)
 for v,a in e:
        y=400+i*v*m.cos(a),400+i*v*m.sin(a)
        s.set_at(map(int,y),[0]*3)

0

Пітон - 327 символів

Цікаві речі:

  • Використовуйте комплексне число як 2D-вектор
  • (v * cos(a), v * sin(a)) реалізований як v*e**(1j*a)
  • Схоже на 3D-вибух.
  • Гравітація.

.

import pygame as P,random as R,math
R=R.random
D=P.display
D.init()
W=800
S=D.set_mode((W,W))
T=P.time.Clock()
C=lambda v:map(int,(v.real,v.imag))
X=[(8+R())*math.cos(R()*1.57)*2.7**(1j*R()*6.28) for i in range(999)]
for t in range(250):
 D.flip();T.tick(30);S.fill(2**24-1)
 for v in X:S.set_at(C(v*t+.005j*t*t+W/2*(1+1j)),0)

0

dwitter 112

c.width^=0
t?o.push({X:1e3,Y:500,U:S(99*t),V:C(9*t)}):o=[]
o.map(a=>{a.X+=a.U,a.Y+=a.V,x.fillRect(a.X,a.Y,9,9)})

спробуйте скопіювати / вставити код на dwitter.net


Коли мова відкладає виклик, ви повинні відзначити її як неконкурентну.
fəˈnɛtɪk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.