KTUG마당은 KTUG를 방문하는 모든 이용자가 대화를 나누고 소식을 전하는 곳입니다.

  • 로그인 없이 자유롭게 글을 읽고 쓸 수 있는 철학은 처음과 같이 계속됩니다.
  • Team Blog의 글을 이곳 게시판의 "정보글"로 모았습니다. Team blog는 기고자가 올린 글에 질문을 받는 부담을 줄이기 위하여 댓글을 허용하지 않았습니다. 그러나 이곳 게시판으로 모으면서 댓글을 달 수 있습니다. 게시물을 작성하실 때 댓글을 원하지 않으시면 댓글을 허용하시지 않으시기를 바랍니다. 또한 불필요한 소모성 댓글을 달지 않도록 주의하여 주시기를 바랍니다.
  • TeX과 관련된 질문이나 답변은 QnA 마당을 이용하십시오. TeX과 관련된 질문은 지웁니다
  • MathJax를 이용한 수식조판을 사용하실 수 있습니다. 여기를 참조하세요.
  • 스팸 글을 막기 위하여 짧은 시간 내에 다시 글이 등록되는 IP를 막거나, 광고 글을 막기 위하여 금지어로 .com, .net 등을 설정하고 있습니다. 다소간의 불편함이 있으시더라도 양해 바랍니다.
    • 금지어에서 stackexchange, stackoverflow, ctan, overleaf, , github, google.com, gmail.com, .org, .io, sil.org, wiki.com, tistory.com등은 해제하였습니다.
  • 사용하는 편집기는 CKeditor입니다. 편집기에서 [enter]를 누르면 <p> 태그가 들어가고, 문단으로 생각하고 한줄을 비웁니다. 글줄만 바꾸려면 shift-enter 를 누르시면 <BR>가 들어가므로 용도에 맞게 나누어 쓸 수 있습니다.

SET 게임 카드 그리기

2015.10.26 04:07

puzzlist 조회 수:4581

보드 게임 가운데 SET라는 이름의 게임이 있습니다. https://en.wikipedia.or지/wiki/Set_(game)

다음과 같이 네 가지 속성마다 세 가지 종류가 있어서 카드는 총 \(3^4=81\)장입니다.


모양: 둥근 막대(oval), 다이아몬드(diamond), 삐뚤빼뚤(squiggle)

색깔: 빨강, 초록, 보라

개수: 1, 2, 3

무늬: 비움, 줄무늬, 채움


어쩌다 이걸 TeX에서 TikZ로 그려볼 일이 생겼습니다. 이렇게요.


SetGame-AllCards.png


81개를 하나씩 그린다는 건 말이 안 되니, 이걸 속성별로 그리게 하면 되겠다는 생각이 들었습니다.


우선 카드 크기는 보통 1:1.4 정도 되는 것 같으니, 테두리를 그리는 건 간단합니다. 가로 2.8, 세로 2로 하고, 카드 위치를 인자로 해서 


\draw[rounded corners=2mm] (3.0*#1,2.2*#2) rectangle (3.0*#1+2.8,2.2*#2+2);


로 그립니다. 개수가 하나부터 셋까지니까, 위치를 잡기 위해 하나 가운데 하나(1,1)와 셋 가운데 둘(3,2)은 0이 나오도록 해서 출력 위치를 계산합니다.


\def\pos#1#2#3#4{({3*#1+1.4+(#4-(#3+1)/2)*.8},2.2*#2+1)}


이 명령은 왼쪽에서 #1 번째, 위로 #2 번째 카드에 그려질 #3 개 모양 가운데 #4 번째의 출력 위치를 알려줍니다.

둥근 막대를 어떻게 다룰지 먼저 생각했습니다. 모양 하나는


\def\oval{(-.2,.4) -- (-.2,-.4) arc (180:360:.2) -- (.2,.4) arc (0:180:.2) -- cycle}


로 그립니다. 이제 \draw[shift={\pos{...}}] \oval로 여러 개를 그릴 수 있습니다. 현재는 무늬 없는 모양이 그려지겠지요. \diamond는 좌우폭을 \oval보다 조금 크게 했습니다. \oval과 똑같은 폭으로 그리면 너무 좁아 보여서요. 곡선으로 이루어진 \squiggle은 어떻게 그릴지 고민스러웠는데,


\draw plot [smooth cycle, tension=.5] coordinates {(0,.59) (-.17,.6) (-.2,.5) (-.15,.4) (-.1,.2) (-.2,-.4) (-.12,-.55) (0,-.59) (.18,-.6) (.2,-.5) (.15,-.4) (.1,-.2) (.2,.4) (.12,.55)}}


