Самый компактный код для имитации взрыва

13

Можете ли вы написать программу, которая отображает группу пикселей, взрывающихся друг от друга (как в простом механизме частиц), и можете ли вы сделать это с любым удивительно небольшим количеством символов (нажатий клавиш)? (Вспомните игровые лемминги, когда эти маленькие парни взорвутся и их маленькие пиксельные кусочки разлетятся.)

Кто-то запрограммировал здесь простую систему частиц как скетч- процессинг, и это довольно дорого по сравнению с тем, что, на мой взгляд, должны быть в состоянии выполнить другие, если они попытаются. Но я был бы гораздо более впечатлен, если бы кто-то мог сделать то же самое в c ++ и sdl, или даже в java или c #.

Тодд хопкинсон
источник
2
«Строки кода» - это метрика, которая открывает много неоднозначности и, безусловно, не является «кодом-гольфом», который представляет собой «количество символов» или иногда «количество байтов». Связанное обсуждение по мета.
dmckee --- котенок экс-модератора
4
Кстати, вопрос, который я поднял выше, и довольно неполная спецификация - это вещи, которые можно было бы с пользой решить, обсудив это заранее в чате Puzzle Lab или в Песочнице на мета . Но, в любом случае, добро пожаловать в CodeGolf.SE.
dmckee --- котенок экс-модератора
Обновлен вопрос, заменен LOC на количество символов.
Тодд Хопкинсон
1
да, если вы напишите C / C ++ / Java / Any производную C, вы можете написать целую ОС в одной строке кода
Nate Koppenhaver
Связанный: stackoverflow.com/questions/1947031/…
gnibbler

Ответы:

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

Не очень серьезно; это была в основном попытка, работало ли это на самом деле.

Здесь я использую ItemsControl (Menu, поскольку он короче) в WPF для отображения частиц с помощью привязки данных и шаблонов. Шаблон данных контролирует, как выглядят частицы (в данном случае простой круг), а привязка данных контролирует цвет и положение частиц.

Каждая частица имеет позицию, цвет и направление, которые обновляются таймером. Первоначально группа частиц генерируется в центре окна с (нормально распределенными) случайными направлениями. Эта коллекция получает привязку к данным для ItemsControl, который затем автоматически обрабатывает отображение частиц при каждом обновлении свойств. Частицы тянутся вниз под действием силы тяжести.

Это стало немного длинным, по общему признанию. Но, по крайней мере, это выглядит красиво:

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

Конечно, это можно сделать короче, пропустив:

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

Я решил не делать этого в интересах эстетики. Это решение намного дольше, чем все остальное, независимо от того, Подход к привязке данных и шаблонам может быть элегантным, но он также довольно многословен по сравнению с простым обновлением растрового изображения. (Примечание: я сократил его до 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: Я должен признать, что эскиз Обработки (я только посмотрел на конечный результат, а не код) был моим вдохновением для внешнего вида.
Джои
Г! Я перестаю играть в гольф сейчас. На данный момент в нем есть несколько приятных трюков (например, PropertyChanged для всех свойств и только для последнего установленного). Учитывая, что я начал с более чем 2000 символов, я думаю, что сокращение на 500 символов не так уж и плохо. Это также стало довольно медленным к настоящему времени. DispatcherTimer работает намного лучше, чем Timer, но намного дольше. Я мог бы испытать желание портировать это на Silverlight и запустить его на моем телефоне, хотя.
Джои
Я думаю, что это то, что нужно для комбинации размера кода и эстетического качества взрыва.
Тодд Хопкинсон
icnivad: позже я перепишу все это, чтобы рисовать прямо на растровом изображении; тогда оно должно быть намного короче. 45% кода XAML; большая часть кода становится способной связывать элементы пользовательского интерфейса со свойствами частиц. Добавьте к этому общую многословность C #, и это будет гораздо более многословно, чем нужно.
Джои
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-мерный взрыв из двух частиц:

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)

Чтобы запустить его, откройте пустую страницу about: в хорошем веб-браузере, вставьте ее в строку URL и нажмите enter. Вы можете изменить взрыв, отредактировав значения в конце в s(10,5,1,0). Первое значение - это размер взорвавшейся частицы. Второе значение - размер взорвавшейся частицы. Третье значение - это скорость взорвавшейся частицы. Оставьте «0» как есть.

david4dev
источник
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 не поддерживает тег canvas , если вы не выполните некоторые грязные трюки: stackoverflow.com/questions/1332501/…
Кристиан Лупаску
4

APL ( 120 118)

Он имеет тот же тип вывода, что и запись Python (то есть он просто выводит состояния в таблице символов). Только сетка 30x15, а источник частиц - 15x7.

⍎⊃,⌿(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

Это комбинация ответов Joey и david4dev (это бесстыдная копия алгоритма Joey, реализованного с использованием 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 = цвет

Пользователь неизвестен
источник
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 здесь

Делая код полностью процедурным, я больше не нуждался в массиве или коде назначения объекта, что значительно уменьшало размер. Создание процедурного эффекта также имеет некоторые другие приятные побочные эффекты.

Код можно сделать меньше, пропустив Gravity, Seeds, Number of Particles и т. Д., Но я думаю, что эти функции слишком хороши для удаления;).

Характеристики

  • Конфигурируемый X, Y центр взрыва.
  • Конфигурируемое количество частиц
  • Гравитация в вертикальном направлении: ваши частицы падают или взлетают!
  • Посеянное семя, каждое семя имеет свой собственный взрыв и каждый раз будет показывать именно этот взрыв на компьютерах.
  • Замедленное движение, быстрая перемотка вперед и игра взрывами Все назад возможно, благодаря процедурному способу создания эффекта.
  • Размер: 138 байт.

Также проверьте это на GitHub , для аннотированной версии.

Qqwy
источник
0

Питон с PyGame, 240 символов

Я понимаю, что в python уже есть решение, но так как оно просто печатает символы, я подумал, что было бы целесообразно создать такое, которое рисует хорошую анимацию.

Ungolfed, с чего я начал:

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

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