Muestra la explosión de una estrella en ASCII-art

12

El objetivo es animar a una estrella explotando en el arte ASCII, comenzando desde un solo personaje estrella *hasta una supernova y, finalmente, al vacío espacial.

Reglas :

  • Debe mostrar solo 80 caracteres por línea en 24 líneas (este es el tamaño de terminal predeterminado en Linux)
  • Solo se permiten estos 95 caracteres imprimibles de ASCII
  • Pasos:
    1. La estrella inicial debe estar *centrada horizontal y verticalmente
    2. La estrella tiene que crecer para demostrar que explota
    3. Al final, la pantalla debe estar vacía (la estrella ha desaparecido)
  • La longitud del código o los idiomas son irrelevantes
  • Los votos decidirán los resultados más creativos y hermosos. ¿Alguna vez has visto una estrella en explosión? Veamos cómo te imaginas esto.

Agregué una respuesta usando Python como ejemplo, pero le recomendamos que cree algo diferente o mejor.

Tienes una semana para participar, el ganador será elegido el 01/04/2014.

Muestras de salida (solo con algunos cuadros):

# start





                                        *





# during explosion

                                    ****#****
                                 ***#@##*#@#****
                               *@**@@@*##**#*#**#*
                              **@@*#**#@*#@****#***
                              ****@*@***#****@**@@*
                             *******@***@@***#****#*
                              *#***#*##@****##@@@**
                              **#@###****@*********
                               *****@**@*@*****@**
                                 ************@**
                                    ****#****


# star is expanding

                                        *                                       
                               ********* **@******
                           ****   **#**@ #**#*#   ****
                         ***  **  **##** *@@*@*  **  ***
                       **  *  @@   *@*#* ***@*   *#  *  **
                     *** #  *  *#  *@#** ***@*  **  @  * *@*
                    ** *  * ** *@  ****@ @****  ** #* *  * **
                   ** * @* * ** *@  #### *#**  ** ** * @* * **
                  *# * # ** * #* *  **** ****  @ ** * ** * * #*
                 ** * *# * @ * #  @  @*@ *#*  *  @ # # * @* * **
                 *# * * * * # * @* * **# *#* * ** * * * * * # **
                 ** # * * @ * * # * # ** @* * * * * * # @ @ * **
                *# * * * * * * * * # * * * * * * @ @ * * * * * **
                 *# * @ * @ * @ * * * ** *@ * * # * * * * * @ @*
                 *# # @ * * # * *@ * *** @#@ @ ** * @ @ * * # **
                 *# * ** * * * @  @  **@ ***  *  @ * * * @* * #*
                  ** * * ** * #@ *  #*** **##  * #* * #@ * * @*
                   *# * *@ * @@ *#  **** @***  ** ** * #* * #*
                    *# *  * *@ **  @**@* *@#**  ** ** *  * @*
                     *#* @  *  @@  **##* ****@  **  #  * @**
                       **  @  #*   @*@#* @*@*#   @#  *  **
                         *#*  @*  @#*@*# **#*@#  **  ***
                           ****   *##**# #***@*   @***
                               ****@**@* *****@***

