El código más compacto para una explosión simulada

13

¿Puede escribir un programa que muestre un grupo de píxeles que explotan (como en un motor de partículas simple) y puede hacerlo en cualquier número notablemente pequeño de caracteres (pulsaciones de teclas)? (Recordemos los lemmings del juego, cuando esos pequeños muchachos explotaban y sus pequeñas piezas de píxeles se separaban).

Alguien programó un sistema de partículas simple aquí como un boceto de procesamiento y es bastante considerable en comparación con lo que creo que otros deberían poder lograr si lo intentaran. Pero estaría mucho más impresionado si alguien pudiera hacer lo mismo en c ++ y sdl, o incluso en java o c #.

Todd Hopkinson
fuente
2
"Líneas de código" es una métrica que abre mucha ambigüedad, y ciertamente no es [code-golf], que es "número de caracteres" o, a veces, "número de bytes". Discusión relacionada sobre meta.
dmckee --- ex-gatito moderador
44
Por cierto, el problema que mencioné anteriormente, y la especificación bastante incompleta son cosas que podrían haberse solucionado útilmente al discutir esto por adelantado en el chat de Puzzle Lab o en el Sandbox sobre meta . Pero, en cualquier caso, bienvenido a CodeGolf.SE.
dmckee --- ex gatito moderador
Pregunta actualizada, reemplazada LOC por número de caracteres.
Todd Hopkinson
1
sí, si escribes C / C ++ / Java / Any C derivado podrías escribir un sistema operativo completo en 1 línea de código
Nate Koppenhaver

Respuestas:

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
fuente
No es una explosión lemming, ¡pero definitivamente un +1 por brevedad!
Todd Hopkinson
10

C #, WPF - 1523

No terriblemente serio; esto fue principalmente un intento de si realmente funcionó.

Lo que estoy haciendo aquí es usar un ItemsControl (Menú, ya que es más corto) en WPF para mostrar partículas a través de la vinculación de datos y la plantilla. Una plantilla de datos controla el aspecto de las partículas (en este caso, un círculo simple) y el enlace de datos controla el color y la posición de las partículas.

Cada partícula tiene una posición, un color y una dirección que se actualizan mediante un temporizador. Inicialmente, se generan un montón de partículas en el centro de la ventana con direcciones aleatorias (distribuidas normalmente). Esa colección se enlaza con los datos al ItemsControl que luego maneja la visualización de las partículas automáticamente, cada vez que se actualizan las propiedades. Las partículas se arrastran un poco hacia abajo debido a la gravedad.

Se hizo un poco largo, lo admito. Pero al menos se ve bien:

ingrese la descripción de la imagen aquí

Seguramente se puede acortar omitiendo:

  • gravedad, haciendo que las partículas se expandan uniformemente a todos los lados;
  • la distribución normal de los vectores iniciales, haciendo que las partículas se expandan en una escasa »caja«;
  • La variación del brillo, dejando partículas negras.

Opté por no hacerlo en interés de la estética. Sin embargo, esta solución es mucho más larga que casi cualquier otra cosa. El enfoque de vinculación de datos y plantillas puede ser elegante, pero también es bastante detallado en comparación con la simple actualización de un mapa de bits. (Nota: lo bajé a 1356 dejando todo lo anterior, pero se ve horrible entonces).

El código se distribuye en tres archivos, que se dan aquí en forma formateada para su legibilidad:

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
fuente
1
+1 ¡Un gran ejemplo! Al igual que esos clásicos lemmings de antaño. Y creo que esto supera el código de procesamiento en la pregunta inicial.
Todd Hopkinson
@icnivad: Tengo que admitir que el boceto de Processing (solo miré el resultado final, no el código) fue mi inspiración para el aspecto.
Joey
Gah! Dejo de jugar al golf ahora. Tiene algunos buenos trucos en este momento (como el PropertyChanged para todas las propiedades y solo en el último que está configurado). Dado que comencé con más de 2000 caracteres, supongo que una reducción de 500 caracteres no es tan mala. También se hizo bastante lento por ahora. DispatcherTimer funciona mucho mejor que Timer, pero es mucho más largo. Sin embargo, podría sentir la tentación de transferir esto a Silverlight y ejecutarlo en mi teléfono.
Joey
Creo que este es el mejor para la combinación del tamaño del código y la calidad estética de la explosión.
Todd Hopkinson
icnivad: Reescribiré todo para pintar directamente en un mapa de bits más tarde; debería ser mucho más corto, entonces. 45% del código son XAML; una gran parte del código se puede vincular a los elementos de la interfaz de usuario con las propiedades de las partículas. Agregue a eso la verbosidad general de C # y es mucho más detallado de lo que debería ser.
Joey
7

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

corre con gs -dNOPAUSE asplode.ps

Incluso podría imprimirlo y hacer un flipbook

Geoff Reedy
fuente
¡Maravilloso! ¡Es bonito!
usuario desconocido
5

Javascript - 268 caracteres

Aquí hay una explosión de 1 dimensión, 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 ejecutarlo, abra una página acerca de: en blanco en un buen navegador web, péguelo en la barra de direcciones y presione Entrar. Puede modificar la explosión editando los valores al final en s(10,5,1,0). El primer valor es el tamaño de la partícula que explota. El segundo valor es el tamaño de la partícula que se explota fuera de ella. El tercer valor es la velocidad de la partícula explotada. Deje el '0' como está.

