Código mais compacto para uma explosão simulada

13

Você pode escrever um programa que processa a exibição de um grupo de pixels que explodem separados (como em um mecanismo de partículas simples) e pode fazer isso em um número notavelmente pequeno de caracteres (pressionamentos de tecla)? (Lembre-se dos lemingues do jogo, quando esses caras explodiriam e seus pequenos pedaços de pixels se separariam.)

Alguém programou um sistema simples de partículas aqui como um esboço de processamento e é bastante robusto em comparação com o que eu acho que outros deveriam ser capazes de realizar se tentassem. Mas eu ficaria muito mais impressionado se alguém pudesse fazer o mesmo em c ++ e sdl, ou mesmo java ou c #.

Todd Hopkinson
fonte
2
"Linhas de código" é uma métrica que abre muita ambiguidade e certamente não é [code-golf] que é "número de caracteres" ou, às vezes, "número de bytes". Discussão relacionada sobre meta.
dmckee --- ex-moderador gatinho
4
BTW - A questão que levantei acima e a especificação bastante incompleta são coisas que poderiam ter sido úteis, discutindo isso com antecedência no bate - papo do Puzzle Lab ou no Sandbox na meta . Mas, em qualquer caso, seja bem-vindo ao CodeGolf.SE.
dmckee --- gatinho ex-moderador
Pergunta atualizada, substituiu LOC pelo número de caracteres.
Todd Hopkinson
1
sim, se você escrever C / C ++ / Java / C Qualquer derivado você poderia escrever um sistema operacional inteiro em uma linha de código
Nate Koppenhaver

Respostas:

13

Python, 245 caracteres

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)
Keith Randall
fonte
Não é uma explosão, mas definitivamente um +1 por brevidade!
Todd Hopkinson
10

C #, WPF - 1523

Não é terrivelmente sério; isso foi principalmente uma tentativa de realmente funcionar.

O que estou fazendo aqui é usar um ItemsControl (Menu, já que é mais curto) no WPF para exibir partículas via ligação de dados e modelagem. Um modelo de dados controla a aparência das partículas (neste caso, um círculo simples) e a ligação de dados controla a cor e a posição das partículas.

Cada partícula tem uma posição, uma cor e uma direção que são atualizadas por um temporizador. Inicialmente, um monte de partículas é gerado no centro da janela com direções aleatórias (distribuídas normalmente). Essa coleção obtém dados vinculados ao ItemsControl, que manipula a exibição automática das partículas, sempre que as propriedades são atualizadas. As partículas são arrastadas um pouco devido à gravidade.

Ficou um pouco demorado, é verdade. Mas pelo menos parece bom:

insira a descrição da imagem aqui

Certamente pode ser reduzido, omitindo:

  • gravidade, fazendo com que as partículas se expandam uniformemente para todos os lados;
  • a distribuição normal para os vetores iniciais, fazendo com que as partículas se expandam em uma caixa esparsa »;
  • a variação do brilho, deixando as partículas pretas.

Optei por não fazê-lo no interesse da estética. Esta solução é muito mais longa do que quase qualquer outra coisa, independentemente. A abordagem de vinculação e modelagem de dados pode ser elegante, mas também é bastante detalhada em comparação com a simples atualização de um bitmap. (Nota: reduzi para 1356 , deixando tudo de fora, mas parece horrível.)

O código é distribuído em três arquivos, fornecidos aqui em formato formatado para legibilidade:

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;
}
Joey
fonte
1
+1 Excelente exemplo! Muito parecido com aqueles clássicos e explosivos lemmings de dias passados. E acho que isso supera o código de processamento na pergunta inicial.
Todd Hopkinson
@icnivad: Eu tenho que admitir que o esboço de processamento (eu apenas olhei o resultado final, não o código) foi minha inspiração para a aparência.
Joey
Gah! Eu paro de jogar isso agora. Ele já possui alguns truques interessantes (como o PropertyChanged para todas as propriedades e apenas na última que está definida). Dado que comecei acima de 2000 caracteres, acho que uma redução de 500 caracteres não é tão ruim. Também ficou bastante lento agora. DispatcherTimer funciona muito melhor que o Timer, mas é muito mais longo. Talvez eu esteja tentado a portar isso para o Silverlight e executá-lo no meu telefone.
Joey
Eu acho que esse é o único a ser batido pela combinação de tamanho de código e qualidade estética da explosão.
Todd Hopkinson
icnivad: Vou reescrever a coisa toda para pintar diretamente em um bitmap mais tarde; deve ser muito menor, então. 45% do código são XAML; uma grande parte do código é capaz de vincular elementos da interface do usuário às propriedades das partículas. Acrescente a isso a verbosidade geral do C # e é muito mais detalhada do que deveria ser.
Joey
7

postscript - 287 244 caracteres

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

correr com gs -dNOPAUSE asplode.ps

Você pode até imprimir e fazer um flipbook

Geoff Reedy
fonte
Maravilhoso! É lindo!
usuário desconhecido
5

Javascript - 268 caracteres

Aqui está uma explosão unidimensional, 2 partículas:

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)

Para executá-lo, abra uma página em branco sobre: ​​em um bom navegador, cole na barra de URL e pressione Enter. Você pode modificar a explosão editando os valores no final de s(10,5,1,0). O primeiro valor é o tamanho da partícula que é explodida. O segundo valor é o tamanho da partícula que é explodida. O terceiro valor é a velocidade da partícula explodida. Deixe o '0' como está.

