% \iffalse meta-comment %% %% 文件:weiqi.dtx %% %% ç‰ˆæƒ (C) 2023-2024 By Ms_yam %% %% 它å¯ä»¥åœ¨ LaTeX 项目公共许å¯ï¼ˆLPPL)1.3c åŠä¹‹åŽçš„ä»»æ„版本(éšä½ çš„æ„è§ï¼‰ä¸‹åˆ†å‘或修改。 %% 这个许å¯çš„最新版本在如下文件ä¸ï¼š %% %% https://www.latex-project.org/lppl.txt %% %% 本å®åŒ…ä¸ºä½œè€…ç»ƒä¹ epxl3 和编写 dtx 文件所编写,里é¢çš„接å£åŠæ–¹æ³•å¹¶ä¸æ˜¯æœ€ä¼˜çš„。 %% ä»…ä¾›å‚考。 %% % \fi % % \iffalse %<*driver> \documentclass[full]{l3doc} \usepackage{weiqi} % 创建代ç 示例 \usepackage{listings} \ExplSyntaxOn \makeatletter \lst@RequireAspects{writefile} \box_new:N \l__demo_box \lstnewenvironment{demo}[1][code and example] { \use:c { demo_#1: } } { \use:c { demo_#1_end: } } \cs_new:Nn \__demo_common: { \setkeys{lst} { basicstyle = \ttfamily, gobble = 2, language = [LaTeX]{TeX}, } } \cs_new:Nn \__demo_input: { \catcode`\^^M = 10\relax \catcode`\% = 14\relax \input{\jobname.tmp} } \cs_new:Npn \__demo_init:nnn #1#2#3 { \cs_set:cn {demo_#1:} { #2 } \cs_set:cn {demo_#1_end:} { #3 } } \__demo_init:nnn{code and example} {% \hbox_set:Nw \l__demo_box \__demo_common: \lst@BeginAlsoWriteFile{\jobname.tmp}% } {% \lst@EndWriteFile \hbox_set_end: %\begin{center} \fp_compare:nNnTF { \box_wd:N \l__demo_box } > { 0.6 * \linewidth } { \begin{minipage}{\linewidth} \box_use:N \l__demo_box \end{minipage}% \par \begin{minipage}{\linewidth} \__demo_input: \end{minipage} } { \begin{minipage}{0.40\linewidth} \__demo_input: \end{minipage}% %\hfil \begin{minipage}{0.54\linewidth} \box_use:N \l__demo_box \end{minipage}% } %\end{center} } \makeatother \ExplSyntaxOff % ^^A æ·»åŠ ä¸æ–‡æ”¯æŒåŠè®¾ç½®è¶…级链接 \usepackage[UTF8,hyperref]{ctex} \hypersetup{ colorlinks, linkcolor=blue, hyperindex, pdfstartview=FitH, plainpages=false, backref, } % ^^A 引用待办包 \usepackage{todo} % ^^A 汉化 l3doc 的部分定义 \NewDocumentEnvironment { texnote } { }% ä¸èƒ½ç”¨ Renew...ï¼ŒåŽŸå› æœªçŸ¥ { \endgraf \vspace{0.5em}% 3mm => 0.5em \small\textbf{\TeX{} 黑客笔记:}% \TeX~hackers~note: } { \vspace{0.5em}% 3mm => 0.5em } \begin{document} \DocInput{\jobname.dtx} \todos % ^^A 列出待办事宜 \end{document} %</driver> % \fi % % \title{^^A % \pkg{weiqi}å®åŒ…:绘制围棋棋谱^^A % } % % \author{Ms\_yam\thanks % {^^A % 本å®åŒ…æ˜¯ä½œè€…ç»ƒä¹ \LaTeX3 和编写 dtx 文件的作å“,里é¢çš„接å£åŠæ–¹æ³•å¹¶æœªä¼˜åŒ–;但å®åŒ…æ¼æ´žä¼šå°½åŠ›ä¿®å¤ã€‚ % }^^A % \ (\href{mailto:Ms_yam@163.com}{Ms\_yam@163.com})^^A % } % \date{\zhdigits*{2024}å¹´\zhnumber{02}月\zhnumber{22}æ—¥} % % \maketitle % % \DoNotIndex{\[,\\,\]} % \DoNotIndex{\Large, \meta, \noindent, \textbf, \texttt} % \DoNotIndex{\ExplSyntaxOn, \ExplSyntaxOff, \NeedsTeXFormat, \RequirePackage, \ProvidesExplPackage, \NewDocumentCommand} % \DoNotIndex{\IfBooleanT, \IfBooleanF, \IfNoValueTF} % \DoNotIndex{\bool_new:N, \bool_set_eq:NN, \bool_set_false:N, \bool_set_inverse:N, \bool_set_true:N, \bool_to_str:N} % \DoNotIndex{\bool_gset_eq:NN, \bool_gset_false:N, \bool_gset_true:N} % \DoNotIndex{\bool_if:nT, \bool_if:NT, \bool_if:nTF, \bool_if:NTF} % \DoNotIndex{\bool_lazy_all:nT, \bool_lazy_all:nTF, \bool_lazy_and:nnT, \bool_lazy_and:nnTF} % \DoNotIndex{\bool_lazy_any:nTF, \bool_lazy_or:nnT, \bool_lazy_or:nnF, \bool_lazy_or:nnTF} % \DoNotIndex{\box_ht:N, \box_wd:N} % \DoNotIndex{\clist_new:N, \clist_const:Nn, \clist_clear:N, \clist_set:Nn, \clist_set_eq:NN, \clist_set_from_seq:NN, \clist_pop:NN, \clist_use:Nn} % \DoNotIndex{\clist_gclear:N, \clist_gput_right:Nn, \clist_set_eq:Nc, \clist_gset_eq:NN, \clist_gset_eq:cN} % \DoNotIndex{\clist_if_empty:NTF, \clist_map_function:NN, \clist_map_inline:Nn} % \DoNotIndex{\color_fill:n, \color_select:n} % \DoNotIndex{\cs_new:Nn, \cs_new:Npn, \cs_generate_variant:Nn, \cs_if_free:cT, \cs_if_free:cTF} % \DoNotIndex{\draw_begin:, \draw_end:, \draw_linewidth:n, \draw_path_circle:nn, \draw_path_lineto:n, \draw_path_moveto:n} % \DoNotIndex{\draw_box_use:Nn, \draw_path_use_clear:n, \draw_transform_scale:n} % \DoNotIndex{\fp_new:N, \fp_set_eq:NN, \fp_set:Nn, \fp_add:Nn,\fp_sub:Nn, \fp_compare:nNnT, \fp_compare:nNnTF, \fp_gset:Nn, \fp_use:N} % \DoNotIndex{\group_begin:, \group_end:} % \DoNotIndex{\hbox_set:Nn} % \DoNotIndex{\int_new:N, \int_new:c, \int_const:Nn, \int_set_eq:NN, \int_set_eq:Nc, \int_set:Nn, \int_set:Ne, \int_add:Nn, \int_incr:N, \int_use:N} % \DoNotIndex{\int_gset:Nn, \int_gset:Ne, \int_gincr:N, \int_gset_eq:NN, \int_gset_eq:Nc, \int_gset_eq:cN} % \DoNotIndex{\int_max:nn, \int_min:nn, \int_sign:n, \int_abs:n, \int_from_alph:n, \int_from_alph:e, \int_to_alph:n, \int_to_Alph:n} % \DoNotIndex{\int_case:nn, \int_compare_p:n, \int_compare_p:nNn, \int_compare:nNnT, \int_compare:nNnF, \int_compare:nNnTF} % \DoNotIndex{\int_if_zero:nF, \int_if_zero:nTF, \int_step_inline:nn, \int_step_inline:nnnn} % \DoNotIndex{\intarray_new:Nn, \intarray_new:cn, \intarray_gset:Nnn, \intarray_gset:cnn, \intarray_gzero:N, \intarray_item:Nn, \intarray_item:cn} % \DoNotIndex{\ior_open:Nn, \ior_close:N, \ior_str_map_inline:Nn} % \DoNotIndex{\prg_set_conditional:Npnn, \prg_return_false:, \prg_return_true:, \prg_generate_conditional_variant:Nnn, \prg_break_point:, \prg_break:} % \DoNotIndex{\regex_match:nn, \regex_match:nnTF, \regex_match:nVTF, \regex_extract_all:nnN} % \DoNotIndex{\regex_extract_once:nnN, \regex_extract_once:nVN, \regex_extract_once:nnNTF, \regex_extract_once:nVNTF} % \DoNotIndex{\seq_new:N, \seq_new:c, \seq_put_right:Nn, \seq_item:Nn, \seq_gclear:N, \seq_gset_item:Nnn, \seq_gset_item:NnV} % \DoNotIndex{\seq_if_in:NnT, \seq_if_in:NnF, \seq_if_in:NnTF} % \DoNotIndex{\str_new:N, \str_const:Nn, \str_set:Nn, \str_set:NV, \str_set:Nx, \str_set_eq:NN} % \DoNotIndex{\str_put_right:Nn, \str_put_right:NV, \str_put_right:Nx} % \DoNotIndex{\str_gset_eq:NN} % \DoNotIndex{\str_head:N, \str_item:Nn, \str_range:Nnn, \str_range:nnn, \str_tail:N, \str_lowercase:n} % \DoNotIndex{\str_if_empty_p:N, \str_if_empty:NTF, \str_if_empty:nTF, \str_if_eq_p:nn, \str_if_eq_p:Vn, \str_if_eq:nnTF} % \DoNotIndex{\str_case:nn, \str_case_e:nn, \str_compare:eNeT, \str_compare:nNnTF, \str_compare:eNeTF} % % \begin{documentation} % % \section{\pkg{weiqi} 文档} % % 本å®åŒ…æ供了绘制围棋棋谱功能。本å®åŒ…å‚考(或延用)了 \pkg{igo} å®åŒ…的部分命令, % 但本å®åŒ…的实现完全采用 \pkg{expl3} æ–¹å¼ã€‚ % % 本å®åŒ…的绘图采用 \pkg{l3draw} å®åŒ…(2024-01-04 ç‰ˆï¼‰å®žçŽ°ï¼Œå› å‰è€…具有\emph{高度}å®žéªŒæ€§ï¼Œå› äº›æœ¬ % å®åŒ…也åŒæ ·å…·ä½“\emph{高度}实验性。 % % % \subsection{相关概念}^^A % % % \subsubsection{尺寸} % % 本å®åŒ…ä¸çš„ \meta{尺寸} 特指棋盘尺寸(å³ä¸€ä¸ªæ–¹å‘包å«å‡ 路),棋盘大å°ä¸º \meta{尺寸} x \meta{尺寸}。 % 本å®åŒ…支æŒçš„ \meta{尺寸} å–值为 $2$\~{}$26$,但通常建议使用 $9$ã€$13$ å’Œ $19$ 三ç§å°ºå¯¸ã€‚ % å…¶ä¸ï¼Œ$19$x$19$ ä¸ºæ ‡å‡†æ£‹ç›˜å¤§å°ï¼ˆä¹Ÿæ˜¯é»˜è®¤å¤§å°ï¼‰ã€‚ % % % \subsubsection{åæ ‡} % % 为方便æè¿°è½åä½ç½®ï¼Œæœ¬å®åŒ…ä¾æƒ¯ä¾‹é‡‡ç”¨ \meta{åæ ‡} 的概念。 % 本å®åŒ…支æŒä¸¤ç§å½¢å¼çš„ \meta{åæ ‡}:以左下角为起点(常规模å¼ï¼‰å’Œå·¦ä¸Šè§’为起点($SGF$ 模å¼ï¼‰ã€‚ % % 两ç§å½¢å¼çš„横åæ ‡ç›¸åŒï¼Œä»Žå·¦å¾€å³ä¾æ¬¡ä¸º $a$ã€$b$ã€\dots。它们的区别在于: % å‰è€…纵åæ ‡ä»Žä¸‹å¾€ä¸Šä¾æ¬¡ä¸º $1$ã€$2$ã€\dots;而åŽè€…的纵åæ ‡ä»Žä¸Šå¾€ä¸‹ä¾æ¬¡ä¸º $a$ã€$b$ã€\dots。 % å‰è€…是为便于人员交互设计,åŽè€…æ˜¯ä¸ºæ”¯æŒ $sgf$ 棋谱åæ ‡è€Œè®¾è®¡ã€‚ % % 横åæ ‡ä¸Žçºµåæ ‡ç»„åˆå½¢æˆ \meta{åæ ‡},如 |a1|ã€|dp| ç‰ã€‚ % é€šå¸¸éœ€è¦ \meta{åæ ‡} 的地方,也支æŒé€—å·åˆ—表形å¼çš„ \meta{åæ ‡} 集åˆï¼Œå¦‚ “|a2, b2, dp|â€ã€‚ % % \begin{minipage}{0.45\linewidth} % \newweiqi % \showweiqi[a1,e4] % \end{minipage}% % \begin{minipage}{0.45\linewidth} % \sgflocmode % \showweiqi[aa,ed] % \end{minipage}\\ % % % \subsubsection{虚ç€} % % 围棋有一个比较特殊的规则:它å…许一方åœä¸€æ‰‹ï¼ˆä¹Ÿå«è™šç€ï¼‰ï¼Œå¦ä¸€æ–¹ç»§ç»ä¸‹ã€‚ % 为了以统一的方å¼è®°å½•æ¯ä¸€æ‰‹æ£‹ï¼Œç‰¹å°†è™šç€çš„ \meta{åæ ‡} 定义为 |-| 或 |pass|。 % % \subsection{基本命令}^^A % % % \begin{function}{\newweiqi} % \begin{syntax} % \cs{newweiqi} [\meta{尺寸}] % \end{syntax} % åˆå§‹åŒ–新对局,\meta{尺寸}用于指定棋盘大å°ï¼ˆé»˜è®¤ä¸º $19$)。 % 带星å·ç‰ˆæœ¬åŒæ—¶æ›´æ”¹ \meta{尺寸} 的默认值。 % \end{function} % % % \begin{function}{\weiqisize} % \begin{syntax} % \cs{weiqisize} \Arg{尺寸} % \end{syntax} % 修改棋盘大å°ä¸º \meta{尺寸}。 % 带星å·ç‰ˆæœ¬åŒæ—¶æ›´æ”¹ \meta{尺寸} 的默认值。 % \begin{texnote} % 修改棋盘尺寸ä¸ä¼šæ£€æŸ¥å·²æœ‰æ£‹å是å¦è¶Šç•Œã€‚ % åŒæ—¶è¿˜ä¼šå¼•å‘已有的 \meta{åæ ‡}为 $SGF$ 模å¼çš„棋åçš„ä½ç½®é”™ä¹±ã€‚ % \end{texnote} % \end{function} % % % \begin{function}{\weiqiblack, \weiqiwhite} % \begin{syntax} % \cs{weiqiblack} [\meta{æ ‡ç¾}] \Arg{åæ ‡} % \end{syntax} % å‘当å‰å¯¹å±€ä¸æ·»åŠ 棋å。 % å…¶ä¸ï¼Œå¦‚æžœ \meta{æ ‡ç¾} 为手数,则会自动递增且切æ¢é»‘白方。 % 如果 \meta{æ ‡ç¾} 为 $0$,则ä¸æ˜¾ç¤ºæ ‡ç¾ä½†ä»åˆ‡æ¢é»‘白方。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€æ‰‹æ£‹ï¼› % 默认以左下角的 \meta{åæ ‡} 为 $a1$;虚ç€è¯·ä½¿ç”¨ $-$ã€|pass| 或留空。 % \end{function} % % % \begin{function}{\weiqidie} % \begin{syntax} % \cs{weiqidie} \Arg{åæ ‡} % \end{syntax} % 设置指定ä½ç½®çš„棋å为æ»å。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€ä¸ªä½ç½®ã€‚ % \begin{texnote} % æ»å是之å‰å·²ç»ä¸‹è¿‡çš„棋åï¼Œå› ä¸ºæ²¡æœ‰æ°”ï¼Œæ‰€ä»¥éœ€è¦ä»Žæ£‹ç›˜æ‹¿èµ°ã€‚ % å°†æ²¡æœ‰æ ‡ç¾çš„棋åæ ‡è®°ä¸ºæ»å是没有æ„义的。 % \end{texnote} % \end{function} % % % \begin{function}{\showweiqi} % \begin{syntax} % \cs{showweiqi} [\meta{区间}] % \end{syntax} % 绘制对局。如果指定 \meta{区间},则 \meta{区间} 应由两个角点åæ ‡æˆ– |full| 组æˆï¼Œä»¥ç¤ºæŒ‡å®šåŒºé—´å†…çš„ä¿¡æ¯ï¼› % 如未指定区间,则会自动计算范围,该范围å¯ä¿è¯è‡³å°‘包å«ä¸€ä¸ªè§’,其余边至少余一路。 % 默认情况显示完æˆåŽä¼šæ¸…除对局,使用星å·å‘½ä»¤å¯ä¿ç•™å¯¹å±€ã€‚ % \begin{texnote} % 自动计算的范围会考虑最å°æ˜¾ç¤ºå¤§å°ï¼›å¦‚果指定区间,则ä¸å—æ¤é™åˆ¶ã€‚区间外内容ä¸ä¼šæ˜¾ç¤ºã€‚ % \end{texnote} % \end{function} % % \begin{demo} % \newweiqi % \weiqiblack[0]{bq,dq,-} % \weiqiwhite[1]{b2,c2,c3,a2,d2,b1} % \weiqiwhite[7]{-,b2} % \weiqidie{b2} % \showweiqi % \end{demo}\\ % % % æ»åå’Œå¸¦æ ‡ç¾ï¼ˆé€šå¸¸ä¸ºæ‰‹æ•°ï¼‰è™šç€ä¼šç»˜åˆ¶åœ¨æ£‹ç›˜ä¸‹æ–¹ï¼›ä¸å¸¦æ ‡ç¾çš„虚ç€åˆ™ä¸ä¼šç»˜åˆ¶ï¼ˆå› 为它没有任æ„实际æ„义)。 % % \subsection{æ ‡ç¾ä¸ŽæŒ‡ç¤ºç‚¹}^^A % % % \begin{function}{\weiqilabel, \clearlabel} % \begin{syntax} % \cs{weiqilabel} [\meta{æ ‡ç¾}] \Arg{åæ ‡}\\ % \cs{clearlabel} % \end{syntax} % å‘当å‰å¯¹å±€ä¸æ·»åŠ æ ‡ç¾ï¼Œæˆ–清除对局ä¸çš„æ‰€æœ‰æ ‡ç¾ã€‚ % å…¶ä¸ï¼Œå¦‚æžœ \meta{æ ‡ç¾} 为手数,则会自动递增。\meta{æ ‡ç¾} 默认为 $a$。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€ä¸ªæ ‡ç¾ã€‚ % 带星å·ç‰ˆæœ¬åœ¨æ·»åŠ æ ‡ç¾çš„åŒæ—¶ä¼šåˆ é™¤æ—§çš„æ ‡ç¾ã€‚ % \begin{texnote} % 如果 \meta{æ ‡ç¾} 为 $0$ 或为空(|[]|),则显示实心空白圆。 % \meta{åæ ‡} 规则与棋å一致,本规则在所有 \meta{åæ ‡} ä¸ç”Ÿæ•ˆã€‚ % \end{texnote} % \end{function} % % % \begin{function}{\weiqired, \weiqigreen, \weiqiblue, \clearpoint} % \begin{syntax} % \cs{weiqired} \Arg{åæ ‡}\\ % \cs{clearpoint} % \end{syntax} % å‘当å‰å¯¹å±€ä¸æ·»åŠ 指示点,或清除所有指示点。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€ä¸ªç‚¹ã€‚ % 带星å·ç‰ˆæœ¬åœ¨æ·»åŠ æ ‡ç¾çš„åŒæ—¶ä¼šåˆ 除旧的指示点(å«å…¶å®ƒé¢œè‰²ï¼‰ã€‚ % \end{function} % % % \begin{demo} % \newweiqi % \weiqiblack{a2,-,b1,cq} % \weiqilabel[1]{c2,dq,-} % \weiqired{d2,e3,-} % \weiqigreen{b3} % \showweiqi[a1,e3] % \end{demo} % % % \subsection{棋盘设置}^^A % % % \begin{function}{\weiqirotate, \weiqimirror, \weiqiposition} % \begin{syntax} % \cs{weiqirotate} [\meta{角度}]\\ % \cs{weiqimirror} [\meta{é•œåƒè½´}]\\ % \cs{weiqiposition} [\meta{角度}] % \end{syntax} % 这三个命令用于设置棋盘的方ä½ï¼ˆæ—‹è½¬ã€é•œåƒåŠæŒ‡å®šæ–¹å‘)。 % å…¶ä¸ï¼Œå‰ä¸¤ä¸ªå‘½ä»¤æ˜¯åŸºäºŽå·²æœ‰æ–¹ä½çš„,最åŽä¸€ä¸ªåˆ™ä¸è€ƒè™‘当å‰æ–¹ä½ã€‚\\ % \meta{角度}以度为å•ä½ï¼ˆé€†æ—¶é’ˆæ–¹å‘),如未指定,默认分别为 $90$ 度(旋转)和 $0$ 度(指定方å‘)。 % \meta{é•œåƒè½´} 应当为 $x$ã€$y$ 或 $xy$(默认) 三者之一。\\ % 使用星å·å‘½ä»¤å¯ä½¿å½“å‰æ£‹ç›˜æ–¹ä½ä¸ºé»˜è®¤æ–¹ä½ã€‚ % \end{function} % % % \begin{function}{\weiqiscale} % \begin{syntax} % \cs{weiqiscale} [\meta{比例}] % \end{syntax} % 按 \meta{比例} 缩放棋盘。 如未指定,则æ¢å¤é»˜è®¤æ¯”例。 % 使用星å·å‘½ä»¤å¯ä½¿å½“å‰ç¼©æ”¾æ¯”例为默认缩放比例。缩放是基于原有比例的。 % \end{function} % % % \begin{function}{\weiqiminsize} % \begin{syntax} % \cs{weiqiminsize} \meta{宽度} \meta{高度} % \end{syntax} % 棋盘最å°æ˜¾ç¤ºå¤§å°ï¼ˆä»¥æ ¼å计),使用星å·å‘½ä»¤å¯ä½¿å½“å‰å¤§å°ä¸ºé»˜è®¤å€¼ã€‚ % \end{function} % % % \begin{function}{\nonelocmode, \normallocmode, \sgflocmode} % \begin{syntax} % \cs{nonelocmode} % \end{syntax} % 将棋盘åæ ‡æ˜¾ç¤ºæ–¹å¼è®¾ç½®ä¸ºï¼šä¸æ˜¾ç¤ºåæ ‡ã€å¸¸è§„模å¼åæ ‡å’Œ $SGF$ 模å¼åæ ‡ä¹‹ä¸€ã€‚ % å…¶ä¸ï¼Œé»˜è®¤ä¸ºå¸¸è§„模å¼ï¼Œä½¿ç”¨æ˜Ÿå·å‘½ä»¤å¯ä½¿å½“å‰è®¾ç½®ä¸ºé»˜è®¤å€¼ã€‚ % \end{function} % % ~\\ % \begin{demo} % \newweiqi % \weiqiblack[1]{a2,b2,c3,-,dr} % \weiqilabel[A]{dq} % \weiqirotate[180] % \weiqiscale[0.8] % \weiqiminsize{6}{5} % \sgflocmode % \showweiqi % \end{demo} % % % \subsection{棋局å¤ç”¨}^^A % % \begin{function}{\saveweiqi, \useweiqi} % \begin{syntax} % \cs{saveweiqi} [\meta{åºå·}] % \end{syntax} % ä¿å˜/使用对局(åªä¿ç•™å¯¹å±€ä¿¡æ¯ï¼Œæ£‹ç›˜æ–¹ä½ç‰ä¿¡æ¯ä¸ä¿å˜ï¼‰ã€‚ % \meta{åºå·} 是ä¿å˜çš„ä½ç½®åºå·ï¼ˆè‡ªç„¶æ•°ï¼ŒæŽ¨è $0$\~{}$26$)。 % 星å·ç‰ˆä½¿ç”¨å¯¹å±€ä¼šåˆ 除所有棋åæ ‡ç¾åŠæ ‡ç¾ã€‚ % \end{function} % % % \begin{function}{\weiqichange} % \begin{syntax} % \cs{weiqichange} \Arg{åæ ‡} % \end{syntax} % 切æ¢æŒ‡å®šä½ç½®çš„棋å的所属方(黑白方)。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€ä¸ªä½ç½®ã€‚ % \end{function} % % % \begin{demo} % \newweiqi % \weiqiblack[1]{a2,b2,c3,-,dr} % \weiqilabel[A]{dq} % \saveweiqi[1] % \newweiqi % \useweiqi*[1] % \weiqichange{dr} % \showweiqi % \end{demo} % % % \begin{function}{\weiqiremove} % \begin{syntax} % \cs{weiqiremove} \Arg{åæ ‡} % \end{syntax} % 移除指定ä½ç½®çš„所有棋å,移除åŽç›¸å½“于没有这一手棋。 % \meta{åæ ‡} 是一组表示棋åä½ç½®çš„逗å·åˆ†éš”列表,æ¯ä¸€é¡¹è¡¨ç¤ºä¸€ä¸ªä½ç½®ã€‚ % \begin{texnote} % 这与 \cs{weiqidie} 有本质的区别:\cs{weiqidie} æ—¨åœ¨æ ‡è®°æ»å(这手棋是真实å˜åœ¨çš„); % 而本命令是直接移除这手棋,主è¦æ˜¯ä»¥å¤ç”¨æ£‹å±€è€Œè®¾ç½®ã€‚ % \end{texnote} % \end{function} % % % \begin{demo} % \newweiqi % \weiqiblack[0]{bq,dq,-} % \weiqiwhite[1]{b2,c2,c3,a2,d2,b1} % \weiqidie{b2} % \weiqiremove{d2} % \weiqiwhite[5]{b4} % \sgflocmode % \showweiqi % \end{demo} % % % \begin{function}{\resetnumber} % \begin{syntax} % \cs{resetnumber} [\meta{起点}] % \end{syntax} % é‡ç½®å›´æ£‹æ‰‹æ•°ï¼Œ\meta{起点} 所在ä½ç½®çš„æ ‡ç¾è®¾ç½®ä¸º $1$,之åŽæ ‡ç¾ä¾æ¬¡é€’增,之å‰æ— æ ‡ç¾ï¼›é»˜è®¤ä»¥ç¬¬ $1$ 手为起点。 % \end{function} % % % \begin{demo} % \useweiqi*[1] % \resetnumber[2] % \showweiqi % \end{demo} % % \subsection{sgf 棋谱支æŒ}^^A % % % \begin{function}{\weiqisgf} % \begin{syntax} % \cs{weiqisgf} [\meta{æ ‡ç¾}] \Arg{文本} % \end{syntax} % 使用 |sgf| 棋谱 \Arg{文本} æ¥æŒ‡å®šæ£‹å。如果 \meta{æ ‡ç¾} 为手数,则会自动递增。 % \end{function} % % ~\\ % \begin{demo} % \newweiqi % \weiqisgf{;B[cc];W[dd]} % \weiqisgf[1]{;B[cd];W[dc];B[cb]} % \showweiqi % \end{demo} % % \begin{function}{\inputsgf} % \begin{syntax} % \cs{weiqisgf} [\meta{起点}] \Arg{文件} % \end{syntax} % 新建对局并输入指定棋谱。\meta{起点} 所在ä½ç½®çš„æ ‡ç¾è®¾ç½®ä¸º $1$,之åŽæ ‡ç¾ä¾æ¬¡é€’增,之å‰æ— æ ‡ç¾ï¼›é»˜è®¤ä»¥ç¬¬ $1$ 手为起点。 % \end{function} % % % \subsection{调试支æŒ}^^A % % \begin{function}{\weiqidata} % \begin{syntax} % \cs{weiqidata} % \end{syntax} % æ ¼å¼åŒ–输出内部å˜é‡æ•°æ®ã€‚带星å·ç‰ˆæœ¬ä¼šé¢å¤–输出边界å˜é‡ä¿¡æ¯ã€‚ % \end{function} % % \newweiqi % \weiqiblack[0]{bq,dq,-} % \weiqiwhite[1]{b2,c2,c3,a2,d2,b1} % \weiqidie{b2} % \weiqiremove{d2} % \weiqiwhite[5]{b4} % \weiqidata* % % \subsection{下一æ¥è®¡åˆ’}^^A % % ä¸æ–‡æ ‡ç¾çš„支æŒã€‚ % % \end{documentation} % % \begin{implementation} % % \newpage % % \section{\pkg{weiqi}实现} % % \subsection{åˆå§‹åŒ–ä¿¡æ¯} % % \begin{macrocode} %<*package> %<@@=weiqi> % \end{macrocode} % % å®åŒ…基本信æ¯ï¼š % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesExplPackage{weiqi}{2024-02-22}{0.1} {drawing weiqi using expl3} % \end{macrocode} % % éœ€è¦ l3draw å®åŒ…,以支æŒç»˜å›¾ï¼š % \begin{macrocode} \RequirePackage{l3draw}[2024-01-04] % \end{macrocode} % % å¼€å¯ expl3 模å¼ï¼š % \begin{macrocode} \ExplSyntaxOn % \end{macrocode} % % % \subsection{声明系统函数的å˜ä½“} % % \begin{macrocode} \cs_generate_variant:Nn \int_set:Nn { Ne } \cs_generate_variant:Nn \int_gset:Nn { Ne } \cs_generate_variant:Nn \int_from_alph:n { e } \cs_generate_variant:Nn \seq_gset_item:Nnn { NnV } \cs_generate_variant:Nn \regex_extract_once:nnN { nVN } \prg_generate_conditional_variant:Nnn \regex_match:nn { nV } { T, F, TF } \prg_generate_conditional_variant:Nnn \regex_extract_once:nnN { nVN } { T, F, TF } % \end{macrocode} % % \subsection{声明选项} % % \begin{macrocode} % 待实现 % \end{macrocode} % % % \subsection{定义常é‡} % % \begin{variable}{\c_@@_normal_size_int, \c_@@_mid_size_int, \c_@@_small_size_int, \c_@@_normal_star_clist, % \c_@@_mid_star_clist, \c_@@_small_star_clist } % 棋盘尺寸åŠå¯¹åº”星ä½åæ ‡ï¼š % \begin{macrocode} \int_const:Nn \c_@@_normal_size_int { 19 } \int_const:Nn \c_@@_mid_size_int { 13 } \int_const:Nn \c_@@_small_size_int { 9 } \clist_const:Nn \c_@@_normal_star_clist { d4, j4, p4, d10, j10, p10, d16, j16, p16 } \clist_const:Nn \c_@@_mid_star_clist { c3, g3, k3, c7, g7, k7, c11, g11, k11 } \clist_const:Nn \c_@@_small_star_clist { c3, k3, c7, k7 } % \end{macrocode} % \end{variable} % % % \begin{variable}{\c_@@_max_step_int, \c_@@_normal_mode_str, \c_@@_sgf_mode_str } % 支æŒçš„最大æ¥æ•°åŠåæ ‡æ˜¾ç¤ºæ¨¡å¼ï¼š % \begin{macrocode} \int_const:Nn \c_@@_max_step_int { 500 } \str_const:Nn \c_@@_normal_mode_str { normal } \str_const:Nn \c_@@_sgf_mode_str { sgf } % \end{macrocode} % \end{variable} % % % \subsection{定义å˜é‡} % % \subsubsection{棋盘信æ¯} % % 棋盘信æ¯åŒ…å«æ–¹ä½ï¼ˆ$x/y$æ–¹å‘åŠæ˜¯å¦äº’æ¢ä¸‰è€…决定)ã€æ¯”例ã€æœ€å°æ˜¾ç¤ºå¤§å°ï¼ˆé•¿ä¸Žå®½ï¼‰åŠåæ ‡æŽ§åˆ¶ï¼ˆæ˜¯å¦æ˜¾ç¤ºåŠåæ ‡æ¨¡å¼ï¼‰ã€‚ % 共有 $8$ 个å˜é‡æŽ§åˆ¶ï¼Œä¸”å‡å…·æœ‰å…¨å±€åŠæœ¬åœ°ä¹‹åˆ†ã€‚全局å˜é‡ä¸ºé»˜è®¤å€¼ï¼Œæœ¬åœ°ä¸ºå½“å‰å¯¹å±€çš„设置。 % % \begin{variable}{\g_@@_x_direction_int, \g_@@_y_direction_int, \g_@@_swap_xy_bool, % \g_@@_scale_fp, \g_@@_min_width_int, \g_@@_min_hight_int, \g_@@_show_loc_bool, % \g_@@_loc_mode_str} % 全局棋盘信æ¯ï¼š % \begin{macrocode} \int_new:N \g_@@_x_direction_int \int_new:N \g_@@_y_direction_int \bool_new:N \g_@@_swap_xy_bool \fp_new:N \g_@@_scale_fp \int_new:N \g_@@_min_width_int \int_new:N \g_@@_min_hight_int \bool_new:N \g_@@_show_loc_bool \str_new:N \g_@@_loc_mode_str % \end{macrocode} % \begin{macrocode} \int_gset:Nn \g_@@_x_direction_int { 1 } \int_gset:Nn \g_@@_y_direction_int { 1 } \bool_gset_false:N \g_@@_swap_xy_bool \fp_gset:Nn \g_@@_scale_fp { 1 } \int_gset:Nn \g_@@_min_width_int { 3 } \int_gset:Nn \g_@@_min_hight_int { 2 } \bool_gset_true:N \g_@@_show_loc_bool \str_gset_eq:NN \g_@@_loc_mode_str \c_@@_normal_mode_str % \end{macrocode} % \end{variable} % % \begin{variable}{\l_@@_x_direction_int, \l_@@_y_direction_int, \l_@@_swap_xy_bool, % \l_@@_scale_fp, \l_@@_min_width_int, \l_@@_min_hight_int, \l_@@_show_loc_bool, % \l_@@_loc_mode_str} % 本地棋盘信æ¯ï¼š % \begin{macrocode} \int_new:N \l_@@_x_direction_int \int_new:N \l_@@_y_direction_int \bool_new:N \l_@@_swap_xy_bool \fp_new:N \l_@@_scale_fp \int_new:N \l_@@_min_width_int \int_new:N \l_@@_min_hight_int \bool_new:N \l_@@_show_loc_bool \str_new:N \l_@@_loc_mode_str % \end{macrocode} % \end{variable} % % % \subsubsection{对局信æ¯} % % 对局信æ¯åŒ…括棋盘大å°ã€æ¥æ•°ã€æ£‹å/æ ‡ç¾çš„ä¿¡æ¯é›†ï¼ˆ$x/y$ åæ ‡ï¼Œæ£‹æ‰‹ï¼Œæ ‡ç¾ï¼‰ã€æ»å集(索引)åŠæŒ‡ç¤ºç‚¹é›†ï¼ˆä¸‰è‰²ï¼‰ç»„æˆã€‚ % å…± $10$ 个å˜é‡ï¼Œå¦åŠ 一个默认棋盘大å°ã€‚本å°èŠ‚çš„å˜é‡çš„å–值å‡ä¸ºåŽŸå§‹æ–¹ä½çš„å–值。 % % \begin{variable}{\g_@@_default_size_int} % 默认对局大å°ï¼š % \begin{macrocode} \int_new:N \g_@@_default_size_int \int_gset_eq:NN \g_@@_default_size_int \c_@@_normal_size_int % \end{macrocode} % \end{variable} % % \begin{variable}{\g_@@_size_int, \g_@@_step_count_int, \g_@@_x_intarray, % \g_@@_y_intarray, \g_@@_player_intarray, \g_@@_label_seq, \g_@@_die_seq} % 对局内容: % \begin{macrocode} \int_new:N \g_@@_size_int \int_new:N \g_@@_step_count_int \intarray_new:Nn \g_@@_x_intarray { \c_@@_max_step_int } \intarray_new:Nn \g_@@_y_intarray { \c_@@_max_step_int } \intarray_new:Nn \g_@@_player_intarray { \c_@@_max_step_int } \seq_new:N \g_@@_label_seq \seq_new:N \g_@@_die_seq % \end{macrocode} % \end{variable} % % % \begin{variable}{\g_@@_red_point_clist, \g_@@_green_point_clist,\g_@@_blue_point_clist} % 对局辅助指示点: % \begin{macrocode} \clist_new:N \g_@@_red_point_clist \clist_new:N \g_@@_green_point_clist \clist_new:N \g_@@_blue_point_clist % \end{macrocode} % \end{variable} % % % \subsubsection{边界信æ¯} % % 本å°èŠ‚çš„å˜é‡ä¸ºç»˜å›¾è¿‡ç¨‹ä¸ä½¿ç”¨çš„边界信æ¯å˜é‡ã€‚其是åæ ‡æ˜¯è€ƒè™‘æ–¹ä½ä¿¡æ¯çš„,但左å³ã€ä¸Šä¸‹åŠå¤§å°ä¸è€ƒè™‘。 % % 棋å区间(ä¸è€ƒè™‘延伸的信æ¯ï¼‰ï¼š % \begin{macrocode} \int_new:N \l_@@_x_min_int \int_new:N \l_@@_x_max_int \int_new:N \l_@@_y_min_int \int_new:N \l_@@_y_max_int % \end{macrocode} % % 棋盘边界(考虑延伸的信æ¯ï¼‰ï¼š % \begin{macrocode} \bool_new:N \l_@@_left_bool \bool_new:N \l_@@_right_bool \bool_new:N \l_@@_up_bool \bool_new:N \l_@@_down_bool \fp_new:N \l_@@_x_min_fp \fp_new:N \l_@@_x_max_fp \fp_new:N \l_@@_y_min_fp \fp_new:N \l_@@_y_max_fp % \end{macrocode} % % \subsubsection{其它å˜é‡} % % 通用信æ¯å˜é‡ï¼š % \begin{macrocode} \str_new:N \l_@@_label_str \int_new:N \l_@@_x_int \int_new:N \l_@@_y_int \int_new:N \l_@@_player_int \fp_new:N \l_@@_x_fp \fp_new:N \l_@@_y_fp \clist_new:N \l_@@_point_clist % \end{macrocode} % % 其它临时å˜é‡ï¼š % \begin{macrocode} \int_new:N \l_@@_tmp_int \str_new:N \l_@@_tmp_str \bool_new:N \l_@@_tmp_bool \seq_new:N \l_@@_tmp_seq % \end{macrocode} % % % \subsection{设置棋局的函数} % % \subsubsection{对局准备} % % 指定围棋大å°ã€åˆå§‹åŒ–对局的其余 $9$ 个å˜é‡ï¼ˆæ¸…空对局所有对局信æ¯ï¼‰åŠæ£‹ç›˜ä¿¡æ¯çš„ $8$ 个å˜é‡ï¼ˆä½¿ç”¨é»˜è®¤å€¼[全局å˜é‡])。 % % \begin{macro}{\@@_new_game:n} % åˆå§‹åŒ–对局信æ¯ï¼ˆ|#1| 棋盘大å°ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_new_game:n #1 { \int_set_eq:NN \l_@@_x_direction_int \g_@@_x_direction_int \int_set_eq:NN \l_@@_y_direction_int \g_@@_y_direction_int \bool_set_eq:NN \l_@@_swap_xy_bool \g_@@_swap_xy_bool \fp_set_eq:NN \l_@@_scale_fp \g_@@_scale_fp \int_set_eq:NN \l_@@_min_width_int \g_@@_min_width_int \int_set_eq:NN \l_@@_min_hight_int \g_@@_min_hight_int \bool_set_eq:NN \l_@@_show_loc_bool \g_@@_show_loc_bool \str_set_eq:NN \l_@@_loc_mode_str \g_@@_loc_mode_str % \end{macrocode} % \begin{macrocode} \int_gset:Ne \g_@@_size_int { #1 } \int_gset:Nn \g_@@_step_count_int { 0 } \intarray_gzero:N \g_@@_x_intarray \intarray_gzero:N \g_@@_y_intarray \intarray_gzero:N \g_@@_player_intarray \seq_gclear:N \g_@@_label_seq \seq_gclear:N \g_@@_die_seq % \end{macrocode} % \begin{macrocode} \clist_gclear:N \g_@@_red_point_clist \clist_gclear:N \g_@@_green_point_clist \clist_gclear:N \g_@@_blue_point_clist } % \end{macrocode} % \end{macro} % % % \subsubsection{åæ ‡è½¬æ¢å‡½æ•°} % % 实现棋ååæ ‡çš„åæ ‡å¯¹å½¢å¼ä¸Žå—符串形å¼ï¼ˆè™šç€ä½¿ç”¨ |-| )两者之间的转æ¢ã€‚ % % \begin{macro}{\@@_loc_to_xy:n, \@@_loc_to_xy:V} % 设置 $x$ã€$y$ åæ ‡å˜é‡ï¼ˆ|#1| åæ ‡ï¼Œæ”¯æŒä¸¤ç§æ¨¡å¼ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_loc_to_xy:n #1 { \str_set:Nx \l_tmpa_str { \str_lowercase:n { #1 } } \bool_lazy_any:nTF { { \str_if_empty_p:N \l_tmpa_str } { \str_if_eq_p:Vn { \l_tmpa_str } { - } } { \str_if_eq_p:Vn { \l_tmpa_str } { pass } } } { \int_set:Nn \l_@@_x_int { 0 } \int_set:Nn \l_@@_y_int { 0 } } { \int_set:Ne \l_@@_x_int { \int_from_alph:e { \str_head:N \l_tmpa_str } } \regex_match:nVTF { [a-z]{2} } { \l_tmpa_str } { \int_set:Ne \l_tmpa_int { \int_from_alph:e { \str_tail:N \l_tmpa_str } } \int_set:Nn \l_@@_y_int { \g_@@_size_int - \l_tmpa_int + 1 } } { \int_set:Ne \l_@@_y_int { \str_range:Nnn \l_tmpa_str { 2 } { 5 } } } } } % \end{macrocode} % \begin{macrocode} \cs_generate_variant:Nn \@@_loc_to_xy:n { V } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_xy_to_loc:N} % 将指定å˜é‡è®¾ç½®ä¸ºå½“å‰åæ ‡çš„å—符串形å¼ï¼ˆ|#1| 指定的å˜å‚¨å˜é‡ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_xy_to_loc:N #1 { \int_compare:nNnTF { \l_@@_x_int } = { 0 } { \str_set:Nn #1 { - } } { \str_set:Nx \l_tmpa_str { \int_to_alph:n { \l_@@_x_int } } \str_compare:eNeTF { \l_@@_loc_mode_str } = { \c_@@_sgf_mode_str } { \int_set:Nn \l_tmpa_int { \g_@@_size_int - \l_@@_y_int + 1 } \str_set:Nx \l_tmpb_str { \int_to_alph:n { \l_tmpa_int } } \str_put_right:NV \l_tmpa_str { \l_tmpb_str } } { \str_put_right:NV \l_tmpa_str { \l_@@_y_int } } \str_set_eq:NN #1 \l_tmpa_str } } % \end{macrocode} % \end{macro} % % % \subsubsection{æ·»åŠ æ£‹åæˆ–çº¯æ ‡ç¾} % % å‘对局ä¸æ·»åŠ 棋åæˆ–çº¯æ ‡ç¾ï¼Œå®ƒä»¬ä½¿ç”¨ç›¸åŒçš„结构å˜å‚¨ã€‚除了所属方ä¸ä¸€æ ·å¤–ï¼Œå®ƒä»¬å†…éƒ¨æ·»åŠ æ–¹å¼å®Œå…¨ç›¸åŒã€‚ % å…¶ä¸ï¼Œæ‰€å±žæ–¹ç”¨ $0$ 表示未使用\footnote{新局开始,所属方å‡åˆå§‹åŒ–为 $0$;移除状æ€çš„棋å,也会设置为零(åŒæ—¶åæ ‡ä¹Ÿä¸ºé›¶ï¼‰ã€‚}, % $1$ 表示黑方,$2$ 表示白方,$3$ è¡¨ç¤ºçº¯æ ‡ç¾ã€‚ % % 棋åå¯ä»¥å«æ ‡ç¾ï¼ˆå¦‚手数或特殊å—符ç‰ï¼‰ï¼Œæ£‹å|+| çº¯æ ‡ç¾ä¸ç‰äºŽå¸¦æ ‡ç¾çš„棋å。 % å› ä¸ºå‰è€…是两æ¡è®°å½•ï¼ŒåŽè€…是一æ¡è®°å½•ï¼ŒåŽç»å¤„ç†ä¹Ÿä¸ä¸€æ ·ã€‚ % % \begin{macro}{\@@_add_stone:nnn, \@@_add_stone:nnV, \@@_add_stone:nVV} % å‘对局ä¸æ·»åŠ 一æ¥æ£‹ï¼ˆ|#1| 黑白方 ï¼›|#2| åæ ‡ï¼›|#3| æ ‡ç¾ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_add_stone:nnn #1#2#3 { \int_gincr:N \g_@@_step_count_int \intarray_gset:Nnn \g_@@_player_intarray \g_@@_step_count_int { #1 } % \end{macrocode} % \begin{macrocode} \@@_loc_to_xy:n { #2 } \intarray_gset:Nnn \g_@@_x_intarray \g_@@_step_count_int \l_@@_x_int \intarray_gset:Nnn \g_@@_y_intarray \g_@@_step_count_int \l_@@_y_int % \end{macrocode} % \begin{macrocode} \str_if_eq:nnTF { #3 } { 0 } { \seq_put_right:Nn \g_@@_label_seq {} } { \seq_put_right:Nn \g_@@_label_seq { #3 } } } % \end{macrocode} % \begin{macrocode} \cs_generate_variant:Nn \@@_add_stone:nnn {nnV, nVV} % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_add_stones:nnn} % 批é‡å‘对局ä¸æ·»åŠ 棋å(|#1| 黑白方 ï¼›|#2| åæ ‡åºåˆ—ï¼›|#3| æ ‡ç¾ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_add_stones:nnn #1#2#3 { \int_set:Nn \l_@@_player_int { #1 } \clist_set:Nn \l_@@_position_clsit { #2 } \bool_set_false:N \l_@@_tmp_bool \str_if_empty:nTF { #3 } { \str_set:Nn \l_@@_tmp_str {} } { \regex_match:nnTF { [^0-9]+ } { #3 } { \str_set:Nx \l_@@_tmp_str { #3 } } { \bool_set_true:N \l_@@_tmp_bool \int_set:Nn \l_@@_tmp_int { #3 } } } \clist_map_inline:Nn \l_@@_position_clsit { \bool_if:nTF \l_@@_tmp_bool { \@@_add_stone:nnV { \l_@@_player_int } { ##1 } { \l_@@_tmp_int } \int_case:nn { \l_@@_player_int } { { 1 } { \int_set:Nn \l_@@_player_int { 2 } } { 2 } { \int_set:Nn \l_@@_player_int { 1 } } { 3 } { \int_set:Nn \l_@@_player_int { 3 } } } \int_compare:nNnT { \l_@@_tmp_int } > { 0 } { \int_incr:N \l_@@_tmp_int } } { \@@_add_stone:nnV { #1 } { ##1 } { \l_@@_tmp_str } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_add_sgf_stones:nn, \@@_add_sgf_stones:VV} % 批é‡å‘对局ä¸æ·»åŠ sgf æ ¼å¼æ£‹å(|#1| 带黑白方的åæ ‡åºåˆ—ï¼›|#2| æ ‡ç¾ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_add_sgf_stones:nn #1#2 { \regex_extract_all:nnN { ;[BW]\[[a-z]{2}\] } { #1 } \l_@@_tmp_seq \clist_set_from_seq:NN \l_@@_point_clist \l_@@_tmp_seq \bool_set_false:N \l_@@_tmp_bool \str_if_empty:nTF { #2 } { \str_set:Nn \l_@@_tmp_str {} } { \regex_match:nnTF { [^0-9]+ } { #2 } { \str_set:Nx \l_@@_tmp_str { #2 } } { \bool_set_true:N \l_@@_tmp_bool \int_set:Nn \l_@@_tmp_int { #2 } } } \clist_map_inline:Nn \l_@@_point_clist { \str_set:Nx \l_tmpa_str { \str_item:Nn { ##1 } { 2 } } \str_set:Nx \l_tmpb_str { \str_range:nnn { ##1 } { 4 } { -2 } } \str_case_e:nn { \l_tmpa_str } { { B } { \int_set:Nn \l_@@_player_int { 1 } } { W } { \int_set:Nn \l_@@_player_int { 2 } } } \bool_if:nTF \l_@@_tmp_bool { \@@_add_stone:nVV { \l_@@_player_int } { \l_tmpb_str } { \l_@@_tmp_int } \int_compare:nNnT { \l_@@_tmp_int } > { 0 } { \int_incr:N \l_@@_tmp_int } } { \@@_add_stone:nVV { \l_@@_player_int } { \l_tmpb_str } { \l_@@_tmp_str } } } } % \end{macrocode} % \begin{macrocode} \cs_generate_variant:Nn \@@_add_sgf_stones:nn { VV } % \end{macrocode} % \end{macro} % % \subsubsection{修改对局} % % 修改对局ä¸çš„棋åä¿¡æ¯ï¼ˆæ‰€æœ‰æ–¹ã€æ ‡ç¾ç‰ï¼‰ã€ç§»é™¤æ£‹å 或设置æ»åç‰ã€‚ % å…¶ä¸ï¼Œç§»é™¤æ£‹å相当于没有输入这个棋å\footnote{ % 移除棋å是通过把该手棋全部设置为零æ¥å®žçŽ°ï¼›è¿™ä¸Žè™šç€ä¸ä¸€æ ·ï¼ŒåŽè€…ä»æœ‰æ‰€å±žæ–¹ã€‚}ï¼› % 而设置æ»å则用于棋å被åƒçš„情况\footnote{ % 设置æ»åæ˜¯é€šè¿‡å°†æ£‹åŠ å…¥æ»å列表ä¸æ¥å®žçŽ°ï¼Œå…¶åæ ‡ä¿¡æ¯å…¨éƒ¨ä¸å˜ã€‚}。 % % \begin{macro}{\@@_reset_stone_number:n} % é‡ç½®æ‰€æœ‰æ£‹åçš„æ ‡ç¾ï¼Œç§»é™¤æ‰€æœ‰æ£‹åæ ‡ç¾ï¼ˆä¸å«çº¯æ ‡ç¾ï¼‰å¹¶æŒ‰æ‰‹æ•°ï¼ˆä»¥ |#1| 起为第 $1$ æ‰‹ï¼‰è®¾ç½®æ–°æ ‡ç¾ã€‚ % \begin{macrocode} \cs_new:Npn \@@_reset_stone_number:n #1 { \int_set:Ne \l_@@_tmp_int { 1 - #1 } \int_step_inline:nn { \c_@@_max_step_int } { \bool_lazy_or:nnF { \int_compare_p:nNn { \intarray_item:Nn \g_@@_player_intarray { ##1 } } = { 0 } } { \int_compare_p:nNn { \intarray_item:Nn \g_@@_player_intarray { ##1 } } = { 3 } } { \int_incr:N \l_@@_tmp_int \int_compare:nNnTF { \l_@@_tmp_int } > { 0 } { \seq_gset_item:NnV \g_@@_label_seq { ##1 } { \l_@@_tmp_int } } { \seq_gset_item:Nnn \g_@@_label_seq { ##1 } {} } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_change_stone:n} % 切æ¢æŒ‡å®šç´¢å¼•çš„棋å的黑白方(|#1| 索引)。 % \begin{macrocode} \cs_new:Npn \@@_change_stone:n #1 { \int_case:nn { \intarray_item:Nn \g_@@_player_intarray { #1 } } { { 1 } { \intarray_gset:Nnn \g_@@_player_intarray { #1 } { 2 } } { 2 } { \intarray_gset:Nnn \g_@@_player_intarray { #1 } { 1 } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_remove_stone:n} % åˆ é™¤æŒ‡å®šç´¢å¼•çš„æ£‹å(|#1| 索引)。 % \begin{macrocode} \cs_new:Npn \@@_remove_stone:n #1 { \intarray_gset:Nnn \g_@@_x_intarray { #1 } { 0 } \intarray_gset:Nnn \g_@@_y_intarray { #1 } { 0 } \intarray_gset:Nnn \g_@@_player_intarray { #1 } { 0 } \seq_gset_item:Nnn \g_@@_label_seq { #1} { } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_die_stone:n} % 设置指定索引的棋å为æ»å(|#1| 索引)。 % \begin{macrocode} \cs_new:Npn \@@_die_stone:n #1 { \seq_if_in:NnF \g_@@_die_seq { #1 } { \seq_put_right:Nn \g_@@_die_seq { #1 } \prg_break: } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_modify_stone:N} % 使用指定函数(|#1|)修改指定ä½ç½®çš„棋å(由 $x$, $y$ åæ ‡æŒ‡å®šï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_modify_stone:N #1 { \int_step_inline:nn { \c_@@_max_step_int } { \bool_lazy_and:nnT { \int_compare_p:n { \intarray_item:Nn \g_@@_x_intarray { ##1 } = \l_@@_x_int } } { \int_compare_p:n { \intarray_item:Nn \g_@@_y_intarray { ##1 } = \l_@@_y_int } } { #1 { ##1 } } } \prg_break_point: } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_modify_stones:nN} % 批é‡ä¿®æ”¹å½“å‰å¯¹å±€ä¸çš„棋å(|#1| åæ ‡åºåˆ—,|#2| 修改函数)。 % \begin{macrocode} \cs_new:Npn \@@_modify_stones:nN #1#2 { \clist_set:Nn \l_@@_position_clsit { #1 } \clist_map_inline:Nn \l_@@_position_clsit { \@@_loc_to_xy:n { ##1 } \int_compare:nNnF { \l_@@_x_int } = { 0 } { \@@_modify_stone:N { #2 } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_clear_labels:} % æ¸…é™¤æ‰€æœ‰çº¯æ ‡ç¾ã€‚ % \begin{macrocode} \cs_new:Nn \@@_clear_labels: { \int_step_inline:nn { \c_@@_max_step_int } { \int_compare:nNnT { \intarray_item:Nn \g_@@_player_intarray { ##1 } } = { 3 } { \intarray_gset:Nnn \g_@@_x_intarray { ##1 } { 0 } \intarray_gset:Nnn \g_@@_y_intarray { ##1 } { 0 } \intarray_gset:Nnn \g_@@_player_intarray { ##1 } { 0 } \seq_gset_item:Nnn \g_@@_label_seq { ##1 } {} } } } % \end{macrocode} % \end{macro} % % % \subsubsection{指示点} % % 指示点是棋盘上的特殊圆点,它支æŒçº¢ç»¿è“三ç§é¢œè‰²ã€‚旨在用于在æŸä¸ªç‰¹å®šæƒ…况下的特殊指示。 % 指示点的实现原ç†ä¸Žçº¯æ ‡ç¾å®Œå…¨ä¸ä¸€æ ·ï¼Œä¾§é‡ç‚¹ä¹Ÿä¸ä¸€æ ·ã€‚ % % \begin{macro}{\@@_add_points:nn} % 批é‡å‘对局ä¸æ·»åŠ 指示点(|#1| 颜色 ï¼›|#2| åæ ‡åºåˆ—)。 % \begin{macrocode} \cs_new:Npn \@@_add_points:nn #1#2 { \str_case:nn { #1 } { { red } { \clist_gput_right:Nn \g_@@_red_point_clist { #2 } } { green } { \clist_gput_right:Nn \g_@@_green_point_clist { #2 } } { blue } { \clist_gput_right:Nn \g_@@_blue_point_clist { #2 } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_clear_points:} % 清除所有指示点。 % \begin{macrocode} \cs_new:Nn \@@_clear_points: { \clist_clear:N \g_@@_red_point_clist \clist_clear:N \g_@@_green_point_clist \clist_clear:N \g_@@_blue_point_clist } % \end{macrocode} % \end{macro} % % % \subsection{绘制棋局的函数} % % \subsubsection{åæ ‡å˜æ¢} % % 由于对局ä¸çš„åæ ‡ä»¥åŽŸå§‹æ–¹ä½è¾“入与ä¿å˜ï¼Œè€Œæ˜¾ç¤ºæ—¶éœ€è¦æŒ‰æŒ‡å®šçš„æ–¹ä½æ¥æ˜¾ç¤ºï¼Œ % å› æ¤åœ¨æ˜¾ç¤ºï¼ˆç»˜å›¾ï¼‰å‰éœ€è¦æ ¹æ®æ£‹ç›˜æ–¹ä½ä¿¡æ¯æ¥è¿›è¡Œåæ ‡å˜æ¢ã€‚ % % \begin{macro}{\@@_transform_xy:NN} % 转æ¢åæ ‡ï¼ˆ|#1|ã€|#2| 分别为 $x,y$ åæ ‡ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_transform_xy:NN #1#2 { \int_set:Ne \l_tmpa_int { #1 * \l_@@_x_direction_int } \int_set:Ne \l_tmpb_int { #2 * \l_@@_y_direction_int } \bool_if:NTF \l_@@_swap_xy_bool { \int_set_eq:NN #1 \l_tmpb_int \int_set_eq:NN #2 \l_tmpa_int } { \int_set_eq:NN #1 \l_tmpa_int \int_set_eq:NN #2 \l_tmpb_int } } % \end{macrocode} % \end{macro} % % % \subsubsection{边界函数} % % 绘制棋局时,需è¦ç¡®è®¤è¦æ˜¾ç¤ºçš„区域(显示整个棋盘通常ä¸æ˜¯æœ€ä¼˜æ–¹æ¡ˆï¼‰ï¼Œ % 本å°èŠ‚æ供一系列函数,用于确认显示边界。 % % \begin{macro}{\@@_calc_range:} % 计算棋å所在区间边界。 % \begin{macrocode} \cs_new:Nn \@@_calc_range: { \int_set:Nn \l_@@_x_min_int { 99 } \int_set:Nn \l_@@_y_min_int { 99 } \int_set:Nn \l_@@_x_max_int { 0 } \int_set:Nn \l_@@_y_max_int { 0 } % \end{macrocode} % é历生æˆè‡ªç„¶è¾¹ç•Œï¼š % \begin{macrocode} \int_step_inline:nn {\g_@@_step_count_int} { \int_set:Ne \l_@@_x_int { \intarray_item:Nn \g_@@_x_intarray { ##1 } } \int_set:Ne \l_@@_y_int { \intarray_item:Nn \g_@@_y_intarray { ##1 } } \int_compare:nNnF { \l_@@_x_int } = { 0 } { \int_compare:nNnT \l_@@_x_min_int > \l_@@_x_int { \int_set_eq:NN \l_@@_x_min_int \l_@@_x_int } \int_compare:nNnT \l_@@_x_max_int < \l_@@_x_int { \int_set_eq:NN \l_@@_x_max_int \l_@@_x_int } \int_compare:nNnT \l_@@_y_min_int > \l_@@_y_int { \int_set_eq:NN \l_@@_y_min_int \l_@@_y_int } \int_compare:nNnT \l_@@_y_max_int < \l_@@_y_int { \int_set_eq:NN \l_@@_y_max_int \l_@@_y_int } } } % \end{macrocode} % æ— æœ‰æ•ˆæ£‹å的情况下,显示整个棋盘: % \begin{macrocode} \int_compare:nNnT { \l_@@_x_min_int } = { 99 } { \int_set:Nn \l_@@_x_min_int { 1 } \int_set:Nn \l_@@_y_min_int { 1 } \int_set_eq:NN \l_@@_x_max_int \g_@@_size_int \int_set_eq:NN \l_@@_y_max_int \g_@@_size_int } % \end{macrocode} % å‘外延伸,以ä¿è¯è‡³å°‘有一个角: % \begin{macrocode} \int_set:Ne \l_tmpa_int { \int_min:nn { \g_@@_size_int } { \l_@@_min_width_int } } \int_compare:nNnTF { \g_@@_size_int - \l_@@_x_max_int } > { \l_@@_x_min_int - 1 } { \int_set:Nn \l_@@_x_min_int { 1 } \int_set:Ne \l_@@_x_max_int { \int_max:nn { \l_@@_x_max_int + 1 } { \l_tmpa_int } } } { \int_set_eq:NN \l_@@_x_max_int \g_@@_size_int \int_compare:nNnF { \l_@@_x_min_int } = { 1 } { \int_set:Ne \l_@@_x_min_int { \int_min:nn { \l_@@_x_min_int - 1 } { \g_@@_size_int - \l_tmpa_int + 1 } } } } \int_set:Ne \l_tmpa_int { \int_min:nn { \g_@@_size_int } { \l_@@_min_hight_int } } \int_compare:nNnTF { \g_@@_size_int - \l_@@_y_max_int } > { \l_@@_y_min_int - 1 } { \int_set:Nn \l_@@_y_min_int { 1 } \int_set:Ne \l_@@_y_max_int { \int_max:nn { \l_@@_y_max_int + 1 } { \l_tmpa_int } } } { \int_set_eq:NN \l_@@_y_max_int \g_@@_size_int \int_compare:nNnF { \l_@@_y_min_int } = { 1 } { \int_set:Ne \l_@@_y_min_int { \int_min:nn { \l_@@_y_min_int - 1 } { \g_@@_size_int - \l_tmpa_int + 1 } } } } % \end{macrocode} % å˜æ¢åæ ‡ï¼š % \begin{macrocode} \@@_transform_xy:NN \l_@@_x_min_int \l_@@_y_min_int \@@_transform_xy:NN \l_@@_x_max_int \l_@@_y_max_int } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_set_range:n} % 指定棋å区间边界(边界外棋åä¸æ˜¾ç¤ºï¼‰ï¼Œæ”¯æŒ |full|。 % \begin{macrocode} \cs_new:Npn \@@_set_range:n #1 { \str_compare:eNeTF { \str_lowercase:n { #1 } } = { full } { \int_set:Nn \l_@@_x_min_int { 1 } \int_set:Nn \l_@@_y_min_int { 1 } \int_set_eq:NN \l_@@_x_max_int \g_@@_size_int \int_set_eq:NN \l_@@_y_max_int \g_@@_size_int } { \clist_set:Nn \l_@@_position_clsit { #1 } \clist_pop:NN \l_@@_position_clsit \l_tmpa_tl \@@_loc_to_xy:V { \l_tmpa_tl } \int_set_eq:NN \l_@@_x_min_int \l_@@_x_int \int_set_eq:NN \l_@@_y_min_int \l_@@_y_int \clist_pop:NN \l_@@_position_clsit \l_tmpa_tl \@@_loc_to_xy:V { \l_tmpa_tl } \int_set_eq:NN \l_@@_x_max_int \l_@@_x_int \int_set_eq:NN \l_@@_y_max_int \l_@@_y_int } % \end{macrocode} % 生æˆæ ‡å‡†å¯¹è§’点,å˜æ¢åæ ‡ï¼š % \begin{macrocode} \int_compare:nNnT { \l_@@_x_min_int } > { \l_@@_x_max_int } { \int_set_eq:NN \l_tmpa_int \l_@@_x_min_int \int_set_eq:NN \l_@@_x_min_int \l_@@_x_max_int \int_set_eq:NN \l_@@_x_max_int \l_tmpa_int } \int_compare:nNnT { \l_@@_y_min_int } > { \l_@@_y_max_int } { \int_set_eq:NN \l_tmpa_int \l_@@_y_min_int \int_set_eq:NN \l_@@_y_min_int \l_@@_y_max_int \int_set_eq:NN \l_@@_y_max_int \l_tmpa_int } \@@_transform_xy:NN \l_@@_x_min_int \l_@@_y_min_int \@@_transform_xy:NN \l_@@_x_max_int \l_@@_y_max_int } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_calc_board_border:} % 计算棋盘的显示边界。 % \begin{macrocode} \cs_new:Nn \@@_calc_board_border: { \int_compare:nNnTF { \int_abs:n { \l_@@_x_min_int } } = { 1 } { \bool_set_true:N \l_@@_left_bool \fp_set:Nn \l_@@_x_min_fp { \l_@@_x_min_int } } { \bool_set_false:N \l_@@_left_bool \fp_set:Nn \l_@@_x_min_fp { \l_@@_x_min_int - 0.3 * \int_sign:n { \l_@@_x_min_int } } } \int_compare:nNnTF { \int_abs:n { \l_@@_x_max_int } } = { \g_@@_size_int } { \bool_set_true:N \l_@@_right_bool \fp_set:Nn \l_@@_x_max_fp { \l_@@_x_max_int } } { \bool_set_false:N \l_@@_right_bool \fp_set:Nn \l_@@_x_max_fp { \l_@@_x_max_int + 0.3 * \int_sign:n { \l_@@_x_max_int } } } \int_compare:nNnTF { \int_abs:n { \l_@@_y_min_int } } = { 1 } { \bool_set_true:N \l_@@_down_bool \fp_set:Nn \l_@@_y_min_fp { \l_@@_y_min_int } } { \bool_set_false:N \l_@@_down_bool \fp_set:Nn \l_@@_y_min_fp { \l_@@_y_min_int - 0.3 * \int_sign:n { \l_@@_y_min_int } } } \int_compare:nNnTF { \int_abs:n { \l_@@_y_max_int } } = { \g_@@_size_int } { \bool_set_true:N \l_@@_up_bool \fp_set:Nn \l_@@_y_max_fp { \l_@@_y_max_int } } { \bool_set_false:N \l_@@_up_bool \fp_set:Nn \l_@@_y_max_fp { \l_@@_y_max_int + 0.3 * \int_sign:n { \l_@@_y_max_int } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_within_range_p:nn, \@@_within_range:nnT} % 判定点是å¦åœ¨èŒƒå›´å†…(|#1| $x$åæ ‡ï¼›|#2| $y$ åæ ‡ï¼‰ã€‚ % åæ ‡æ˜¯å˜æ¢åŽçš„åæ ‡ã€‚ % \begin{macrocode} \prg_set_conditional:Npnn \@@_within_range:nn #1#2 { p, T } { \fp_set:Nn \l_tmpa_fp { abs( \l_@@_x_min_fp - #1 ) } \fp_add:Nn \l_tmpa_fp { abs( \l_@@_x_max_fp - #1 ) } \fp_sub:Nn \l_tmpa_fp { abs( \l_@@_x_max_fp - \l_@@_x_min_fp ) } \fp_add:Nn \l_tmpa_fp { abs( \l_@@_y_min_fp - #2 ) } \fp_add:Nn \l_tmpa_fp { abs( \l_@@_y_max_fp - #2 ) } \fp_sub:Nn \l_tmpa_fp { abs( \l_@@_y_max_fp - \l_@@_y_min_fp ) } \fp_compare:nNnTF { \l_tmpa_fp } < { 0.1 } { \prg_return_true: } { \prg_return_false: } } % \end{macrocode} % \end{macro} % % % \subsubsection{绘制函数} % % 绘制对局包括绘制棋盘ã€æ£‹åä¸Žçº¯æ ‡ç¾ã€æ ‡è®°ç‚¹åŠæ»åå‡ ä¸ªæ¥éª¤ã€‚ % å…¶ä¸ï¼Œæ£‹ç›˜åŒ…æ‹¬ç½‘æ ¼çº¿ã€è¾¹ç•Œçº¿ã€è§’ã€æ˜Ÿä½åŠåæ ‡æ ‡ç¾ã€‚ % 绘制å‰éœ€è¦è®¾ç½®å¥½æ£‹å区间边界\footnote{æ£‹ç›˜è¾¹ç•Œåœ¨ç»˜åˆ¶æ£‹ç›˜æ—¶å†…éƒ¨è°ƒç”¨ï¼Œå› æ¤ä¸éœ€è¦é¢å¤–设置。}。 % % % \begin{macro}{\@@_draw_board_grid:} % ç»˜åˆ¶æ£‹ç›˜çš„ç½‘æ ¼çº¿ï¼ˆè·¯å¾„ï¼‰ã€‚ % \begin{macrocode} \cs_new:Nn \@@_draw_board_grid: { \int_set:Ne \l_@@_tmp_int { \int_sign:n { \l_@@_x_max_int - \l_@@_x_min_int } } \int_step_inline:nnnn { \l_@@_x_min_int } { \l_@@_tmp_int } { \l_@@_x_max_int } { \draw_path_moveto:n { ##1 cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { ##1 cm, \l_@@_y_max_fp cm } } \int_set:Ne \l_@@_tmp_int { \int_sign:n { \l_@@_y_max_int - \l_@@_y_min_int } } \int_step_inline:nnnn { \l_@@_y_min_int } { \l_@@_tmp_int } { \l_@@_y_max_int } { \draw_path_moveto:n { \l_@@_x_min_fp cm, ##1 cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, ##1 cm } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_board_border:} % 绘制棋盘的边界线(路径)。 % \begin{macrocode} \cs_new:Nn \@@_draw_board_border: { \bool_if:nT { \l_@@_left_bool } { \draw_path_moveto:n { \l_@@_x_min_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_min_fp cm, \l_@@_y_max_fp cm } } \bool_if:nT { \l_@@_right_bool } { \draw_path_moveto:n { \l_@@_x_max_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_max_fp cm } } \bool_if:nT { \l_@@_down_bool } { \draw_path_moveto:n { \l_@@_x_min_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_min_fp cm } } \bool_if:nT { \l_@@_up_bool } { \draw_path_moveto:n { \l_@@_x_min_fp cm, \l_@@_y_max_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_max_fp cm } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_board_corner:} % 绘制棋盘的角(路径)。 % \begin{macrocode} \cs_new:Nn \@@_draw_board_corner: { \bool_if:nT { \l_@@_left_bool && \l_@@_down_bool } { \draw_path_moveto:n { \l_@@_x_min_fp cm, \l_@@_y_max_fp cm } \draw_path_lineto:n { \l_@@_x_min_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_min_fp cm } } \bool_if:nT { \l_@@_right_bool && \l_@@_down_bool } { \draw_path_moveto:n { \l_@@_x_max_fp cm, \l_@@_y_max_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_min_fp cm, \l_@@_y_min_fp cm } } \bool_if:nT { \l_@@_right_bool && \l_@@_up_bool } { \draw_path_moveto:n { \l_@@_x_max_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_max_fp cm } \draw_path_lineto:n { \l_@@_x_min_fp cm, \l_@@_y_max_fp cm } } \bool_if:nT { \l_@@_left_bool && \l_@@_up_bool } { \draw_path_moveto:n { \l_@@_x_min_fp cm, \l_@@_y_min_fp cm } \draw_path_lineto:n { \l_@@_x_min_fp cm, \l_@@_y_max_fp cm } \draw_path_lineto:n { \l_@@_x_max_fp cm, \l_@@_y_max_fp cm } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_draw_point:n} % 绘制å•ä¸ªç‚¹ï¼ˆè·¯å¾„)(|#1| åæ ‡ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_draw_point:n #1 { \__weiqi_loc_to_xy:n { #1 } \@@_transform_xy:NN \l_@@_x_int \l_@@_y_int \@@_within_range:nnT { \l_@@_x_int } { \l_@@_y_int } { \draw_path_circle:nn { \l_@@_x_int cm, \l_@@_y_int cm } { 1mm } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_board_star:} % 绘制棋盘的星ä½ï¼ˆè·¯å¾„)。 % \begin{macrocode} \cs_new:Nn \@@_draw_board_star: { \clist_clear:N \l_@@_point_clist \int_case:nn { \g_@@_size_int } { { \c_@@_normal_size_int } { \clist_set_eq:NN \l_@@_point_clist \c_@@_normal_star_clist } { \c_@@_mid_size_int } { \clist_set_eq:NN \l_@@_point_clist \c_@@_mid_star_clist } { \c_@@_small_size_int } { \clist_set_eq:NN \l_@@_point_clist \c_@@_small_star_clist } } \clist_map_function:NN \l_@@_point_clist \@@_draw_point:n } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_set_loc_label:nn} % 设置åæ ‡æ ‡ç¾ï¼ˆ|#1| æ ‡ç¾æ–¹æ¡ˆï¼›|#2| å•è½´åæ ‡ï¼‰ã€‚ % \begin{macrocode} \cs_new:Npn \@@_set_loc_label:nn #1#2 { \str_case_e:nn { #1 } { { A } { \str_set:Nx \l_@@_label_str { \int_to_Alph:n { #2 } } } { \c_@@_normal_mode_str } { \str_set:NV \l_@@_label_str { #2 } } { \c_@@_sgf_mode_str } { \int_set:Nn \l_tmpa_int { \g_@@_size_int - #2 + 1 } \str_set:Nx\l_@@_label_str { \int_to_alph:n { \l_tmpa_int } } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_board_loc:} % 绘制棋盘的åæ ‡ï¼ˆè·¯å¾„ï¼‰ã€‚ % \begin{macrocode} \cs_new:Nn \@@_draw_board_loc: { \int_gset:Nn \g_tmpa_int { \int_sign:n { \l_@@_x_max_int - \l_@@_x_min_int } } \int_gset:Nn \g_tmpb_int { \int_sign:n { \l_@@_y_max_int - \l_@@_y_min_int } } \int_step_inline:nnnn { \l_@@_x_min_int } { \g_tmpa_int } { \l_@@_x_max_int } { \int_set:Ne \l_@@_tmp_int { \int_abs:n { ##1 } } \bool_if:NTF \l_@@_swap_xy_bool { \@@_set_loc_label:nn { \l_@@_loc_mode_str } { \l_@@_tmp_int } } { \@@_set_loc_label:nn { A } { \l_@@_tmp_int } } \hbox_set:Nn \l_tmpa_box { \l_@@_label_str } \fp_set:Nn \l_tmpa_fp { 0.2 * \g_tmpb_int } \fp_set:Nn \l_tmpb_fp { 0.5 * { \box_ht:N \l_tmpa_box } * \g_tmpb_int } \bool_if:NT \l_@@_up_bool { \draw_box_use:Nn \l_tmpa_box { ##1 cm - 0.5 * { \box_wd:N \l_tmpa_box }, (\l_@@_y_max_fp + \l_tmpa_fp ) cm - abs(\l_tmpb_fp) + \l_tmpb_fp } } \bool_if:NT \l_@@_down_bool { \draw_box_use:Nn \l_tmpa_box { ##1 cm - 0.5 * { \box_wd:N \l_tmpa_box }, (\l_@@_y_min_fp - \l_tmpa_fp ) cm - abs(\l_tmpb_fp) - \l_tmpb_fp } } } \int_step_inline:nnnn { \l_@@_y_min_int } { \g_tmpb_int } { \l_@@_y_max_int } { \int_set:Ne \l_@@_tmp_int { \int_abs:n { ##1 } } \bool_if:NTF \l_@@_swap_xy_bool { \@@_set_loc_label:nn { A } { \l_@@_tmp_int } } { \@@_set_loc_label:nn { \l_@@_loc_mode_str } { \l_@@_tmp_int } } \hbox_set:Nn \l_tmpa_box { \l_@@_label_str } \fp_set:Nn \l_tmpa_fp { 0.2 * \g_tmpa_int } \fp_set:Nn \l_tmpb_fp { 0.5 * { \box_wd:N \l_tmpa_box } * \g_tmpa_int } \bool_if:NT \l_@@_left_bool { \draw_box_use:Nn \l_tmpa_box { (\l_@@_x_min_fp - \l_tmpa_fp) cm - abs(\l_tmpb_fp) - \l_tmpb_fp, ##1 cm - 0.5 * { \box_ht:N \l_tmpa_box } } } \bool_if:NT \l_@@_right_bool { \draw_box_use:Nn \l_tmpa_box { (\l_@@_y_max_fp + \l_tmpa_fp) cm - abs(\l_tmpb_fp) + \l_tmpb_fp, ##1 cm - 0.5 * { \box_ht:N \l_tmpa_box } } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_board:} % ç»˜åˆ¶å®Œæ•´çš„æ£‹ç›˜å…ƒç´ ã€‚ % \begin{macrocode} \cs_new:Nn \@@_draw_board: { \@@_calc_board_border: % \end{macrocode} % % \begin{macrocode} \draw_linewidth:n { 0.7 } \color_select:n { black } \@@_draw_board_grid: \draw_path_use_clear:n { stroke } % \end{macrocode} % % \begin{macrocode} \draw_linewidth:n { 2 } \@@_draw_board_border: \draw_path_use_clear:n { stroke } \@@_draw_board_corner: \draw_path_use_clear:n { stroke } % \end{macrocode} % % \begin{macrocode} \color_select:n { black } \@@_draw_board_star: \draw_path_use_clear:n { draw, fill } % \end{macrocode} % % \begin{macrocode} \color_select:n { black!50 } \bool_if:NT \l_@@_show_loc_bool { \@@_draw_board_loc: } \draw_path_use_clear:n { stroke } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_points:} % 绘制完整的指示点。 % \begin{macrocode} \cs_new:Npn \@@_draw_points: { \color_select:n { red } \clist_map_function:NN \g_@@_red_point_clist \@@_draw_point:n \draw_path_use_clear:n { draw, fill } \color_select:n { green } \clist_map_function:NN \g_@@_green_point_clist \@@_draw_point:n \draw_path_use_clear:n { draw, fill } \color_select:n { blue } \clist_map_function:NN \g_@@_blue_point_clist \@@_draw_point:n \draw_path_use_clear:n { draw, fill } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_draw_stone:nnnn} % ç»˜åˆ¶ä¸€æ‰‹æ£‹æˆ–çº¯æ ‡ç¾ï¼ˆ|#1| 黑白方;|#2| $x$åæ ‡ï¼›|#3| $y$ åæ ‡ï¼›|#4| æ ‡ç¾ï¼‰ã€‚\\ % åæ ‡æ˜¯å˜æ¢åŽçš„åæ ‡ã€‚ % \begin{macrocode} \cs_new:Npn \@@_draw_stone:nnnn #1#2#3#4 { % \end{macrocode} % ç»˜åˆ¶å¤–å›´ç©ºç™½ï¼Œå¦‚æžœæ˜¯çº¯æ ‡ç¾åˆ™ä¸ç»˜åˆ¶ï¼š % \begin{macrocode} \int_compare:nNnF { #1 } = { 3 } { \color_fill:n { white } \draw_path_circle:nn { #2cm, #3cm } { 4.4mm } \draw_path_use_clear:n { fill } } % \end{macrocode} % 绘制棋å(ä¸å«æ ‡ç¾ï¼‰ï¼›å¦‚æžœä¸ºçº¯æ ‡ç¾ï¼Œåˆ™ç»˜åˆ¶ç©ºç™½ï¼š % \begin{macrocode} \color_select:n { black } \int_case:nn { #1 } { { 1 } { \color_fill:n { black } } { 2 } { \color_fill:n { white } } { 3 } { \color_select:n { white } } } \draw_path_circle:nn{ #2cm, #3cm } { 4mm } \draw_path_use_clear:n { draw, fill } % \end{macrocode} % 绘制棋åæ ‡ç¾ï¼š % \begin{macrocode} \int_case:nn { #1 } { { 1 } { \color_select:n { white } } { 2 } { \color_select:n { black } } { 3 } { \color_select:n { blue } } } \hbox_set:Nn \l_tmpa_box { \Large \textbf{ #4 } } \draw_box_use:Nn \l_tmpa_box { #2cm - 0.5 * { \box_wd:N \l_tmpa_box }, #3cm - 0.5 * { \box_ht:N \l_tmpa_box } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_stones:} % 绘制完整的常规棋å。 % \begin{macrocode} \cs_new:Nn \@@_draw_stones: { \draw_linewidth:n { 1 } \int_step_inline:nn {\g_@@_step_count_int} { \int_set:Ne \l_@@_x_int { \intarray_item:Nn \g_@@_x_intarray { ##1 } } \int_set:Ne \l_@@_y_int { \intarray_item:Nn \g_@@_y_intarray { ##1 } } \int_set:Ne \l_@@_player_int { \intarray_item:Nn \g_@@_player_intarray { ##1 } } \str_set:Nx \l_@@_tmp_str { \seq_item:Nn \g_@@_label_seq { ##1 } } \seq_if_in:NnT \g_@@_die_seq { ##1 } { \int_set:Nn \l_@@_x_int { 0 } } \int_if_zero:nF { \l_@@_x_int } { \@@_transform_xy:NN \l_@@_x_int \l_@@_y_int \@@_within_range:nnT { \l_@@_x_int } { \l_@@_y_int } { \@@_draw_stone:nnnn { \l_@@_player_int } { \l_@@_x_int } { \l_@@_y_int } { \l_@@_tmp_str } } } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_specific_stone:} % 绘制指定的一个特殊的棋å(æ»åã€è™šç€ï¼‰ã€‚ % \begin{macrocode} \cs_new:Nn \@@_draw_specific_stone: { \color_select:n { black } \int_case:nn { \l_@@_player_int } { { 1 } { \color_fill:n { black } } { 2 } { \color_fill:n { white } } } \draw_path_circle:nn{ \l_@@_x_fp cm, \l_@@_y_fp cm } { 4mm } \draw_path_use_clear:n { draw, fill } % \end{macrocode} % \begin{macrocode} \int_case:nn { \l_@@_player_int } { { 1 } { \color_select:n { white } } { 2 } { \color_select:n { black } } } \@@_xy_to_loc:N \l_tmpa_str \hbox_set:Nn \l_tmpa_box { \Large \textbf{ \l_@@_tmp_str } } \hbox_set:Nn \l_tmpb_box { \Large \texttt{ \l_tmpa_str } } \draw_box_use:Nn \l_tmpa_box { \l_@@_x_fp cm - 0.5 * { \box_wd:N \l_tmpa_box }, \l_@@_y_fp cm - 0.5 * { \box_ht:N \l_tmpa_box } } \color_select:n { black } \draw_box_use:Nn \l_tmpb_box { \l_@@_x_fp cm + 6mm, \l_@@_y_fp cm - 0.5 * { \box_ht:N \l_tmpa_box } } % \end{macrocode} % \begin{macrocode} \fp_set:Nn \l_tmpa_fp { min(\l_@@_x_min_fp, \l_@@_x_max_fp) } \fp_set:Nn \l_tmpb_fp { max(\l_@@_x_min_fp, \l_@@_x_max_fp) } \fp_add:Nn \l_@@_x_fp { 2 } \fp_compare:nNnT { \l_@@_x_fp } > { \l_tmpb_fp } { \fp_set_eq:NN \l_@@_x_fp \l_tmpa_fp \fp_sub:Nn \l_@@_y_fp { 1 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_draw_specific_stones:} % 绘制完整的特殊棋å(æ»åã€è™šç€ï¼‰ã€‚ % \begin{macrocode} \cs_new:Nn \@@_draw_specific_stones: { \draw_linewidth:n { 1 } \fp_set:Nn \l_@@_x_fp { min(\l_@@_x_min_int, \l_@@_x_max_int) } \fp_set:Nn \l_@@_y_fp { min(\l_@@_y_min_int, \l_@@_y_max_int) - 1.2} \int_step_inline:nn {\g_@@_step_count_int} { \int_set:Ne \l_@@_x_int { \intarray_item:Nn \g_@@_x_intarray { ##1 } } \int_set:Ne \l_@@_y_int { \intarray_item:Nn \g_@@_y_intarray { ##1 } } \int_set:Ne \l_@@_player_int { \intarray_item:Nn \g_@@_player_intarray { ##1 } } \str_set:Nx \l_@@_tmp_str { \seq_item:Nn \g_@@_label_seq { ##1 } } % \end{macrocode} % \begin{macrocode} \seq_if_in:NnTF \g_@@_die_seq { ##1 } { \int_set:Nn \l_tmpa_int { 0 } } { \int_set_eq:NN \l_tmpa_int \l_@@_x_int } \str_compare:eNeT { \l_@@_tmp_str } = {} { \int_set:Nn \l_tmpa_int { 1 } } \bool_lazy_all:nT { { \int_compare_p:nNn { \l_tmpa_int } = { 0 } } { \int_compare_p:nNn { \l_@@_player_int } > { 0 } } { \int_compare_p:nNn { \l_@@_player_int } < { 3 } } } { \@@_draw_specific_stone: } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\@@_show:} % 显示完整对局。 % \begin{macrocode} \cs_new:Nn \@@_show: { \draw_begin: \group_begin: \draw_transform_scale:n { \l_@@_scale_fp } \@@_draw_board: \@@_draw_points: \@@_draw_stones: \@@_draw_specific_stones: \group_end: \draw_end: } % \end{macrocode} % \end{macro} % % % \subsection{定义文档命令} % % 本节定义了一些供å®åŒ…外使用的文档命令。 % % \begin{macro}{\newweiqi} % 开始新对局。 % \begin{macrocode} \NewDocumentCommand \newweiqi { s o } { \IfNoValueTF { #2 } { \@@_new_game:n { \g_@@_default_size_int } } { \IfBooleanT { #1 } { \int_gset:Nn \g_@@_default_size_int { #2 } } \@@_new_game:n { #2 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqisize} % 更改棋盘大å°ã€‚ % \begin{macrocode} \NewDocumentCommand \weiqisize { s m } { \IfBooleanT{ #1 } { \int_gset:Nn \g_@@_default_size_int { #2 } } \int_set:Nn \g_@@_size_int { #2 } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqiblack, \weiqiwhite} % æ·»åŠ é»‘/白棋å。星å·ç‰ˆæœ¬å‘½ä»¤æ— 区别。 % \begin{macrocode} \NewDocumentCommand \weiqiblack { s o m } { \IfNoValueTF { #2 } { \@@_add_stones:nnn { 1 } { #3 } { } } { \@@_add_stones:nnn { 1 } { #3 } { #2 } } } % \end{macrocode} % \begin{macrocode} \NewDocumentCommand \weiqiwhite { s o m } { \IfNoValueTF { #2 } { \@@_add_stones:nnn { 2 } { #3 } { } } { \@@_add_stones:nnn { 2 } { #3 } { #2 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqisgf} % 使用 sgf æ–‡æœ¬æ·»åŠ é»‘/白棋å。星å·ç‰ˆæœ¬å‘½ä»¤æ— 区别。 % \begin{macrocode} \NewDocumentCommand \weiqisgf { s o m } { \IfNoValueTF { #2 } { \@@_add_sgf_stones:nn { #3 } { } } { \@@_add_sgf_stones:nn { #3 } { #2 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\inputsgf} % è¯»å– sgf 棋谱。星å·ç‰ˆæœ¬å‘½ä»¤æ— 区别。 % \begin{macrocode} \NewDocumentCommand \inputsgf { s o m } { \ior_open:Nn \g_tmpa_ior { #3 } \str_set:Nn \l_@@_tmp_str {} \ior_str_map_inline:Nn \g_tmpa_ior { \str_put_right:Nx \l_@@_tmp_str { ##1 } } \ior_close:N \g_tmpa_ior % \end{macrocode} % \begin{macrocode} \regex_extract_once:nVNTF { ;GM\[1\] } { \l_@@_tmp_str } \l_tmpa_seq { \regex_extract_once:nVNTF { SZ\[[0-9]+\] } { \l_@@_tmp_str } \l_tmpa_seq { \str_set:Nx \l_tmpa_str { \seq_item:Nn \l_tmpa_seq { 1 } } \str_set:Nx \l_tmpa_str { \str_range:Nnn \l_tmpa_str { 4 } { -2 } } \int_set:Ne \l_tmpa_int { \l_tmpa_str } \newweiqi [ \l_tmpa_int ] \regex_extract_once:nVN { HA\[[0-9]+\] } { \l_@@_tmp_str } \l_tmpa_seq \str_set:Nx \l_tmpa_str { \seq_item:Nn \l_tmpa_seq { 1 } } \str_set:Nx \l_tmpa_str {\str_range:Nnn \l_tmpa_str { 4 } { -2 } } \int_set:Ne \l_tmpa_int { \l_tmpa_str } \IfNoValueTF { #2 } { \int_add:Nn \l_tmpa_int { 1 } } { \int_add:Nn \l_tmpa_int { #2 } } \@@_add_sgf_stones:VV { \l_@@_tmp_str } { \l_tmpa_int } } { 解æžæ£‹ç›˜å¤§å°å¤±è´¥ } } { ä¸æ”¯æŒçš„棋谱 } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\resetnumber} % é‡æ–°ä¿®æ”¹æ£‹å手数。星å·ç‰ˆæœ¬å‘½ä»¤æ— 区别。 % \begin{macrocode} \NewDocumentCommand \resetnumber { s o } { \IfNoValueTF { #2 } { \@@_reset_stone_number:n { 1 } } { \@@_reset_stone_number:n { #2 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqilabel, \clearlabel} % æ·»åŠ /åˆ é™¤æ ‡ç¾ã€‚ % \begin{macrocode} \NewDocumentCommand \weiqilabel { s o m } { \IfBooleanT{ #1 } { \@@_clear_labels: } \IfNoValueTF { #2 } { \@@_add_stones:nnn { 3 } { #3 } { a } } { \@@_add_stones:nnn { 3 } { #3 } { #2 } } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \clearlabel { } { \@@_clear_labels: } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqired, \weiqigreen, \weiqiblue, \clearpoint} % æ·»åŠ çº¢ç»¿è“点。 % \begin{macrocode} \NewDocumentCommand \weiqired { s m } { \IfBooleanT{ #1 } { \@@_clear_points: } \@@_add_points:nn { red } { #2 } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \weiqigreen { s m } { \IfBooleanT{ #1 } { \@@_clear_points: } \@@_add_points:nn { green } { #2 } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \weiqiblue { s m } { \IfBooleanT{ #1 } { \@@_clear_points: } \@@_add_points:nn { blue } { #2 } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \clearpoint { } { \@@_clear_points: } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqidie} % æ ‡è®°æ»å。 % \begin{macrocode} \NewDocumentCommand \weiqidie { s m } { \@@_modify_stones:nN { #2 } \@@_die_stone:n } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqiremove} % 移除棋å。 % \begin{macrocode} \NewDocumentCommand \weiqiremove { s m } { \@@_modify_stones:nN { #2 } \@@_remove_stone:n } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqichange} % 切æ¢æ£‹å黑白方。 % \begin{macrocode} \NewDocumentCommand \weiqichange { s m } { \@@_modify_stones:nN { #2 } \@@_change_stone:n } % \end{macrocode} % \end{macro} % % % \begin{macro}{\showweiqi} % 显示棋盘。 % \begin{macrocode} \NewDocumentCommand \showweiqi { s o } { \IfNoValueTF { #2 } { \@@_calc_range: } { \@@_set_range:n { #2 } } \@@_show: \IfBooleanF { #1 } { \newweiqi } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\nonelocmode, \normallocmode, \sgflocmode} % 设置围棋åæ ‡æ˜¾ç¤ºæ¨¡å¼ã€‚ % \begin{macrocode} \NewDocumentCommand \nonelocmode { s } { \bool_set_false:N \l_@@_show_loc_bool \IfBooleanT { #1 } { \bool_gset_false:N \g_@@_show_loc_bool } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \normallocmode { s } { \bool_set_true:N \l_@@_show_loc_bool \str_set_eq:NN \l_@@_loc_mode_str \c_@@_normal_mode_str \IfBooleanT { #1 } { \bool_gset_true:N \g_@@_show_loc_bool \str_gset_eq:NN \g_@@_loc_mode_str \c_@@_normal_mode_str } } % \end{macrocode} % % \begin{macrocode} \NewDocumentCommand \sgflocmode { s } { \bool_set_true:N \l_@@_show_loc_bool \str_set_eq:NN \l_@@_loc_mode_str \c_@@_sgf_mode_str \IfBooleanT { #1 } { \bool_gset_true:N \g_@@_show_loc_bool \str_gset_eq:NN \g_@@_loc_mode_str \c_@@_sgf_mode_str } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqirotate, \weiqimirror, \weiqiposition} % 旋转棋盘ã€é•œåƒæ£‹ç›˜æˆ–指定棋盘方ä½ã€‚ % \begin{macrocode} \NewDocumentCommand \weiqirotate { s o } { \IfNoValueTF { #2 } { \int_set:Nn \l_tmpa_int { 90 } } { \int_set:Ne \l_tmpa_int { #2 } } \int_compare:nNnT { \l_tmpa_int } < { 0 } { \int_add:Nn \l_tmpa_int { 360 } } \int_case:nn { \l_tmpa_int } { { 90 } { \bool_set_inverse:N \l_@@_swap_xy_bool \int_set:Ne \l_tmpb_int { \l_@@_x_direction_int } \int_set:Ne \l_@@_x_direction_int { \l_@@_y_direction_int } \int_set:Ne \l_@@_y_direction_int { 0 - \l_tmpb_int } } { 180 } { \int_set:Ne \l_@@_x_direction_int { 0 - \l_@@_x_direction_int } \int_set:Ne \l_@@_y_direction_int { 0 - \l_@@_y_direction_int } } { 270 } { \bool_set_inverse:N \l_@@_swap_xy_bool \int_set:Ne \l_tmpb_int { \l_@@_x_direction_int } \int_set:Ne \l_@@_x_direction_int { 0 - \l_@@_y_direction_int } \int_set:Ne \l_@@_y_direction_int { \l_tmpb_int } } } \IfBooleanT{ #1 } { \bool_gset_eq:NN \g_@@_swap_xy_bool \l_@@_swap_xy_bool \int_gset_eq:NN \g_@@_x_direction_int \l_@@_x_direction_int \int_gset_eq:NN \g_@@_y_direction_int \l_@@_y_direction_int } } % \end{macrocode} % \begin{macrocode} \NewDocumentCommand \weiqimirror { s o } { \IfNoValueTF { #2 } { \str_set:Nn \l_tmpa_str { xy } } { \str_set:Nx \l_tmpa_str { #2 } } \str_case_e:nn { \l_tmpa_str } { { x } { \int_set:Ne \l_@@_x_direction_int { 0 - \l_@@_x_direction_int } } { y } { \int_set:Ne \l_@@_y_direction_int { 0 - \l_@@_y_direction_int } } { xy } { \int_set:Ne \l_@@_x_direction_int { 0 - \l_@@_x_direction_int } \int_set:Ne \l_@@_y_direction_int { 0 - \l_@@_y_direction_int } } } \IfBooleanT{ #1 } { \bool_set_eq:NN \g_@@_swap_xy_bool \l_@@_swap_xy_bool \int_set_eq:NN \g_@@_x_direction_int \l_@@_x_direction_int \int_set_eq:NN \g_@@_y_direction_int \l_@@_y_direction_int } } % \end{macrocode} % \begin{macrocode} \NewDocumentCommand \weiqiposition { s o } { \IfNoValueTF { #2 } { \int_set:Nn \l_tmpa_int { 0 } } { \int_set:Ne \l_tmpa_int { #2 } } \int_compare:nNnT { \l_tmpa_int } < { 0 } { \int_add:Nn \l_tmpa_int { 360 } } \int_case:nn { \l_tmpa_int } { { 0 } { \bool_set_false:N \l_@@_swap_xy_bool \int_set:Nn \l_@@_x_direction_int { 1 } \int_set:Nn \l_@@_y_direction_int { 1 } } { 90 } { \bool_set_true:N \l_@@_swap_xy_bool \int_set:Nn \l_@@_x_direction_int { 1 } \int_set:Nn \l_@@_y_direction_int { -1 } } { 180 } { \bool_set_false:N \l_@@_swap_xy_bool \int_set:Nn \l_@@_x_direction_int { -1 } \int_set:Nn \l_@@_y_direction_int { -1 } } { 270 } { \bool_set_true:N \l_@@_swap_xy_bool \int_set:Nn \l_@@_x_direction_int { -1 } \int_set:Nn \l_@@_y_direction_int { 1 } } } \IfBooleanT{ #1 } { \bool_gset_eq:NN \g_@@_swap_xy_bool \l_@@_swap_xy_bool \int_gset_eq:NN \g_@@_x_direction_int \l_@@_x_direction_int \int_gset_eq:NN \g_@@_y_direction_int \l_@@_y_direction_int } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqiscale} % 缩放棋盘。 % \begin{macrocode} \NewDocumentCommand \weiqiscale { s o } { \IfNoValueTF { #2 } { \fp_set:Nn \l_@@_scale_fp { 1.0 } } { \fp_set:Nn \l_@@_scale_fp { #2 * \l_@@_scale_fp } } \IfBooleanT{ #1 } { \fp_set_eq:NN \g_@@_scale_fp \l_@@_scale_fp } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqiminsize} % 最å°æ˜¾ç¤ºå°ºå¯¸ã€‚ % \begin{macrocode} \NewDocumentCommand \weiqiminsize { s m m } { \int_set:Nn \l_@@_min_width_int { #2 } \int_set:Nn \l_@@_min_hight_int { #3 } \IfBooleanT{ #1 } { \int_gset:Nn \g_@@_min_width_int { #2 } \int_gset:Nn \g_@@_min_hight_int { #3 } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\saveweiqi} % ä¿å˜å¯¹å±€ã€‚ % \begin{macrocode} \NewDocumentCommand \saveweiqi { s o } { \IfNoValueTF { #2 } { \str_set:Nx \l_tmpa_str { Default } } { \str_set:Nx \l_tmpa_str { \int_to_alph:n { #2 } } } \cs_if_free:cT { g_@@_size_int_\l_tmpa_str } { \int_new:c { g_@@_size_int_\l_tmpa_str } \int_new:c { g_@@_step_count_int_\l_tmpa_str } \intarray_new:cn { g_@@_x_intarray_\l_tmpa_str } { \c_@@_max_step_int } \intarray_new:cn { g_@@_y_intarray_\l_tmpa_str } { \c_@@_max_step_int } \intarray_new:cn { g_@@_player_intarray_\l_tmpa_str } { \c_@@_max_step_int } \seq_new:c { g_@@_label_seq_\l_tmpa_str } \seq_new:c { g_@@_die_seq_\l_tmpa_str } } \int_gset_eq:cN { g_@@_size_int_\l_tmpa_str } \g_@@_size_int \int_gset_eq:cN { g_@@_step_count_int_\l_tmpa_str } \g_@@_step_count_int \int_step_inline:nn { \c_@@_max_step_int } { \intarray_gset:cnn { g_@@_x_intarray_\l_tmpa_str } { ##1 } { \intarray_item:Nn \g_@@_x_intarray { ##1 } } \intarray_gset:cnn { g_@@_y_intarray_\l_tmpa_str } { ##1 } { \intarray_item:Nn \g_@@_y_intarray { ##1 } } \intarray_gset:cnn { g_@@_player_intarray_\l_tmpa_str } { ##1 } { \intarray_item:Nn \g_@@_player_intarray { ##1 } } } \clist_gset_eq:cN { g_@@_label_seq_\l_tmpa_str } \g_@@_label_seq \clist_gset_eq:cN { g_@@_die_seq_\l_tmpa_str } \g_@@_die_seq } % \end{macrocode} % \end{macro} % % % \begin{macro}{\useweiqi} % 使用对局。 % \begin{macrocode} \NewDocumentCommand \useweiqi { s o } { \IfNoValueTF { #2 } { \str_set:Nx \l_tmpa_str { Default } } { \str_set:Nx \l_tmpa_str { \int_to_alph:n { #2 } } } \cs_if_free:cTF { g_@@_size_int_\l_tmpa_str } { \@@_new_game:n { \g_@@_default_size_int } } { \int_set_eq:Nc \l_tmpa_int { g_@@_size_int_\l_tmpa_str } \@@_new_game:n { \l_tmpa_int } \int_gset_eq:Nc \g_@@_step_count_int { g_@@_step_count_int_\l_tmpa_str } \int_step_inline:nn { \c_@@_max_step_int } { \intarray_gset:Nnn \g_@@_x_intarray { ##1 } { \intarray_item:cn { g_@@_x_intarray_\l_tmpa_str } { ##1 } } \intarray_gset:Nnn \g_@@_y_intarray { ##1 } { \intarray_item:cn { g_@@_y_intarray_\l_tmpa_str } { ##1 } } \intarray_gset:Nnn \g_@@_player_intarray { ##1 } { \intarray_item:cn { g_@@_player_intarray_\l_tmpa_str } { ##1 } } } \clist_set_eq:Nc \g_@@_label_seq { g_@@_label_seq_\l_tmpa_str } \clist_set_eq:Nc \g_@@_die_seq { g_@@_die_seq_\l_tmpa_str } } \IfBooleanT{ #1 } { \@@_clear_labels: \int_step_inline:nn { \g_@@_step_count_int } { \seq_gset_item:Nnn \g_@@_label_seq { ##1 } {} } } } % \end{macrocode} % \end{macro} % % % \begin{macro}{\weiqidata} % 查询内部数æ®ã€‚ % \begin{macrocode} \NewDocumentCommand \weiqidata { s } { \noindent 棋盘大å°ï¼š\int_use:N \g_@@_size_int~ (默认:\int_use:N \g_@@_default_size_int)\\ 当å‰å¯¹å±€æ¥æ•°ï¼š\int_use:N \g_@@_step_count_int~(å«çº¯æ ‡ç¾åŠç§»é™¤æ£‹å)\\ \int_compare:nNnT { \g_@@_step_count_int } > { 0 } { åºå·ï¼š($x$,~$y$)ï¼Œæ‰€å±žæ–¹ï¼Œæ ‡ç¾ï¼Œå¤‡æ³¨\\ } \int_step_inline:nn {\g_@@_step_count_int} { \int_set:Ne \l_@@_x_int { \intarray_item:Nn \g_@@_x_intarray { ##1 } } \int_set:Ne \l_@@_y_int { \intarray_item:Nn \g_@@_y_intarray { ##1 } } \int_set:Ne \l_@@_player_int { \intarray_item:Nn \g_@@_player_intarray { ##1 } } \str_set:Nx \l_@@_tmp_str { \seq_item:Nn \g_@@_label_seq { ##1 } } ##1: (\int_use:N \l_@@_x_int,~\int_use:N \l_@@_y_int), \int_case:nn { \l_@@_player_int } { { 1 } { B } { 2 } { W } { 3 } { L } { 0 } { - } }, \str_if_empty:NTF \l_@@_tmp_str { \meta{空} } { \l_@@_tmp_str }, \int_compare:nNnTF { \l_@@_player_int } = { 0 } { \meta{æ— æ•ˆ} } { \seq_if_in:NnT \g_@@_die_seq { ##1 } { \meta{æ»å} } { \int_compare:nNnT { \l_@@_x_int } = { 0 } { \meta{虚ç€} } } }\\ } 红色指示点: \clist_if_empty:NTF \g_@@_red_point_clist { \meta{空} } { \clist_use:Nn \g_@@_red_point_clist {,~} }\\ 绿色指示点: \clist_if_empty:NTF \g_@@_green_point_clist { \meta{空} } { \clist_use:Nn \g_@@_green_point_clist {,~} }\\ è“色指示点: \clist_if_empty:NTF \g_@@_blue_point_clist { \meta{空} } { \clist_use:Nn \g_@@_blue_point_clist {,~} }\\ æ–¹ä½ä¿¡æ¯ï¼š \int_use:N \l_@@_x_direction_int,~ \int_use:N \l_@@_x_direction_int,~ \bool_to_str:N \l_@@_swap_xy_boolï¼›~ (全局: \int_use:N \g_@@_x_direction_int,~ \int_use:N \g_@@_x_direction_int,~ \bool_to_str:N \g_@@_swap_xy_bool )\\ 缩放比例:\fp_use:N \l_@@_scale_fp~ (全局:\fp_use:N \g_@@_scale_fp)\\ åæ ‡åˆ»åº¦ï¼š\l_@@_loc_mode_str,~\bool_to_str:N \l_@@_show_loc_bool (全局:\g_@@_loc_mode_str,~\bool_to_str:N \g_@@_show_loc_bool)\\ 最å°æ˜¾ç¤ºå°ºå¯¸ï¼š \int_use:N \l_@@_min_width_int,~ \int_use:N \l_@@_min_hight_int~ (全局: \int_use:N \g_@@_min_width_int,~ \int_use:N \g_@@_min_hight_int )\\ \IfBooleanT{ #1 } { 棋å区间: (\int_use:N \l_@@_x_min_int,~\int_use:N \l_@@_y_max_int), (\int_use:N \l_@@_x_max_int,~\int_use:N \l_@@_y_min_int)\\ 棋盘边界: (\fp_use:N \l_@@_x_min_fp,~\fp_use:N \l_@@_x_max_fp), (\fp_use:N \l_@@_y_min_fp,~\fp_use:N \l_@@_y_max_fp)\\ 是å¦è¾¹è·¯ï¼š \bool_to_str:N \l_@@_up_bool, \bool_to_str:N \l_@@_down_bool, \bool_to_str:N \l_@@_left_bool, \bool_to_str:N \l_@@_right_bool(上下左å³ï¼‰\\ } } % \end{macrocode} % \end{macro} % % % \subsection{扫尾} % % åˆå§‹æ–°å¯¹å±€ % \begin{macrocode} \newweiqi % \end{macrocode} % % å…³é— expl3 æ¨¡å¼ % \begin{macrocode} \ExplSyntaxOff % \end{macrocode} % % \begin{macrocode} %</package> % \end{macrocode} % % \end{implementation} % % \PrintIndex