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

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

자유글 ksbaduk 패키지 이야기(1): 흰돌과 검은돌

2015.06.06 22:38

nanim 조회 수:2684

원래 이런 글은 재미도 없고 쓸 생각이 없었는데요,

요즘 ktug 분위기가 뭔가 뒤숭숭해보여서 글 하나라도 써야될 거 같더라고요.
얼마 전에 ksbaduk이라는 패키지를 하나 제작했는데, 코드 전체에 대해 해설하면 좋겠지만 그 역시 재미도 없을 거고,
몇몇 군데 저 스스로 코딩하면서 재미있었다고 생각한 부분을 한 두어 차례 코드 해설 겸해서 연재하려 합니다.
(반응이 없으면... 바로 중단...)
첫 글은 가장 기본적인 흑돌/백돌 그리기에 대한 거구요.

==========

"잠수탔던 하수"께서 어느날 수면 위로 부상하시어서 재미있는 문서를 하나 보여주셨습니다.
디씨인사이드 바둑갤에서도 활동하시는 듯. 그곳에서 연재되었던 "병국세해"라는 글을 모아서 pdf책으로 제작한 거였더랬죠.
"그림은 TikZ로 그렸다"고 하셔서 소스를 보여주실까 내심 기대했는데, 안 보여주시더라구요.
그래서... "이런 그림은 어떻게 그릴 수 있을까?" 생각하다가 한 번 해보게 된 것이었어요.
잠/하 님께 감사드립니다. 그 책이 아니었으면 이런 작업은 시작되지도 않았을 거여요.

==========

일단 바둑판 자체를 그리는 거야... 뭐... 간단하였습니다. 계산을 쉽게 하기 위하여 선 사이를 모두 1(cm)로 하고,
tikzpicture 환경을 scaling하는 방식으로 해보았습니다.

\begin{tikzpicture}[scale=0.5]
\foreach \i in {2.5,3.5,...,18.5} \draw (\i,1.5) -- (\i,19.5);
\foreach \j in {2.5,3.5,...,18.5} \draw (1.5,\j) -- (19.5,\j);
\foreach \i in {4.5,10.5,16.5} \foreach \j in {4.5,10.5,16.5} \filldraw (\i,\j) circle (3pt);;
\end{tikzpicture}

왼쪽 하단을 (0,0)으로 하고 오른쪽 상단을 (19,19)로 해서, 
0.5, 1.5, 2.5, 3.5... 18.5로 가로세로 선을 그으면 끝이죠.
나중에 좌표 이름을 붙이도록 하라고 하셔서 이것을 (1,1)에서 (20,20)으로 바꿨지만 기본적으로는 동일합니다.
위의 코드만 실행하면 외곽선이 안 나올텐데, 그건 조금 두껍게 rectangle로 그려주면 돼요. (1.5,1.5)--(19.5,19.5)로 하는 거죠.
(직접 해보시기 바랍니다.)
마지막의 3포인트짜리 채운 원은 화점과 천원을 그린 거고요.
처음 보시는 분들은 tikz의 \foreach문이 얼마나 강력한지 주의깊게 보시면 되겠네요.

==========

이제 흰돌 하나를 그리려고 합니다. 좌하귀 화점의 좌표는 (D4). 이곳에 적당한 반지름을 가진 circle을 filldraw하면 되겠지요.
(D4)는 가만히 생각해보면 (4,4)란 말이거든요. 그런데 위에서 그린 바둑판 (1,1)--(20,20)에서 이 점의 좌표는 어디일까요?
tikz로 그린 tikzpicture 영역에서 좌표계는 1사분면과 같은 방식으로 매겨지니까, (4,4)를 (4.5,4.5)에 대응시킬 수 있습니다.

\filldraw (4.5,4.5) circle (0.45);

반지름의 길이가 0.5가 되면 나란히 놓인 돌이 맞닿게돼요. 그러니 0.5보다 조금 작게 그리는 것이 좋습니다.
그리는 것 자체는 어렵지 않네요. 다만 이것을 같은 tikzpicture 속에서 그려야 하니까 overlay하는 게 좋겠죠.

여기까지 하면, 바둑판 위에 바둑알을 그리는 것이 가능해집니다. filldraw에 색상만 정해주면 흰돌도 그릴 수 있네요.

\filldraw [fill=white,draw=black] (16.5,16.5) circle (0.45);

참 쉽죠?

이제 문제는 사용자 입력 명령입니다. \White{Q16}, \Black{D4} 이런 식으로 입력하고 싶단 말이죠.
규칙은 알파벳이 먼저 오고 그 뒤에 한 자리 또는 두 자리 숫자가 따라붙습니다.
다행히 알파벳이 두 글자 이상 되는 건 없으니까요, 다음처럼 하기로 했습니다.
(TeX 코딩은 사실 아이디어와의 싸움입니다. 언어 자체보다 해결방법이 더 중요하지요.)
  1. 이 token list의 첫 글자를 떼어내서 이것을 숫자로 변환한다.
  2. 첫 글자를 떼고 남은 글자들을 숫자로 간주한다.
이렇게 하면 숫자 두 개를 얻을 수 있어요. 여기에 각각 0.5씩 더하면 그려야 할 좌표가 나온다는 것입니다.