# star is disappearing

               *  -  -  --  --   ------- -------   --  --  -  -  *
             ** -  -  -  --  --   ------ ------   --  --  -  -  - **
            * -- - -- -- --  --   ------ ------   --  -- -- -- - -- *
          ** - -  - -- -- --  --  ------ ------  --  -- -- -- -  - - **
         *  - - -- - -- -  -  --   ----- -----   --  -  - -- - -- - -  *
        ** - - - -- - -- -  -  --  ----- -----  --  -  - -- - -- - - - **
        * - - - -  - - -  - -- --  ----- -----  -- -- -  - - -  - - - - *
       * - - - -  - - - -- - -- --  ---- ----  -- -- - -- - - -  - - - - *
      * -- - - - - - - - -- - -- -  ---- ----  - -- - -- - - - - - - - -- *
      * - - - - - - - -- - - - -  -  --- ---  -  - - - - -- - - - - - - - *
      * - - - - - - - - - - - - -- - --- --- - -- - - - - - - - - - - - - *
      * - - - - - - - - - - - - - - - -- -- - - - - - - - - - - - - - - - *
     * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
      * - - - - - - - - - - - - - - - -- -- - - - - - - - - - - - - - - - *
      * - - - - - - - - - - - - -- - --- --- - -- - - - - - - - - - - - - *
      * - - - - - - - -- - - - -  -  --- ---  -  - - - - -- - - - - - - - *
      * -- - - - - - - - -- - -- -  ---- ----  - -- - -- - - - - - - - -- *
       * - - - -  - - - -- - -- --  ---- ----  -- -- - -- - - -  - - - - *
        * - - - -  - - -  - -- --  ----- -----  -- -- -  - - -  - - - - *
        ** - - - -- - -- -  -  --  ----- -----  --  -  - -- - -- - - - **
         *  - - -- - -- -  -  --   ----- -----   --  -  - -- - -- - -  *
          ** - -  - -- -- --  --  ------ ------  --  -- -- -- -  - - **
            * -- - -- -- --  --   ------ ------   --  -- -- -- - -- *
             ** -  -  -  --  --   ------ ------   --  --  -  -  - **

# the star is gone
















(there is nothing)

Ejemplo animado de salida:

Estrella explosiva

Si quieres algo de inspiración, puedes ver una explosión del Capitán Blood , un juego de 1988.

Alabama
fuente
1
No hay realmente una especificación aquí para determinar si una respuesta es " correcta " o no.
Peter Taylor
Estoy eliminando la palabra correcta de la pregunta. La respuesta más popular será declarada como la ganadora.
AL
1
Ya sea que la palabra esté en la pregunta o no, todas las preguntas deben tener una especificación clara contra la cual se puedan medir las respuestas.
Peter Taylor
1
¿Es "mostrar algo que se parezca a los ejemplos de salida, pero no dude en ser creativo y artístico" suficiente? Puedo agregar más reglas (tiempo, número de cuadros, tamaños, etc.) pero estoy bastante seguro de que lo hará menos interesante.
AL
Explique si las reglas no son lo suficientemente claras y cómo puedo mejorarlas.
AL

Respuestas:

27

C + maldiciones

Explosión ASCII

No he hecho un gran esfuerzo para ordenar el código fuente. Básicamente, calcula una onda expansiva expansiva, con un fondo sólido agregado a los primeros fotogramas para dar una especie de efecto de flash. [[EDITAR: La explosión se veía un poco extraña al aparecer de un solo asterisco, así que agregué algunos cuadros de expansión al comienzo de la animación.]]

Las partículas aleatorias se superponen encima de esto, con posiciones determinadas de acuerdo con un cálculo de perspectiva básica para darle una sensación ligeramente 3D. (Bueno, esa era la idea, de todos modos).

#include <curses.h>
#include <stdlib.h>
#include <math.h>

#define NUM_FRAMES 150
#define NUM_BLOBS 800
#define PERSPECTIVE 50.0

typedef struct {
  double x,y,z;
} spaceblob;

double prng() {
  static long long s=1;
  s = s * 1488248101 + 981577151;
  return ((s % 65536) - 32768) / 32768.0;
}

