코딩 이야기

코딩으로 크리스마스 트리 만들기

꾸욱꾸우욱 2021. 12. 12. 19:29

christmas_tree.exe
4.66MB
snow_christmas_tree.exe
4.59MB

크리스마스가 다가오면서 다양한 학과별 크리스마스 트리가 인터넷에 돌고 있다.

시험도 끝나가고 시간적 여유가 조금 있어서 크리스마스 트리를 컴퓨터 공학과스럽게 코딩으로 만들어보고자 했다.

사용한 언어는 파이썬이고 두 가지 방식으로 구현을 해보았다. 위의 파일은 완성된 exe 파일이다. 코드를 exe파일로 만드는 방법은 여기를 참고해보자.


첫째로 색깔이 들어간 정적인 트리를 만들어 보았다. 이 트리는 블로그에 있는 글을 참고하여 구현하였다. 파이썬에 색깔이 들어간 작업은 처음 해보았는데 꽤 괜찮게 구현되는 느낌이다.

from colorama import init
init()

from colorama import Fore, Back

size = 11

print()
for i in range(0, size):
    if i == 0:
        print(Fore.YELLOW + "★".center(size, ' '))
    elif i % 2 == 0:
        print(Fore.GREEN + ("*" * i).center(size, ' '))
    else:
        print(Fore.RED + ("'" * (i + 1)).center(size, ' '))

init(autoreset = True)
print()
print(Back.RED + "Merry".center(size + 2, ' '))
print(Back.GREEN + "Christmas!".center(size + 2, ' '))
print()
input()

일종의 별찍기 처럼 하나씩 구현하고 대신 색깔을 입힌 코드다.

출력물은 이렇게 나온다.

캡처본이라 사진 화질이 좋진 않으나 상당히 예쁘게 출력된다.


다음은 직접 구현한 동적인 트리이다. 눈이 내리는 모습을 표현하고 싶었고 눈이 쌓이면서 나무와 글씨를 표현하고 싶었다.

import random, os, time

graph = [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,0],
    [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,0,1,0,0,1,0,1,1,0,0,0,0,0],
    [0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,0,0,0,1,1,0,0,0],
    [0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,0,0,0],
    [0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],    
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] 
]

visit = [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],   
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],   
    [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
]

snow = []

def show(field): # show field
    for i in range(len(field)):
        for j in range(len(field[0])):
            if field[i][j] == 0:
                print(" ", end = "") # empty
            else:
                print("#", end = "") # snow
        print()

while True:
    time.sleep(0.1)
    os.system('cls')
    show(visit)
    print()
    print("                                @Kkook")

    if snow:
        for idx in range(len(snow) - 1, -1, -1):
            if snow[idx][0] + 1 >= len(graph) - 1: # over range
                if graph[snow[idx][0]][snow[idx][1]] == 0:
                    visit[snow[idx][0]][snow[idx][1]] = 0
                snow.pop(idx)
            else:
                if graph[snow[idx][0]][snow[idx][1]] == 0: # empty space
                    visit[snow[idx][0]][snow[idx][1]] = 0
                else:
                    for i in range(snow[idx][0] + 1, len(graph) - 1): # check bottom
                        if graph[i][snow[idx][1]] == 1 and visit[i][snow[idx][1]] == 0:
                            visit[snow[idx][0]][snow[idx][1]] = 0
                            break
                snow[idx][0] += 1
                visit[snow[idx][0]][snow[idx][1]] = 1

    number = random.randint(0, len(graph[0]) - 1) # random generate
    visit[0][number] = 1
    snow.append([0, number])

코드 자체는 크게 어렵지 않다. 사전에 출력 결과로 원하는 것을 graph로 만들어 두고 눈이 쌓인 것을 기록하기 위해 visit를 사용한다. snow라는 리스트를 선언해 눈의 좌표 값을 모두 저장한다.

무한 루프를 돌며 눈이 계속 내리도록 한다. time과 os 라이브러리를 이용해 화면이 갱신되도록 했다. show는 출력 함수이다. 앞서 선언한 snow 리스트의 값을 확인해준다. 만약 범위를 벗어나는 이동을 할 경우 리스트에서 제거한다. 범위 안에서 이동할 때 만약 눈이 쌓이지 않는 위치면 한 단계 내려간다. 그다음으로 눈이 쌓이는 위치인 경우 아래쪽부터 쌓일 수 있도록 했다. 현재 위치부터 가장 아래쪽 위치까지 중에 눈이 쌓여야 할 곳이 아직 존재한다면 현재 칸을 무시하고 내려가 아래쪽에 쌓일 수 있도록 한다.

이후 랜덤으로 눈의 위치를 생성하고 새로운 눈을 추가하며 코드를 마무리했다.

눈이 쌓이는 모습까지 캡쳐하고 싶었으나 꽤 시간이 걸리는 관계로 완성본을 캡처했다.

 

GIF로 캡처하면 이렇다.


이렇게 컴공스럽게 크리스마스 트리 만들기를 해봤다. 시간 때우기엔 이만한 게 없는 듯하다.