로 그렸습니다. 이렇게 하면 coordinates 인자로 주어지는 점들을 지나는 곡선이 그려집니다. 정말 대충 몇 개 점 잡고 tension만 조절했기 때문에 원본 SET 게임에 그려진 모양과는 많이 다릅니다.


이제 줄무늬를 어떻게 할까 고민이 됩니다. 아마 TikZ에서 [pattern=horizontal lines] 옵션을 이용하는 것이 일관성 있는 해결책일 텐데, 문제는 수평선 사이 간격 조정이 안 된다는 점과, 무늬 없는 상태와 속을 채운 상태를 따로 처리해야 한다는 점입니다. pattern을 새로 설정하면 될 텐데, 이 부분이 너무 복잡해서 어떻게 하는지 잘 모르겠더군요. 그래서 무늬 없는 것과 속을 채운 것은 간단히 되니까, 줄무늬만 따로 처리하기로 했습니다. \clip \oval로 둥근 막대 안쪽만 그려지게 설정한 다음 \foreach 명령으로 가로줄을 연속해서 그립니다. 이렇게 하면 y축 증가량을 바꾸어서 줄무늬 간격을 조절할 수 있습니다.


세 가지 무늬에 대해 \ovaloutlined, \ovalstriped, \ovalsolid 세 개로 명령을 만들면, \diamond, \squiggle에 대해서도 똑같이 해야 하니, 비슷한 명령을 세 개씩 만들어서 따로 쓰는 건 아무래도 번거롭습니다. 그래서 어떻게 할까 고민을 하다가, 어차피 그리는 대상만 다르고 처리하는 방식은 똑같으니, \outlined, \striped, \solid로 명령 세 개를 만들고, 각각에서 \oval, \diamond, \squiggle을 처리하게 만들자는 생각이 들었습니다.


그래서 \outlined{위치}{\oval}{색깔}로 둥근 막대를 그리게 했습니다.


\def\outlined#1#2#3{\draw[shift={#1},#3,ultra thick] #2;}


명령어 \oval을 두 번째 인자로 넘겨주자는 아이디어였습니다. \solid와 \striped도 같은 방식으로 정의합니다.


\def\solid#1#2#3{\filldraw[shift={#1},#3,ultra thick] #2;}

\def\striped#1#2#3{\draw[shift={#1},#3,ultra thick] #2; \begin{scope}\clip[shift={#1}] #2; \foreach \y in {-.6,-.5,...,.6} \draw[shift={#1},#3] (-.5,\y)--(.5,\y);\end{scope}}



이제 카드 한 장을 그리려면 총 여섯 개의 인자를 넘겨 줍니다. 가로 위치, 세로 위치, 모양, 색깔, 개수, 무늬.


\def\SETcard#1#2#3#4#5#6{

...

}


이 명령에서는 개수만큼 그림을 그려야 하므로,