int main() {
  char *frames[NUM_FRAMES], *p;
  int i,j,x,y,z,v,rows,cols,ith,i0;
  int maxx,minx,maxy,miny,delay=1E6;
  double bx,by,bz,br,r,th,t;
  spaceblob *blobs;

  /* Initialize ncurses and get window dimensions */
  initscr();
  getmaxyx(stdscr,rows,cols);
  minx = -cols / 2;
  maxx = cols+minx-1;
  miny = -rows / 2;
  maxy = rows+miny-1;

  /* Generate random blob coordinates */
  blobs = malloc(NUM_BLOBS * sizeof(spaceblob));
  for (i=0; i<NUM_BLOBS; i++) {
    bx = prng();
    by = prng();
    bz = prng();
    br = sqrt(bx*bx + by*by + bz*bz);
    blobs[i].x = (bx / br) * (1.3 + 0.2 * prng());
    blobs[i].y = (0.5 * by / br) * (1.3 + 0.2 * prng());;
    blobs[i].z = (bz / br) * (1.3 + 0.2 * prng());;
  }

  /* Generate animation frames */
  for (i=0; i<NUM_FRAMES; i++) {
    t = (1. * i) / NUM_FRAMES;
    p = frames[i] = malloc(cols * rows + 1);
    for (y=miny; y<=maxy; y++) {
      for (x=minx; x<=maxx; x++) {

        /* Show a single '*' in first frame */
        if (i==0) {
          *p++ = (x==0 && y==0) ? '*' : ' ';
          continue;
        }

        /* Show expanding star in next 7 frames */
        if (i<8) {
          r = sqrt(x*x + 4*y*y);
          *p++ = (r < i*2) ? '@' : ' ';
          continue;
        }

        /* Otherwise show blast wave */
        r = sqrt(x*x + 4*y*y) * (0.5 + (prng()/3.0)*cos(16.*atan2(y*2.+0.01,x+0.01))*.3);
        ith = 32 + th * 32. * M_1_PI;
        v = i - r - 7;
        if (v<0) *p++ = (i<19)?"%@W#H=+~-:."[i-8]:' '; /* initial flash */
        else if (v<20) *p++ = " .:!HIOMW#%$&@08O=+-"[v];
        else *p++=' ';
      }
    }

    /* Add blobs with perspective effect */
    if (i>6) {
      i0 = i-6;
      for (j=0; j<NUM_BLOBS; j++) {
        bx = blobs[j].x * i0;
        by = blobs[j].y * i0;
        bz = blobs[j].z * i0;
        if (bz<5-PERSPECTIVE || bz>PERSPECTIVE) continue;
        x = cols / 2 + bx * PERSPECTIVE / (bz+PERSPECTIVE);
        y = rows / 2 + by * PERSPECTIVE / (bz+PERSPECTIVE);
        if (x>=0 && x<cols && y>=0 && y<rows)
          frames[i][x+y*cols] = (bz>40) ? '.' : (bz>-20) ? 'o' : '@';
      }
    }

    /* Terminate the text string for this frame */
    *p = '\0';
  }

  /* Now play back the frames in sequence */
  curs_set(0); /* hide text cursor (supposedly) */
  for (i=0; i<NUM_FRAMES; i++) {
    erase();
    mvaddstr(0,0,frames[i]);
    refresh();
    usleep(delay);
    delay=33333; /* Change to 30fps after first frame */
  }
  curs_set(1); /* unhide cursor */
  endwin(); /* Exit ncurses */
  return 0;
}
r3mainer
fuente
1
¡Eso es bueno! ¿Puede explicar cómo capturó las imágenes del terminal? Creo que debería reducir la parte cuando está escribiendo, si no la ha agregado para provocar al espectador.
AL
1
@ n.1 Tienes razón: se estaba arrastrando un poco. Uso IShowU para capturar la pantalla y exporto los cuadros de QuickTime a ImageMagick para crear un GIF animado, y luego uso Gifsicle para optimizar la animación GIF. Es una especie de palabrería, de verdad. Avísame si has encontrado un método mejor.
r3mainer
7

Javascript

Pensé que valía la pena intentarlo en JS. Sugerir guardar y ejecutar; muy muy lento si pegas en la consola.