david4dev
fonte
1
Isso não funciona no Safari 5.0.5 (mostra algo que se parece um pouco com um taco de beisebol) ou no Chrome 11.0.696.68 (mostra duas bolas, uma ligeiramente maior que a outra, se afastando lentamente).
Marinus
1
@ marinus, o que está acontecendo no Chrome é o que deveria estar acontecendo.
David4dev 13/05
Não é possível fazê-lo funcionar no FF4, IE8. :(
st0le
Bem, eu testei no Firefox 4.0.1 e no Chromium 11.0.696.65. Faça sue que você copiou o script inteiro - acho fácil perder o colchete final ao copiar.
David4dev 18/05
@ st0le IE8 não suporta a tela tag, a menos que você executar alguns truques sujos: stackoverflow.com/questions/1332501/...
Cristian Lupaşcu
4

APL ( 120 118)

Ele tem o mesmo tipo de saída que a entrada Python (ou seja, apenas gera os estados em uma grade de caracteres). Somente a grade é 30x15 e a origem das partículas é 15x7.

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

JavaScript 502 500 496

Esta é uma combinação das respostas de Joey e david4dev (é uma cópia vergonhosa do algoritmo de Joey implementado usando 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)

Visualização do JSFiddle: http://jsfiddle.net/GVqFr/60/ (você pode pressionar o botão TidyUp para formatar bem o código)

Cristian Lupascu
fonte
@Qqwy Obrigado pela edição!
Cristian Lupascu
Não sou especialista em javascript, mas você usa muito a constante 500. Se você pode definir uma variável global a=500, pode salvar alguns caracteres substituindo todos 500por a.
Mr. Llama
@GigaWatt você está certo; que funcionou 250também.
Cristian Lupascu
1

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

Ligue e como explodir.

atualização: colorida

t = texto, c = cls, g = gotoxi, f = mosca, C = COR

Usuário desconhecido
fonte
1

C com SDL, 423 caracteres

Como a descrição original do problema mencionou explicitamente SDL, senti que já era hora de enviar uma solução SDL. Infelizmente, os nomes das funções e estruturas SDL não são particularmente concisos, portanto esse programa é um pouco longo. Na verdade, eu não posso nem deixar de fora o #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);}}

(Como o código já é muito grande, deixei alguns bits extras para compilar sem avisos. Às vezes, sinto falta de compilar sem avisos. A remoção deles economizaria cerca de 30 caracteres.)

A animação é executada em um loop infinito. Feche a janela para sair do programa. Cada explosão usa um novo conjunto de partículas aleatórias.

Eu também gostaria de apontar o número 67372036no código. Ele aparece na expressão do último argumento na segunda chamada para SDL_FillRect(). Como o código está, a explosão é renderizada inteiramente em cinza. Alterar esse número levemente adicionará um efeito de cor muito sutil, mas agradável à explosão. O número 67372032colore as partículas no início da explosão, enquanto o número 67372034fornece um efeito de cor à medida que desaparecem no final. Outros números podem produzir efeitos menos sutis do ciclo de cores. Convido você a experimentá-los.

caixa de pão
fonte
1

Depois de ver alguns dos outros ótimos exemplos aqui, decidi tentar e criar uma função de partícula que se encaixa em 140byt.es

Javascript, 282 caracteres

( Função de partículas de 138 caracteres e padrão de desenho básico em tela de 150 caracteres)

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

Exemplo ao vivo do JSFiddle aqui

Ao tornar o código totalmente processual, não era mais necessário nenhum código de matriz ou de atribuição de objeto, reduzindo muito o tamanho. Fazer um efeito processual também tem outros efeitos colaterais interessantes.

O código pode ser reduzido omitindo Gravidade, Sementes, Número de Partículas, etc., mas acho que esses recursos são bons demais para serem removidos;).

Recursos

  • Centro de explosão X, Y configurável.
  • Número configurável de partículas
  • Gravidade na direção vertical: faça com que suas partículas caiam ou voem!
  • Semente, cada semente tem sua própria explosão e mostrará exatamente essa explosão a cada vez, nos computadores.
  • Movimento lento, avanço rápido e reprodução de explosões para trás são possíveis, devido à maneira processual em que o efeito é criado.
  • Tamanho: 138 bytes.

Também confira no GitHub , para uma versão anotada.

Qqwy
fonte
0

Python com PyGame, 240 caracteres

Percebo que já existe uma solução em python, mas como essa apenas imprime caracteres, pensei que valeria a pena fazer uma que desenhe uma boa animação.

Ungolfed, o que eu comecei com:

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

Depois de muito hackery. Tela cheia para salvar alguns caracteres. Não usando som ou fontes, por isso acho init()desnecessário (funciona para mim).

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)
Sem noção
fonte
0

Python - 327 caracteres

Coisas interessantes:

  • Use número complexo como vetor 2D
  • (v * cos(a), v * sin(a)) implementado como v*e**(1j*a)
  • Parece uma explosão 3D.
  • Gravidade.

.

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)
Raio
fonte
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)})

experimente copiar / colar o código em dwitter.net

não brilhante
fonte
Quando o idioma pós-data do desafio, você deve marcá-lo como não competitivo.
16163