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

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

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

2015.06.06 22:38

nanim 조회 수:4340

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

요즘 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를 정의하세요.

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

번호 제목 글쓴이 날짜 조회 수
공지 장애 복구 안내 [9] 관리자 2017.05.04 98853
942 대화형 인용문에 대하여 [2] file noname 2020.10.28 31
941 latex 템플릿 만들어주실 프리랜서분 구합니다. [1] ysn 2020.10.23 80
940 함초롬 바탕 LVT의 "키보드" 부호 [4] file noname 2020.10.15 254
939 Graphviz [10] file yihoze 2020.10.05 372
938 어제부로 부하 분산에 참여한 신규 CTAN 미러에서 인사 드립니다 ( _ _)/ [14] 배 성호 2020.07.30 1047
937 KTUG 사설저장소 브라우저 [1] 베이드프즈 2017.07.16 91211
936 수식 이미지를 Latex 수식으로 변경해주는 사이트입니다. [4] file SMC 2020.08.29 700
935 한글날 기념, TeX 세상의 한글 2020 [4] file noname 2020.10.09 302
934 574돌 한글날, 발표된 글꼴들 [1] likesam 2020.10.09 249
933 [연습] 다음 결과물은 어떻게 만들 수 있을까? [8] file ChoF 2010.03.15 30172
932 LaTeX으로 편집한 고전 출간 알림 [4] file 판돌이 2020.10.08 264
931 PDF 파일을 열지 않고 페이지 수 알아내기 [8] file yihoze 2020.09.22 442
930 만 단위 이름 붙이기와 문학적 프로그래밍? file noname 2020.09.18 345
929 `KTUG 사설저장소 브라우저'에 대하여 [1] noname 2020.09.16 363
928 폰트를 설치했는데 텍이 찾지 못할 때 [2] file yihoze 2020.09.11 458
927 clist sorting [2] file yihoze 2020.09.09 396
926 안녕하세요 lshort-kr 오타를 찾은 것 같습니다. [2] file 텍초보 2020.09.09 316
925 oblivoir의 chaptertoc [4] noname 2020.05.15 1085
924 TeX Template 제작을 의뢰하고 싶습니다. [3] 경문사 2020.08.03 690
923 지그재그 [6] file yihoze 2020.07.27 752



XE Login