ASCII 아트로 별 폭발을 표시합니다


12

목표는 단일 별 문자 *부터 초신성, 마지막으로 공간 공극에 이르기까지 ASCII 아트에서 폭발하는 별을 애니메이션하는 것입니다 .

규칙 :

  • 24 줄에 줄당 80 자만 표시하면됩니다 (Linux의 기본 터미널 크기).
  • ASCII 에서이 95 개의 인쇄 가능한 문자 만 허용됩니다
  • 단계 :
    1. 초기 별은 *수평 및 수직 중심에 있어야하며
    2. 별이 자라는 것을 보여주기 위해 자라야한다
    3. 마지막에 화면이 비어 있어야합니다 (별이 사라졌습니다).
  • 코드 길이 또는 언어는 관련이 없습니다
  • 투표는 가장 창의적이고 아름다운 결과를 결정합니다. 폭발하는 별을 본 적이 있습니까? 이것을 어떻게 상상하는지 봅시다.

파이썬을 예로 사용하여 답변을 추가했지만 다른 것이 나 더 나은 것을 만들도록 권장합니다.

1 주일 동안 참가하면 2014-04-01에 우승자가 선정됩니다.

출력 샘플 (일부 프레임 만 해당) :

# start





                                        *





# during explosion

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


# star is expanding

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

# star is disappearing

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

# the star is gone
















(there is nothing)

애니메이션 출력 예 :

폭발하는 별

영감을 원한다면 1988 년 게임 Captain Blood폭발을 볼 수 있습니다 .


1
여기에 정답이 맞는지 아닌지 결정하기위한 사양이 없습니다.
피터 테일러

질문에서 올바른 단어를 제거하고 있습니다. 가장 인기있는 답변이 승자로 선언됩니다.
AL

1
단어가 문제에 있는지 여부에 관계없이 모든 질문에는 답을 측정 할 수있는 명확한 사양이 있어야합니다.
피터 테일러

1
"출력 예제처럼 보이지만 창의적이고 예술적으로 자유롭게 표현할 수 있습니까?" 더 많은 규칙 (시간, 프레임 수, 크기 등)을 추가 할 수 있지만 덜 흥미로울 것입니다.
AL

규칙이 명확하지 않은 경우 어떻게 개선 할 수 있는지 설명하십시오.
AL

답변:


27

C + 저주

ASCII 폭발

소스 코드를 정리하기 위해 많은 노력을 기울이지 않았습니다. 기본적으로 확장 충격파를 계산하고 처음 몇 프레임에 단색 배경을 추가하여 일종의 플래시 효과를냅니다. [[편집 : 폭발은 하나의 별표에서 약간 이상하게 보였으므로 애니메이션 시작 부분에 몇 개의 확장 프레임을 추가했습니다.]]

임의의 입자가이 위에 겹쳐지며, 3D 느낌을주기 위해 기본 원근법 계산에 따라 위치가 결정됩니다. (어쨌든 그 아이디어였습니다.)

#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;
}

1
멋지다! 터미널 이미지를 어떻게 캡처했는지 설명해 주시겠습니까? 뷰어를 괴롭히기 위해 추가하지 않은 경우 입력 할 때 부분을 줄여야한다고 생각합니다.
AL

1
@ n.1 당신이 맞아요-조금 끌고있었습니다. IShowU 를 사용 하여 화면을 캡처하고 프레임을 QuickTime에서 ImageMagick으로 내보내 애니메이션 GIF를 만든 다음 Gifsicle을 사용하여 GIF 애니메이션을 최적화합니다. 정말 약간의 골판지입니다. 더 나은 방법을 찾았다면 알려주십시오.
r3mainer

7

자바 스크립트

JS에서 그만한 가치가 있다고 생각했습니다. 저장하고 달리기를 제안하십시오. 콘솔에 붙여 넣으면 매우 느려집니다.

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="";
        }
    }
}());

JSBin에서 수정 : http://jsbin.com/worofeqi/5/watch?js,output

JSBin보다 로컬 파일 시스템에서 수행하면 훨씬 매끄럽게 실행됩니다. 왜 그런지 솔직히; 오늘 저녁에 볼 수 있습니다.


jsfiddle, jsbin 또는 쉽게 볼 수있는 다른 웹 사이트에 배치 할 수 있습니까? 질문을 추가 할 때 터미널에 결과를 표시하는 것에 대해서만 생각했지만 답변을 추가 한 규칙을 업데이트하지 않기 전에이 규칙을 추가해야합니다.
AL

답변 업데이트 됨 ((홀수) 경고)
Dave Forber

1

파이썬

#!/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))

출력 예 (단계를 줄이고 화면을 지우지 않고).

출력에서 발췌 한 내용도 질문에 표시됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.