Il codice più compatto per un'esplosione simulata


13

Riesci a scrivere un programma che esegue il rendering dello schermo di un gruppo di pixel che esplode a pezzi (come in un semplice motore di particelle) e puoi farlo in un numero notevolmente ridotto di caratteri (tratti di tasti)? (Ricorda i lemming di gioco, quando quei ragazzini esploderebbero e i loro piccoli pezzi di pixel voleranno via.)

Qualcuno ha programmato un semplice sistema di particelle qui come uno schizzo di elaborazione ed è piuttosto pesante rispetto a quello che penso che altri dovrebbero essere in grado di realizzare se ci provassero. Ma sarei molto più colpito se qualcuno potesse fare lo stesso in c ++ e sdl, o persino java o c #.


2
"Lines of code" è una metrica che apre molta ambiguità e non è certamente [code-golf] che è "numero di caratteri" o talvolta "numero di byte". Discussione correlata su meta.
dmckee --- ex gattino moderatore

4
A proposito, il problema che ho sollevato sopra e le specifiche piuttosto incomplete sono cose che avrebbero potuto essere utilmente risolte discuterne in anticipo nella chat di Puzzle Lab o nella Sandbox su meta . Ma, in ogni caso, benvenuto su CodeGolf.SE.
dmckee --- ex gattino moderatore

Domanda aggiornata, sostituito LOC con numero di caratteri.
Todd Hopkinson,

1
sì, se scrivi C / C ++ / Java / Qualsiasi derivato C potresti scrivere un intero sistema operativo in 1 riga di codice
Nate Koppenhaver,

Risposte:


13

Python, 245 caratteri

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)

Non è un'esplosione lemming, ma sicuramente un +1 per brevità!
Todd Hopkinson,

10

C #, WPF - 1523

Non terribilmente serio; questo era principalmente un tentativo se funzionasse davvero.

Quello che sto facendo qui è usare un ItemsControl (Menu, poiché è più breve) in WPF per visualizzare le particelle tramite associazione e templatura dei dati. Un modello di dati controlla l'aspetto delle particelle (in questo caso un semplice cerchio) e l'associazione dei dati controlla il colore e la posizione delle particelle.

Ogni particella ha una posizione, un colore e una direzione che vengono aggiornati da un timer. Inizialmente un gruppo di particelle viene generato al centro della finestra con direzioni casuali (distribuite normalmente). Quella raccolta viene vincolata ai dati di ItemsControl che gestisce quindi la visualizzazione automatica delle particelle, ogni volta che le proprietà vengono aggiornate. Le particelle vengono trascinate leggermente verso il basso a causa della gravità.

È diventato un po 'lungo, è vero. Ma almeno sembra carino:

enter image description here

Può sicuramente essere abbreviato omettendo:

  • gravità, causando l'espansione uniforme delle particelle su tutti i lati;
  • la normale distribuzione per i vettori iniziali, causando l'espansione delle particelle in una "scatola" sparsa;
  • la variazione di luminosità, lasciando particelle nere.

Ho scelto di non farlo nell'interesse dell'estetica. Questa soluzione è molto più lunga di quasi qualsiasi altra cosa, indipendentemente. L'approccio basato su dati e templating potrebbe essere elegante ma è anche piuttosto dettagliato rispetto al semplice aggiornamento di una bitmap. (Nota: l'ho ottenuto fino al 1356 lasciando fuori tutto quanto sopra, ma sembra orribile allora.)

Il codice è distribuito in tre file, che vengono forniti qui in formato formattato per motivi di leggibilità:

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 Ottimo esempio! Proprio come quei classici lemming esplosivi dei giorni passati. E penso che questo superi il codice di elaborazione nella domanda iniziale.
Todd Hopkinson,

@icnivad: devo ammettere che lo sketch di Processing (ho solo guardato il risultato finale, non il codice) è stato la mia ispirazione per gli sguardi.
Joey,

Gah! Smetto di giocare a golf, ora. Ormai ci sono alcuni trucchi (come PropertyChanged per tutte le proprietà e solo sull'ultima impostata). Dato che ho iniziato oltre 2000 caratteri, immagino che una riduzione di 500 caratteri non sia poi così male. Ormai è anche abbastanza lento. DispatcherTimer funziona molto meglio di Timer, ma è molto più lungo. Tuttavia, potrei essere tentato di portarlo su Silverlight ed eseguirlo sul mio telefono.
Joey,

Penso che questo sia quello da battere per la combinazione di dimensioni del codice e qualità estetica dell'esplosione.
Todd Hopkinson,

icnivad: riscriverò il tutto per dipingere direttamente su una bitmap in seguito; dovrebbe essere molto più breve, quindi. Il 45% del codice è XAML; gran parte del codice è in grado di associare elementi dell'interfaccia utente alle proprietà delle particelle. Aggiungete a ciò la verbosità generale di C # ed è molto più prolisso di quanto dovrebbe essere.
Joey,

7

postscript - 287 244 caratteri

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

Corri con gs -dNOPAUSE asplode.ps

Potresti persino stamparlo e creare un libro a fogli mobili


Meraviglioso! È bellissimo!
utente sconosciuto

5

Javascript - 268 caratteri

Ecco un'esplosione a 1 dimensione, a 2 particelle:

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)

Per eseguirlo, apri una pagina vuota about: in un buon browser web, incolla la barra dell'URL e premi invio. È possibile modificare l'esplosione modificando i valori alla fine in s(10,5,1,0). Il primo valore è la dimensione della particella che viene esplosa. Il secondo valore è la dimensione della particella che viene esplosa da essa. Il terzo valore è la velocità della particella esplosa da esso. Lascia lo '0' così com'è.


