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 조회 수:2475

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

요즘 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 34301
공지 KTUG 사설저장소 브라우저 베이드프즈 2017.07.16 37818
공지 장애 복구 안내 [9] 관리자 2017.05.04 40258
공지 TeX Live 2016 설치 안내 [7] 관리자 2016.06.05 73772
644 KTUG mystery [3] 세벌 2015.06.12 1520
643 Introduction to LaTeX:라텍 입문 [6] JangNa 2015.06.11 1694
642 게임 트리 그리기 1-1 [14] file ischo 2015.06.10 2149
641 게임 트리 그리기 1 [10] file ischo 2015.06.09 1700
640 코딩의 즐거움: 제1차 라텍 스터디 과제 [19] nanim 2015.06.09 1767
639 주변에서 LyX에 대한 반응 [12] 하늘연 2015.06.09 1736
638 편집하지 않으면 표절 [1] yihoze 2015.06.09 1366
637 lshort Support for Korean KTUG 궁금증... [22] 세벌 2015.06.09 1906
636 pdf 다루는 무료 프로그램 세벌 2015.06.08 1373
635 예의에 대해서 [16] 멀리본다 2015.06.08 1561
634 제가 좀 까칠하기는 하죠? [3] 세벌 2015.06.08 1563
» ksbaduk 패키지 이야기(1): 흰돌과 검은돌 [7] file nanim 2015.06.06 2475
632 Thank you, Hermann Zapf [8] 에드 2015.06.06 1589
631 lshort 다음 버전 미리보기 [12] 세벌 2015.06.05 1601
630 [동영상] 한 방 yihoze 2015.06.05 1384
629 [동영상] 소설가에게 필요한 마크업들은? [1] yihoze 2015.06.05 1386
628 TeX 디자인, 끝까지 밀어붙이기 [12] file 하늘연 2015.06.03 1628
627 텍의 기본기 [2] yihoze 2015.06.03 1527
626 테크니션들의 익살 [4] yihoze 2015.06.03 1366
625 개행(line-break)에 대하여 [8] yihoze 2015.06.02 4317



XE Login