\foreach \cnt in {1,...,#5}


로 반복하도록 설정하고,


#6{\pos{#1}{#2}{#5}{\cnt}}{#3}{#4}


를 수행합니다. 여섯 번째 인자 #6 자체를 명령으로 수행한다는 게 재미있습니다.


예를 들어, \SETcard{2}{0}{\diamond}{red}{2}{\striped}를 실행하면 내부적으로는 \diamond를 \striped 명령에 인자로 넘겨서 두 번 그리게 됩니다.


이제 위의 81개 카드를 모두 그리려면, \foreach를 각 속성에 대해 4중으로 돌리면 됩니다.

\begin{tikzpicture}[scale=1,line join=round]
\foreach \s in {\squiggle,\diamond,\oval}{
    \setcounter{x}{0}
    \foreach \c in {violet,green!80!black,red}{
        \foreach \sh in {\outlined,\striped,\solid}{
            \foreach \n in {1,2,3}{
                \SETcard\thex{\they}\s\c\n\sh;
                \stepcounter{x}
            }
        }
        \stepcounter{y}
        \setcounter{x}{0}
    }
}
\end{tikzpicture}

고수들에게는 별 것 아니겠지만, 저 같은 하수에게는 명령어 자체를 인자로 넘긴다는 게 재미있는 아이디어여서 소개하면 좋겠다 싶어 올려 봤습니다. 고수의 손길로 좀더 간결하고 멋진 코드가 될 수도 있을 것 같고요.

첨부한 파일은 실제로 SET 게임을 할 수 있도록 A4 용지에 맞추어 만든 PDF 파일입니다. A4 용지 규격이 약 1:1.4니까 아홉 개씩 출력하면 딱 맞습니다. 줄간격이나 색깔, 크기 등을 바꾸고 싶은 분도 있을 것 같아 TeX 소스도 함께 첨부하였습니다.
번호 제목 글쓴이 날짜 조회 수
748 흠.. 뭔가를 시도하려 했습니다만... 더이상 진행하지 않고 놔두기로 했습니다.. 불량양파 2016.12.16 6522
747 [잡담]맥북 프로 터치바 [1] 지나가다 2016.12.05 6015
746 [참가신청] 문서작성워크숍 2016 [10] ischo 2016.10.11 7038
745 그럭저럭 또 하나의 Sample pdf 를 만들어 봤습니다. [2] 불량양파 2016.11.23 6958
744 표지에 대한 테스트도 어느정도 됐네요 :D file 불량양파 2016.11.18 5829
743 조금.. 다른 가능성을 찾게 된듯 합니다. file 불량양파 2016.11.18 5830
742 근래에 삽질한걸로 표지 한번 만들어 봤습니다.. [6] file 불량양파 2016.11.16 9430
741 결국 oblivior 는 KNUworkshop 스타일로 모이게 되네요... [4] 불량양파 2016.11.07 20303
740 논문등에서 사용되는 TeX 예제들을 모아서 작업한 분이 있으시네요.. 불량양파 2016.11.07 6088
739 지금까지 작업한 부분을 정리해서 command 로 만들어 봤습니다. [6] 불량양파 2016.11.04 5817
738 실험적으로 해본겁니다만.. 괜찮네요 결과물이... file 불량양파 2016.11.03 5788
737 근래에 본게 좀 있어서.. Layout 테스트를 좀 해봤는데.. [5] file 불량양파 2016.11.01 5853
736 2016 한국텍학회 정기총회 및 KTUG 컨퍼런스 [5] 관리자 2016.01.18 6432
735 테이블 변환도... 거의 완성단계라고 봐도 될거 같습니다. [7] file 불량양파 2016.09.29 5951
734 작업하고 있는 시스템(?) 에서 템플릿 교체 동작까지 확인했습니다. [2] file 불량양파 2016.09.21 5763
733 흠.... 소 뒷걸음질 치듯이... 어찌어찌 하기는 했네요...-.-; [8] file 불량양파 2016.09.20 5801
732 무료폰트 고양체 발표 [1] 에드 2016.08.21 5724
731 일단 하나의 소스로... 가로/세로 템플릿을 통해 바꿔서 출력하는것까지는 되었습니다. [2] 불량양파 2016.08.05 5528
730 GNU Emacs 24.5 버전의 메뉴얼 초벌번역 정리작업이 끝났습니다. [8] 불량양파 2016.08.04 5853
729 TeX, ePub 그리고 수식 [10] file 에드 2012.02.05 27011



XE Login