david4dev
fuente
1
Esto no funciona en Safari 5.0.5 (muestra algo que se parece un poco a un bate de béisbol) o en Chrome 11.0.696.68 (muestra dos bolas, una ligeramente más grande que la otra, que se separan lentamente).
Marinus
1
@marinus lo que está sucediendo en Chrome es lo que se supone que está sucediendo.
david4dev
No puedo hacer que funcione en FF4, IE8. :(
st0le
Bueno, lo probé en Firefox 4.0.1 y Chromium 11.0.696.65. Suponga que copió todo el guión. Creo que es fácil perder el corchete final al copiar.
david4dev
@ st0le IE8 no admite la etiqueta del lienzo , a menos que realice algunos trucos sucios: stackoverflow.com/questions/1332501/…
Cristian Lupascu
4

APL ( 120 118)

Tiene el mismo tipo de salida que la entrada de Python (es decir, solo muestra los estados en una cuadrícula de caracteres). Solo la cuadrícula es de 30x15 y el origen de la partícula es de 15x7.

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

JavaScript 502 500 496

Esta es una combinación de las respuestas de Joey y david4dev (es una copia descarada del 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)

Vista previa de JSFiddle: http://jsfiddle.net/GVqFr/60/ (puede presionar el botón TidyUp para formatear bien el código)

Cristian Lupascu
fuente
@Qqwy ¡Gracias por la edición!
Cristian Lupascu
No soy un experto en JavaScript, pero usas 500mucho la constante . Si puede definir una variable global a=500, puede guardar algunos caracteres reemplazando todos 500con a.
Sr. Llama
@GigaWatt tienes razón; eso funcionó 250también.
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
}

Llame e como explotar.

actualización: coloreada

t = texto, c = cls, g = gotoxi, f = volar, C = COLOR

usuario desconocido
fuente
1

C con SDL, 423 caracteres

Como la descripción original del problema mencionaba explícitamente SDL, sentí que ya era hora de que se presentara una solución SDL. Desafortunadamente, los nombres de las funciones y estructuras SDL no son particularmente concisos, por lo que este programa es un poco largo. De hecho, ni siquiera puedo dejar de lado el #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);}}

(Dado que el código ya es tan grande, dejé algunos bits adicionales para que se compilara sin advertencias. A veces extraño compilar sin advertencias. Eliminarlos ahorraría aproximadamente 30 caracteres).

La animación se ejecuta en un bucle infinito. Cierre la ventana para salir del programa. Cada explosión usa un nuevo conjunto de partículas aleatorias.

También me gustaría señalar el número 67372036en el código. Aparece en la expresión para el último argumento en la segunda llamada a SDL_FillRect(). Tal como está el código, la explosión se representa completamente en grises. Cambiar este número ligeramente agregará un efecto de color muy sutil pero agradable a la explosión. El número 67372032colorea las partículas al comienzo de la explosión, mientras que el número 67372034proporciona un efecto de color a medida que se desvanecen al final. Otros números pueden producir efectos de ciclo de color menos sutiles. Te animo a que las pruebes.

caja de pan
fuente
1

Después de ver algunos de los otros excelentes ejemplos aquí, decidí probarlo y crear una función de partícula que encaje probarlo 140byt.es

Javascript, 282 caracteres

( 138 caracteres de función de partículas y 150 caracteres de diseño básico de lienzo)

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

Ejemplo de JSFiddle en vivo aquí

Al hacer que el código fuera completamente procesal, ya no necesitaba ningún código de matriz o asignación de objeto, lo que reduce mucho el tamaño. Hacer un efecto de procedimiento también tiene algunos otros efectos secundarios agradables.

El código podría hacerse más pequeño omitiendo Gravity, Seeds, Number of Particles, etc., pero creo que estas características son demasiado buenas para eliminarlas;).

Caracteristicas

  • Centro de explosión X, Y configurable.
  • Número configurable de partículas
  • Gravedad en la dirección vertical: ¡haga que sus partículas caigan o vuelen!
  • Verificable, cada semilla tiene su propia explosión y mostrará exactamente esa explosión cada vez, a través de las computadoras.
  • Slowmotion, Fast Forward y reproducir explosiones hacia atrás son posibles, debido a la forma en que se crea el efecto.
  • Tamaño: 138 bytes.

También échale un vistazo en GitHub , para una versión anotada.

Qqwy
fuente
0

Python con PyGame, 240 caracteres

Me doy cuenta de que ya hay una solución en Python, pero como esa solo imprime caracteres, pensé que valdría la pena hacer una que dibuje una buena animación.

Ungolfed, con lo que comencé:

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

Después de mucha piratería. Pantalla completa para guardar algunos personajes. No uso sonido ni fuentes, así que creo que init()es innecesario (funciona para mí).

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)
Despistado
fuente
0

Python - 327 caracteres

Cosas interesantes:

  • Use números complejos como vectores 2D
  • (v * cos(a), v * sin(a)) implementado como v*e**(1j*a)
  • Parece una explosión en 3D.
  • Gravedad.

.

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)
Rayo
fuente
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)})

pruébelo copiando / pegando el código en dwitter.net

don brillante
fuente
Cuando el idioma es posterior al desafío, se supone que debes marcarlo como no competitivo.
fəˈnɛtɪk