문자를 숫자로 변환하는 것이 또 문제였는데요, 처음에는 \int_from_alph:n 이라는 함수를 써보려고 했습니다.
이것도 괜찮긴 한데 두 가지 문제가 있더라고요, 하나는 이 함수를 변수와 결합하여 다른 함수로 처리할 때의 확장 문제가 골치아파요.
두 번째는 A-H까지는 이걸로 얻은 숫자를 그냥 써도 되는데 J-T까지는 1씩 줄여줘야 한다는 거였죠. (왜냐면 I를 안 쓰니까)
그래서 쉽게 가기로 했습니다. \str_case:nn으로 문자를 검사하기로 한 거죠. 특별한 트릭이 없기 때문에 간명하고요.

\str_case:nn { \l_tmpa_tl }
{
   { D } { \int_set:Nn \x_pos_int { 4 } }
   { Q } { \int_set:Nn \x_pos_int { 16 } }
}

위의 루틴을 \firstchar_to_int:n 이라고 정의하고 \White 명령을 만들어봅니다.
이 코드에서 \exp_args: 어쩌구는 인자를 확장하는 명령인데 나중에 설명할 수 있는 기회가 있기를 바랍니다.
이걸 무시하면 이 코드가 무슨 일을 하는지 금방 알 수 있을 겁니다.

\NewDocumentCommand \White { m }
{
   \exp_args:Nx \firstchar_to_int:n { \tl_head:n { #1 } }   %% 첫 글자만 \firstchar_to_int:n 에게 먹입니다.
   \exp_args:NNx \int_set:Nn \y_pos_int { \tl_tail:n { #1 } }  %% 남은 숫자를 \y_pos_int로 설정합니다.
   \filldraw [ fill=white, draw=black, overlay ] 
      ( \fp_eval:n { \x_pos_int + 0.5 } , \fp_eval:n { \y_pos_int + 0.5 } ) circle (0.45);
}

위에 그린 바둑판 위에 \White{D4}를 놓아봤습니다. 첨부 그림처럼 되었네요.
스크린샷 2015-06-06 오후 10.24.44.png

=======


지금까지 한 것의 소스를 첨부했습니다. (lsbd-1.tex)

========

[연습문제(초급)]: 만약 \White{4D} 또는 \Black{15Q}와 같이 입력받으려면 어떻게 해야 할까요?
이와 같이 입력받아서 바둑돌을 그리는 명령을 정의해주세요.

[연습문제(중급)]: 입력이 \White{4D} 또는 \White{D4} 어떤 식으로 입력되더라도 같은 위치에 바독돌을 그리게 하는 명령 \White를 정의하세요.

좋은 답안을 제출해주시면 뭔가 있을는지... 없을는지... 도...

번호 제목 글쓴이 날짜 조회 수
공지 2019 한국텍학회 제12차 정기총회 및 학술대회 [2] yihoze 2019.01.04 37423
공지 KTUG 사설저장소 브라우저 베이드프즈 2017.07.16 40825
공지 장애 복구 안내 [9] 관리자 2017.05.04 43342
공지 TeX Live 2016 설치 안내 [7] 관리자 2016.06.05 77167
866 크기가 다른 PDF 합치기 [1] yihoze 2019.08.06 146
865 expl3 학습자료 file noname 2019.08.18 61
864 최현배 한글 풀어쓰기 [13] file Tzetachi 2019.04.13 4464
863 메무아 매뉴얼 서문의 1890년대풍 번역 [4] file noname 2019.07.16 519
862 \vsplit : 수직 박스 쪼개기 [6] DohyunKim 2011.07.06 2620
861 TeX Template 제작이 가능한 분을 찾고 있습니다. 윤세은 2019.07.15 443
860 stackexchange.com sourceforge.net 등의 도메인은 게시물에 사용하실 수 있습니다. 관리자 2019.07.10 1405
859 MathJax를 이용하여 웹에서 수식을 써 봅시다 [25] file 샘처럼 2010.12.29 128678
858 루비 [5] file noname 2019.05.22 2338
857 LuaLaTeX을 활용한 고서적 조판 [8] file 옛한글 2019.06.13 1874
856 parallel pages, parallel columns, and progress [7] file noname 2019.05.30 1985
855 TexLive 2019 릴리즈 [7] Dennis 2019.05.02 3631
854 [소식] lshort korean 2019 릴리스 [6] noname 2019.05.08 2573
853 grruby와 "선언서" [2] file noname 2019.05.17 2282
852 TeX Live 2019와 xindex [3] file noname 2019.05.04 2465
851 [Expl3] 소인수분해 [3] file noname 2019.04.28 2526
» ksbaduk 패키지 이야기(1): 흰돌과 검은돌 [7] file nanim 2015.06.06 2684
849 이분.. 양반은 못되시는듯 합니다... [1] 불량양파 2019.03.23 2925
848 논문쓰실 때 LaTex 이용하시는 분들 괜찮은 워크샵이 있는 것 같아서 공유드려요! [5] 소미 2019.02.18 3246
847 파이데이 이야기 [1] file noname 2019.03.14 2582



XE Login