1
Questo non funziona in Safari 5.0.5 (mostra qualcosa che assomiglia un po 'a una mazza da baseball) o in Chrome 11.0.696.68 (mostra due palline, una leggermente più grande dell'altra, che si allontanano lentamente).
marinus

1
@marinus quello che sta succedendo in Chrome è quello che dovrebbe succedere.
david4dev,

Non riesco a farlo funzionare su FF4, IE8. :(
st0le

Beh, l'ho provato su Firefox 4.0.1 e Chromium 11.0.696.65. Fai causa, hai copiato l'intera sceneggiatura: trovo facile perdere la parentesi finale durante la copia.
david4dev,

@ st0le IE8 non supporta il tele tag, a meno che non si esegue alcuni trucchi sporchi: stackoverflow.com/questions/1332501/...
Cristian Lupascu

4

APL ( 120 118)

Ha lo stesso tipo di output della voce Python (ovvero genera solo gli stati su una griglia di caratteri). Solo la griglia è 30x15 e l'origine delle particelle è a 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

Questa è una combinazione delle risposte di Joey e david4dev (è una copia spudorata dell'algoritmo di Joey implementato 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)

Anteprima JSFiddle: http://jsfiddle.net/GVqFr/60/ (puoi premere il pulsante TidyUp per formattare il codice in modo corretto)


@Qqwy Grazie per la modifica!
Cristian Lupascu,

Non sono esperto di JavaScript, ma usi molto la costante 500. Se è possibile definire una variabile globale a=500, è possibile salvare alcuni caratteri sostituendo tutti 500con a.
Mr. Llama,

@GigaWatt hai ragione; che ha funzionato anche per 250.
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
}

Chiama e come esplodere.

aggiornamento: colorato

t = testo, c = cls, g = gotoxy, f = fly, C = COLOR


1

C con SDL, 423 caratteri

Dato che la descrizione del problema originale menzionava esplicitamente SDL, ho sentito che era passato il tempo in cui era stata presentata una soluzione SDL. Sfortunatamente, i nomi della funzione e delle strutture SDL non sono particolarmente concisi, quindi questo programma è un po 'lungo. In realtà, non posso nemmeno tralasciare il #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);}}

(Dato che il codice è già così enorme, ho lasciato alcuni bit in più in modo che si compilasse senza avvisi. Mi manca la compilazione senza avvisi a volte. Rimuoverli risparmierebbe circa 30 caratteri circa.)

L'animazione viene eseguita in un ciclo infinito. Chiudi la finestra per uscire dal programma. Ogni esplosione utilizza un nuovo set di particelle casuali.

Vorrei anche sottolineare il numero 67372036nel codice. Appare nell'espressione per l'ultimo argomento nella seconda chiamata a SDL_FillRect(). Allo stato attuale del codice, l'esplosione è resa interamente in grigio. Modificando leggermente questo numero si aggiungerà un effetto colore molto sottile ma piacevole all'esplosione. Il numero 67372032colora le particelle all'inizio dell'esplosione, mentre il numero 67372034fornisce un effetto di colore quando svaniscono alla fine. Altri numeri possono produrre effetti di ciclismo del colore meno sottili. Ti incoraggio a provarli.


1

Dopo aver visto alcuni degli altri grandi esempi qui, ho deciso di provarlo e creare una funzione particellare che si adatta a 140byt.es

Javascript, 282 caratteri

( 138 caratteri funzione particella e 150 caratteri base disegno su tela caldaia)

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

Esempio JSFiddle live qui

Rendendo il codice completamente procedurale, non avevo più bisogno di alcun codice di array o di assegnazione di oggetti, riducendo di molto le dimensioni. Fare un effetto procedurale ha anche alcuni altri effetti collaterali piacevoli.

Il codice potrebbe essere ridotto ommitting Gravity, Seeds, Number of Particles, ecc., Ma penso che queste funzionalità siano troppo belle per essere rimosse;).

Caratteristiche

  • Centro di esplosione configurabile X, Y.
  • Numero configurabile di particelle
  • Gravità in direzione verticale: fai cadere o volare le particelle!
  • Seminabile, ogni seme ha la sua esplosione e mostrerà esattamente quella esplosione ogni volta, attraverso i computer.
  • Rallentatore, avanzamento rapido e riproduzione di esplosioni all'indietro sono tutti possibili, a causa del modo procedurale in cui viene creato l'effetto.
  • Dimensione: 138 byte.

Controllalo anche su GitHub , per una versione annotata.


0

Python con PyGame, 240 caratteri

Mi rendo conto che esiste già una soluzione in Python, ma dato che uno stampa solo personaggi, ho pensato che valesse la pena crearne uno che disegna una bella animazione.

Ungolfed, quello che ho iniziato con:

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

Dopo molto hackery. Schermo intero per salvare alcuni personaggi. Non usare audio o caratteri, quindi penso che init()non sia necessario (funziona per me).

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 caratteri

Cose interessanti:

  • Usa un numero complesso come vettore 2D
  • (v * cos(a), v * sin(a)) implementato come v*e**(1j*a)
  • Sembra un'esplosione 3D.
  • Gravità.

.

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

provalo copiando / incollando il codice su dwitter.net


Quando la lingua post-data la sfida dovresti contrassegnarla come non competitiva.
fəˈnɛtɪk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.