var boomboom = (function() {
    //Clear any existing page
    document.getElementsByTagName("body")[0].innerHTML="";

    var space=document.createElement("div");
    var iterator=0;
    var stars = 50;
    var timer=100;

    //Set container
    space.setAttribute("id","space");
    space.setAttribute("style","width:1000px;height:600px;margin:auto;border:solid 1px #000;position:relative;overflow:hidden;background:#000;color:#fff");
    document.getElementsByTagName("body")[0].appendChild(space);

    //Set interval and draw...
    var interval = setInterval(function(){ drawStars(iterator,stars); }, timer);
    drawStars(iterator, stars);

    function drawStars(r,c) {
        clearInterval(interval);

        //a container for this set of stars
        var starContainer=document.createElement("div");

        //don't draw more if there are too many, it's got to go
        if(iterator < 1000) {
            for(var i = 0; i < c; i++) {
                var x,y;

                if(iterator < 100) {
                    x=500 + r * Math.cos(2 * Math.PI * i / c) * 0.7;
                    y=300 + r * Math.sin(2 * Math.PI * i / c) * 0.7;
                }

                //add some randomness for the boom boom
                if(iterator > 100) { 
                    x=500 + r * Math.cos(2 * Math.PI * i / c) * 0.7*Math.random();
                    y=300 + r * Math.sin(2 * Math.PI * i / c) * 0.7*Math.random();
                }

                //Make a star
                var star=document.createElement("div");
                star.setAttribute("class","star");

                //Exploding stars are red, I hope
                var color = iterator < 100 ? "color:#fff" : "color:rgb("+parseInt(255*Math.random())+",0,0)";
                star.setAttribute("style","position:absolute; left:"+ x +"px;top:"+ y +"px;"+color);

                //Change the star character as boom boom gets bigger
                if(iterator <= 200) {
                    star.innerText="*";
                }
                else if(iterator >=200 & iterator <= 400) {
                    star.innerText="O";
                }
                else  {
                    star.innerText="-";
                }
                //Add the star to its container
                starContainer.appendChild(star);
            }
        }
        //draw the container
        space.appendChild(starContainer);

        //increment the iterator.  It's an iterator because we're using intervals and it's late.
        iterator+=5;

        //remove stars when we get too many
        if(iterator > 200) {
            space.removeChild(space.firstChild);
        }
        if(iterator < 1500) { //do it all again
            timer = timer > 10 ? timer-10 : timer;
            interval=setInterval(function(){ drawStars(iterator,stars); }, timer);
        }

        //make sure it's actually empty
        else {
            space.innerHTML="";
        }
    }
}());

Ediciones en JSBin: http://jsbin.com/worofeqi/5/watch?js,output

Curiosamente se ejecuta mucho más suavemente cuando se realiza desde el sistema de archivos local que en JSBin. Sinceramente, no estoy seguro de por qué; puede ver eso esta tarde.

Dave Forber
fuente
¿Puede colocarlo en jsfiddle, jsbin u otro sitio web donde podamos ver fácilmente? Al agregar la pregunta, solo pensé en mostrar el resultado en un terminal, pero no actualizaré las reglas ahora que ha agregado su respuesta, debería haber agregado esta regla antes.
AL
Respuesta actualizada (tenga en cuenta la advertencia (muy extraña))
Dave Forber
1

Pitón

#!/usr/bin/python

import sys, math, time, random

def distance(x, y):
    # ((y - y_center) * 2) -> correct ratio for a true circle
    return math.ceil(math.sqrt(((x - 40) ** 2) + (((y - 12) * 2) ** 2)))

def star(radiuses):
    for r in radiuses:
        #~ clear screen: http://stackoverflow.com/a/2084521/2257664
        print chr(27) + "[2J"

        # width
        for y in range(24):
            # height
            for x in range(80):
                d = distance(x, y)

                #~ border
                if (d == r):
                    sys.stdout.write('*')
                #~ inside the star
                elif (d < r):
                    if (r > 35):
                        sys.stdout.write(' ')
                    elif (r > 25) and ((d % 2) != 0):
                        sys.stdout.write('-')
                    elif (r > 15) and ((d % 2) == 0):
                        sys.stdout.write(' ')
                    else :
                        sys.stdout.write(random.choice('****#@'))
                #~ space outside the star
                else:
                    sys.stdout.write(' ')
            print
        time.sleep(0.1)

star(range(0, 12) + range(10, 0, -1) + range(0, 50))

Ejemplo de salida (usando menos pasos y sin borrar la pantalla).

Extractos de la salida también se muestran en la pregunta.

Alabama
fuente