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

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

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

2015.06.06 22:38

nanim 조회 수:436

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

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

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

번호 제목 글쓴이 날짜 조회 수
공지 [안내] 2018 한국텍학회 정기총회 및 학술대회 [8] yihoze 2018.01.01 2068
공지 KTUG 사설저장소 브라우저 베이드프즈 2017.07.16 1285
공지 장애 복구 안내 [9] 관리자 2017.05.04 1680
공지 TeX Live 2016 설치 안내 [7] 관리자 2016.06.05 20044
698 호와 원 [1] file yihoze 2018.07.31 118
697 jupyter 의 smalltalk 버전이 있네요. 불량양파 2018.07.28 98
696 설문: 레이텍 과정 [31] yihoze 2018.07.04 734
» ksbaduk 패키지 이야기(1): 흰돌과 검은돌 [8] file nanim 2015.06.06 436
694 TeX Live 2018 [5] 지나가다 2018.04.28 1534
693 latex 에디터 Gummi 소개입니다. [9] file guest 2011.05.01 43506
692 memoir(oblivoir) + tikzpagenodes 호환을 위한 삽질기 [7] file Kriss 2018.04.10 1032
691 [TL2014] [win32] 한글 파일 이름 문제 해결(?) [12] DohyunKim 2014.07.09 6283
690 KTUG 사설 TL 저장소 소식​ [26] DohyunKim 2014.04.26 6635
689 윈도우에서 LyX 2.0 설치시 오류 날 경우 [1] file min-j 2013.09.08 19839
688 ‘나눔옛한글’과 ‘나눔바른펜’ 공개 [4] 에드 2014.10.03 4546
687 TeX Live 2018 출시 일정이 나왔네요. Dennis 2018.03.10 957
686 lilypond와 LaTeX [2] file cantabile 2018.03.05 644
685 [참가신청] 문서작성 워크숍 2017 [3] ischo 2017.10.17 1338
684 MathJax를 이용하여 웹에서 수식을 써 봅시다 [22] file 샘처럼 2010.12.29 123333
683 한국 TeX 사용자 페북 그룹 [2] yihoze 2017.11.21 872
682 11월 15일에 후원해주신 분 [2] yihoze 2017.11.20 386
681 Tikz 그림들을 삽입하기 [1] file yihoze 2017.11.20 746
680 국내의 새 CTAN 미러를 찾았습니다. [4] 베이드프즈 2017.10.11 760



XE Login