%% Copyright (C) 2020-2022 by Nan Geng <nangeng@nwafu.edu.cn> %% -------------------------------------------------------------------------- %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License, either %% version 1.3c of this license or (at your option) any later %% version. This version of this license is in %% http://www.latex-project.org/lppl/lppl-1-3c.txt %% and the latest version of this license is in %% http://www.latex-project.org/lppl.txt %% and version 1.3 or later is part of all distributions of %% LaTeX version 2005/12/01 or later. %% %% This work has the LPPL maintenance status "maintained". %% %% The Current Maintainer of this work is Nan Geng. %% %% -------------------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e}[2020/10/01] \RequirePackage{expl3} \ProvidesExplPackage{chinesechess}{2022-05-09}{v1.2.0} {Typeset Chinese chess with l3draw} \RequirePackage { l3keys2e, l3draw, xparse } % 测é‡ç›’忀»é«˜åº¦(ä¿è¯TeXLiveçš„å‘下兼容) \cs_if_free:NT \box_ht_plus_dp:N { \cs_new_protected:Npn \box_ht_plus_dp:N #1 { \tex_dimexpr:D \box_ht:N #1 + \box_dp:N #1 \scan_stop: } } % æ£‹ç›˜æŽ’ç‰ˆå‘½ä»¤ç”¨æˆ·æŽ¥å£ % #1 星å·å‘½ä»¤ï¼Œæ˜¯å¦è¾“出棋å % #2 æ£‹ç›˜ç±»åž‹ã€æ£‹å类型ç‰å¤–观选项 \NewDocumentCommand{\cchessboard}{ s o } { \group_begin: % 星å·å‘½ä»¤æ˜¯å¦å¸¦æ£‹å \IfBooleanTF{ #1 } { \bool_set_false:N \l__cchess_board_pieces_bool }{ \bool_set_true:N \l__cchess_board_pieces_bool } \IfNoValueF { #2 } { % 设置选项 \keys_set:nn { cchess } { #2 } % 有draft傿•°ï¼Œéœ€è¦é‡æž„棋å和棋盘 \tl_if_in:nnT { #2 } { draft } { % 构建棋盘 \__cchess_board_construct: % 构建红黑å„9个棋å \__cchess_pieces_construct: } \bool_if:NF \g__cchess_draft_bool { % 构建棋盘 \__cchess_board_option_if_in:nT { #2 } { \__cchess_board_construct: } % 构建红黑å„9个棋å \__cchess_piece_option_if_in:nT { #2 } { \__cchess_pieces_construct: } } } \__cchess_board_output: \group_end: } % æ£‹è°±æŽ’ç‰ˆå‘½ä»¤ç”¨æˆ·æŽ¥å£ % #1 æ£‹ç›˜ç±»åž‹ã€æ£‹å类型ç‰å¤–观选项 % #2 棋åä½ç½®åˆ—表 % 红棋:K=帅,A=仕,E/B=相,R=车,C=ç ²,N/H=马,P=å…µ, % 黑棋:k=å°†,a=士,e/b=象,r=車,c=ç‚®,n/h=馬,p=å’ % 横å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8) % 纵å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9) \NewDocumentCommand{\cchessman}{ o m } { \group_begin: % 设置选项 \IfNoValueF { #1} { \keys_set:nn { cchess } { #1 } % 有draft傿•°ï¼Œéœ€è¦é‡æž„棋å和棋盘 \tl_if_in:nnT { #1 } { draft } { % 构建棋盘 \__cchess_board_construct: % 构建红黑å„9个棋å \__cchess_pieces_construct: } \bool_if:NF \g__cchess_draft_bool { % 构建棋盘 \__cchess_board_option_if_in:nT { #1 } { \__cchess_board_construct: } % 构建红黑å„9个棋å \__cchess_piece_option_if_in:nT { #1 } { \__cchess_pieces_construct: } } } \__cchess_manual_output:n { #2 } \group_end: } % 棋åå—符å¤ä½ \NewDocumentCommand{\resetpiece}{} { % 定义棋åå—ç¬¦å¸¸é‡ \clist_map_inline:nn { { K } { 帥 }, % 帥\__cchess_symbol:n {"5E25} { A } { 仕 }, % 仕\__cchess_symbol:n {"4ED5} { E } { 相 }, % 相\__cchess_symbol:n {"76F8} { B } { 相 }, % 相\__cchess_symbol:n {"76F8} { H } { 马 }, % 马\__cchess_symbol:n {"9A6C} { N } { 马 }, % 马\__cchess_symbol:n {"9A6C} { R } { 车 }, % 车\__cchess_symbol:n {"8F66} { C } { ç ² }, % ç ²\__cchess_symbol:n {"7832} { P } { å…µ }, % å…µ\__cchess_symbol:n {"5175} { k } { å°‡ }, % å°‡\__cchess_symbol:n {"5C07} { a } { 士 }, % 士\__cchess_symbol:n {"58EB} { e } { 象 }, % 象\__cchess_symbol:n {"8C61} { b } { 象 }, % 象\__cchess_symbol:n {"8C61} { h } { 馬 }, % 馬\__cchess_symbol:n {"99AC} { n } { 馬 }, % 馬\__cchess_symbol:n {"99AC} { r } { 車 }, % 車\__cchess_symbol:n {"8ECA} { c } { ç‚® }, % ç‚®\__cchess_symbol:n {"70AE} { p } { å’ }, % å’\__cchess_symbol:n {"5352} } { \__cchess_piece_char_setup:nn ##1 } \bool_if:NF \g__cchess_draft_bool { % 构建红黑å„9个棋å \__cchess_pieces_construct: } } % 棋åå—符设置命令 % #1 棋åç¼–å·åŠå—符 % K=帅,A=仕,B/E=相,R=车,C=ç ²,N/H=马,P=å…µ % k=å°†,a=士,b/e=象,r=車,c=ç‚®,n/h=馬,p=å’ \NewDocumentCommand{\piecechar}{ m m } { \__cchess_piece_char_setup:nn { #1 } { #2 } \bool_if:NF \g__cchess_draft_bool { % 构建红黑å„9个棋å \__cchess_pieces_construct: } } % 打谱环境åˆå§‹åŒ–(仅用于setcchessman环境ä¸) % #1 棋åä½ç½®åˆ—表 % 红棋:K=帅,A=仕,E/B=相,R=车,C=ç ²,N/H=马,P=å…µ, % 黑棋:k=å°†,a=士,e/b=象,r=車,c=ç‚®,n/h=馬,p=å’ % 横å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8) % 纵å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9) \NewDocumentCommand{\init}{ m } { % 临时clist \clist_set:Nn \l_tmpa_clist { #1 } % 替æ¢å ä½ç›’å内容 \clist_map_inline:Nn \l_tmpa_clist { \__cchess_piece_replace_handle:nn ##1 } } % 打谱环境ä¸çš„æ£‹å布置命令(仅用于setcchessman环境ä¸) % #1 棋åä½ç½® % #2 棋åä½ç½®åˆ—表 % 红棋:K=帅,A=仕,E/B=相,R=车,C=ç ²,N/H=马,P=å…µ, % 黑棋:k=å°†,a=士,e/b=象,r=車,c=ç‚®,n/h=馬,p=å’ % 横å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8) % 纵å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9) \NewDocumentCommand{\set}{ m m } { \__cchess_piece_replace_handle:nn { #1 } { #2 } } % åˆ é™¤æ‰“è°±çŽ¯å¢ƒä¸çš„æ£‹å(仅用于setcchessman环境ä¸) % #1 棋åä½ç½®åˆ—表 % 横å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8) % 纵å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9) \NewDocumentCommand{\del}{ m } { \__cchess_piece_remove_handle:n { #1 } } % 移动打谱环境ä¸çš„æ£‹å(仅用于setcchessman环境ä¸) % #1 棋ååç§°(å•ä¸ªè‹±æ–‡å—æ¯) % #2 棋å当å‰ä½ç½® % #3 棋å目的ä½ç½® % 红棋:K=帅,A=仕,E/B=相,R=车,C=ç ²,N/H=马,P=å…µ, % 黑棋:k=å°†,a=士,e/b=象,r=車,c=ç‚®,n/h=馬,p=å’ % 横å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8) % 纵å‘定ä½: a(0),b(1),c(2),d(3),e(4),f(5),g(6),h(7),i(8),j(9) \NewDocumentCommand{\mov}{ m m m } { \__cchess_piece_move_handle:nnn { #1 } { #2 } { #3 } } % æ‰“è°±æŽ’ç‰ˆçŽ¯å¢ƒç”¨æˆ·æŽ¥å£ % #1 æ£‹ç›˜ç±»åž‹ã€æ£‹å类型ç‰å¤–观选项 \NewDocumentEnvironment{ setcchessman }{ o +b } { \group_begin: \bool_set_false:N \l__cchess_with_setman_bool % 设置选项 \IfNoValueF { #1} { \keys_set:nn { cchess } { #1 } % 有draft傿•°ï¼Œéœ€è¦é‡æž„棋å和棋盘 \tl_if_in:nnT { #1 } { draft } { % 构建棋盘 \__cchess_board_construct: % 构建红黑å„9个棋å \__cchess_pieces_construct: } \bool_if:NF \g__cchess_draft_bool { % 构建棋盘 \__cchess_board_option_if_in:nT { #1 } { \__cchess_board_construct: } % 构建红黑å„9个棋å \__cchess_piece_option_if_in:nT { #1 } { \__cchess_pieces_construct: } } } \__cchess_setcchessman_pre_setup:n { #2 } }{ \__cchess_setcchessman_post_setup: \group_end: } % 打谱排版星å·çŽ¯å¢ƒç”¨æˆ·æŽ¥å£ï¼Œç”¨äºŽåŒæ—¶è¾“出棋谱æè¿° % #1 æ£‹ç›˜ç±»åž‹ã€æ£‹å类型ç‰å¤–观选项 \NewDocumentEnvironment{ setcchessman* }{ o +b } { \group_begin: \bool_set_true:N \l__cchess_with_setman_bool % 设置选项 \keys_set:nn { cchess } { #1 } \__cchess_setcchessman_pre_setup:n { #2 } }{ \__cchess_setcchessman_post_setup: \group_end: } % æ‰“è°±æ£‹è°±è¾“å‡ºç”¨æˆ·æŽ¥å£ % #1 æ¯è¡Œè¾“å‡ºæ¥æ•° % #2 棋谱交å‰å¼•用label % å‚考雾月的回å¤ï¼šhttps://ask.latexstudio.net/ask/question/7430.html \NewDocumentCommand{\printman}{ O{} >{\TrimSpaces} m } % åŽ»æŽ‰ä¸¤ä¾§ç©ºæ ¼ { \group_begin: % 设置选项 \keys_set:nn { cchess } { #1 } \__cchess_setman_print:n { #2 } \group_end: } % 棋åè¾“å‡ºç”¨æˆ·æŽ¥å£ % #1 棋åå—体å—å· % #2 棋åç¼–ç % 红棋:K=帅,A=仕,E/B=相,R=车,C=ç ²,N/H=马,P=å…µ, % 黑棋:k=å°†,a=士,e/b=象,r=車,c=ç‚®,n/h=馬,p=å’ \NewDocumentCommand{\getpiece}{ O{\normalsize} m } { \group_begin: \__cchess_getpiece_handle:nn {#1} { #2 } \group_end: } % ==========棋åå—符常é‡å®šä¹‰===================== % 读å–ç¬¦å· \cs_new:Npn \__cchess_symbol:n #1 { #1 % \tex_char:D #1 % \scan_stop: } % 棋å符å·å®šä¹‰ \cs_new_protected:Npn \__cchess_piece_define:nn #1#2 { \tl_const:cn { c__cchess_ #1 _tl } { \__cchess_symbol:n { #2 } } } % ==========å˜é‡å®šä¹‰===================== % 绘制棋盘时是å¦å¸¦æœ‰æ£‹åæ ‡å¿— \bool_new:N \l__cchess_board_pieces_bool \bool_new:N \l__cchess_with_setman_bool \bool_new:N \g__cchess_draft_bool % 棋å容器 % 当å‰ä¸å›½è±¡æ£‹ä¸»æµè½¯ä»¶çš„æ£‹å代ç ,多沿用: % K A B N R C P % 帅 仕 相 马 车 ç‚® å…µ % ï¼ˆçº¢æ–¹ç”¨å¤§å†™å—æ¯ï¼Œé»‘æ–¹å°å†™ï¼‰ % 出于对国际象棋棋手æ„è¯†ä¹ æƒ¯çš„å…¼å®¹æ€§è®¾è®¡ % 相 B ,也å¯å…¼å®¹ä½¿ç”¨ E, % 马N, 也å¯å…¼å®¹ä½¿ç”¨ H 代替 % 在æ¤ï¼Œä¸ºå…¼å®¹æ€§è€ƒè™‘使用B/EåŒæ—¶è¡¨ç¤ºç›¸ï¼Œä½¿ç”¨H/NåŒæ—¶è¡¨ç¤ºé©¬ % 在使用时,å¯ä»¥ä»»æ„é€‰æ‹©ä¹ æƒ¯çš„åç§° % 判æ–红黑棋å英文å•å—æ¯åç§°çš„æ£åˆ™è¡¨è¾¾å¼ \regex_new:N \l__capital_regex \regex_set:Nn \l__capital_regex { [KAEBRCHNP] } % 棋å英文å•å—æ¯å称列表 \clist_const:Nn \c__cchess_pieces_name_clist { K,A,E,B,R,C,H,N,P,k,a,e,b,r,c,h,n,p } \msg_new:nnn { cchess } { piecename-exists } { The~ piece~ name~ `#1~ not~ exists. } % 定义棋åå—ç¬¦å¸¸é‡ % 注æ„相和马分别用两个符å·ä»¥é€‚é…ä¸åŒä¹ 惯 \clist_map_inline:nn { { K } { 帥 }, % 帥"5E25 { A } { 仕 }, % 仕"4ED5 { E } { 相 }, % 相"76F8 { B } { 相 }, % 相"76F8 { H } { 马 }, % 马"9A6C { N } { 马 }, % 马"9A6C { R } { 车 }, % 车"8F66 { C } { ç ² }, % ç ²"7832 { P } { å…µ }, % å…µ"5175 { k } { å°‡ }, % å°‡"5C07 { a } { 士 }, % 士"58EB { e } { 象 }, % 象"8C61 { b } { 象 }, % 象"8C61 { h } { 馬 }, % 馬"99AC { n } { 馬 }, % 馬"99AC { r } { 車 }, % 車"8ECA { c } { ç‚® }, % ç‚®"70AE { p } { å’ }, % å’"5352 } { \__cchess_piece_define:nn #1 } % 定义棋åç¼–ç 与å—符对照属性表 \prop_new:N \c__cchess_board_pieces_alph_name_prop \clist_map_inline:Nn \c__cchess_pieces_name_clist { \prop_put:NnV \c__cchess_board_pieces_alph_name_prop { #1 } { \use:c { c__cchess_ #1 _tl } } } % 在棋åç¼–ç åˆ—è¡¨ä¸æ·»åŠ z表示空棋å \clist_push:Nn \c__cchess_pieces_name_clist { z } % 定义棋åç›’å容器 \clist_map_inline:Nn \c__cchess_pieces_name_clist { \coffin_new:c { l__cchess_piece_ #1 _coffin } } % 将空棋åç›’å容器置空 \hcoffin_gset:Nn \l__cchess_piece_z_coffin { \phantom{a} } % 棋盘盒å容器 \coffin_new:N \l__cchess_board_coffin % 棋盘背景盒å容器 \coffin_new:N \l__cchess_board_background_coffin % 棋谱容器 \coffin_new:N \l__cchess_manual_coffin % åˆ¤æ–æ˜¯å¦ä¸ºå—æ¯ä½ç½®çš„æ£åˆ™è¡¨è¾¾å¼ \regex_new:N \l__alph_regex \regex_set:Nn \l__alph_regex { [a-j] } % 棋åä½ç½®å—æ¯ä¸Žæ•°å—对应关系 \prop_const_from_keyval:Nn \c__cchess_board_pos_alph_num_prop { a = 0, b = 1, c = 2 , d = 3, e = 4, f = 5, g = 6, h = 7, i = 8, j = 9 } \coffin_new:N \l__cchess_board_pieces_pos_coffin % åˆ¤æ–æ˜¯å¦ä¸ºæ•°å€¼ä½ç½®çš„æ£åˆ™è¡¨è¾¾å¼ \regex_new:N \l__digit_regex \regex_set:Nn \l__digit_regex { [0-9] } % 棋åä½ç½®æ•°å—ä¸Žå—æ¯å¯¹åº”关系 \prop_const_from_keyval:Nn \c__cchess_board_pos_num_alph_prop { 0 = a, 1 = b, 2 = c, 3 = d, 4 = e, 5 = f, 6 = g, 7 = h, 8 = i, 9 = j } % åˆ¤æ–æ˜¯æ¨ªå‘ä½ç½®åˆæ³•性的列表 \clist_const:Nn \c__cchess_pos_x_index_clist { a,b,c,d,e,f,g,h,i,0,1,2,3,4,5,6,7,8 } \msg_new:nnn { cchess } { posx-exists } { The~ x~ index~ `#1~ not~ exists. } % åˆ¤æ–æ˜¯çºµå‘ä½ç½®åˆæ³•性的列表 \clist_const:Nn \c__cchess_pos_y_index_clist { a,b,c,d,e,f,g,h,i,j,0,1,2,3,4,5,6,7,8,9 } \msg_new:nnn { cchess } { posy-exists } { The~ y~ index~ `#1~ not~ exists. } % 棋åå ä½ç›’å容器 \clist_const:Nn \c__cchess_board_pos_x_clist { a,b,c,d,e,f,g,h,i } \clist_const:Nn \c__cchess_board_pos_y_clist { a,b,c,d,e,f,g,h,i,j } \clist_map_inline:Nn \c__cchess_board_pos_x_clist { \clist_map_inline:Nn \c__cchess_board_pos_y_clist { \coffin_new:c { l__cchess_board_piece_ #1 _ ##1 _coffin } \hcoffin_gset:cn { l__cchess_board_piece_ #1 _ ##1 _coffin } { \phantom{a} } } } \coffin_new:N \l__cchess_board_piece_z_coffin \hcoffin_gset:Nn \l__cchess_board_piece_z_coffin { \phantom{a} } % çº¢æ–¹æ£‹ç›˜åæ ‡å—æ¯ä¸Žçº¢æ£‹ç«–çº¿æ ‡ä½å¯¹åº”关系 \prop_const_from_keyval:Nn \c__cchess_board_red_x_idx_prop { a = ä¹, b = å…«, c = 七 , d = å…, e = 五, f = å››, g = 三, h = 二, i = 一 } % é»‘æ–¹æ£‹ç›˜åæ ‡å—æ¯ä¸Žé»‘æ£‹ç«–çº¿æ ‡ä½å¯¹åº”关系 \prop_const_from_keyval:Nn \c__cchess_board_black_x_idx_prop { a = 1, b = 2, c = 3 , d = 4, e = 5, f = 6, g = 7, h = 8, i = 9 } % 英文数å—ä¸Žä¸æ–‡æ•°å—的对应关系 \prop_const_from_keyval:Nn \c__cchess_board_pos_arabic_zh_prop { 0 = 〇, 1 = 一, 2 = 二, 3 = 三, 4 = å››, 5 = 五, 6 = å…, 7 = 七, 8 = å…«, 9 = ä¹ } % 棋谱记录列表(如车一进二ç‰) \clist_new:N \l__cchess_manual_clist % 棋å外框盒å容器 \coffin_new:N \l__cchess_box_coffin % 棋åç›’å容器 \coffin_new:N \l__cchess_piece_coffin % 楚河汉界盒å容器 \coffin_new:N \l__cchess_char_a_coffin \coffin_new:N \l__cchess_char_b_coffin \coffin_new:N \l__cchess_char_c_coffin \coffin_new:N \l__cchess_char_d_coffin % 临时盒å容器 \coffin_new:N \l__cchess_tmpa_coffin \coffin_new:N \l__cchess_tmpb_coffin \coffin_new:N \l__cchess_tmpc_coffin \coffin_new:N \l__cchess_tmpd_coffin \clist_set:Nn \l_tmpa_clist { a,b,c,d } \clist_map_inline:Nn \l_tmpa_clist { \coffin_new:c { l_char_tmp #1 _coffin } } % 棋å类型 \tl_new:N \l__cchess_piece_box_type_tl % 棋å类型列表 \clist_new:N \g__cchess_piece_box_list_clist % 棋盘类型 \tl_new:N \l__cchess_board_type_tl % 棋盘类型列表 \clist_new:N \g__cchess_board_list_clist % ç¼©æ”¾æ–¹å¼ \tl_new:N \l__cchess_resize_method_tl % 缩放方å¼åˆ—表 \clist_new:N \g__cchess_resize_method_clist % 棋谱输出宽度 \dim_new:N \l__cchess_manual_width_dim % 棋谱输出高度 \dim_new:N \l__cchess_manual_height_dim % 棋盘宽度 \dim_new:N \l__cchess_board_width_dim % 棋盘高度 \dim_new:N \l__cchess_board_height_dim % 棋盘线线宽 \dim_new:N \l__cchess_board_linewidth_dim % 辅线线宽 \dim_new:N \l__cchess_cross_linewidth_dim % è¾…çº¿é—´è· \dim_new:N \l__cchess_cross_sep_dim % 棋åå—ç¬¦æ£æ–¹å½¢å¤–接圆åŠå¾„ \dim_new:N \l__cchess_piece_box_radius_dim % 棋å外框线线宽 \dim_new:N \l__cchess_box_linewidth_dim % æ£‹ç›˜æ ¼å尺寸 \dim_new:N \gridsize % æ£‹åæ•´ä½“尺寸 \dim_new:N \piecesize % 棋åå—符包围盒尺寸 \dim_new:N \charboxsize % 棋åå—符包围盒尺寸åŠé•¿ \dim_new:N \semicharboxsize % 临时尺寸å˜é‡ \dim_new:N \l__cchess_tmpa_dim \dim_new:N \l__cchess_tmpb_dim \dim_new:N \l__cchess_tmpc_dim \dim_new:N \l__cchess_tmpd_dim % 棋åå—ç¬¦æ ¼å¼ \tl_new:N \l__cchess_piece_char_format_tl % 棋盘背景图片åç§° \tl_new:N \l__cchess_board_background_tl % 棋åå—符å—形类型(实线ã€è™šçº¿ç‰) \int_new:N \l__cchess_charstroke_type_int % æ‰“è°±çŽ¯å¢ƒæ£‹è°±æ ‡ç¾ \tl_new:N \l__cchess_setman_label_tl % 打谱结果æ¯è¡Œæ£‹è°±æ¥æ•° \int_new:N \l__cchess_mans_per_line_int % 打谱环境用计数器 \newcounter{setman} % å¢žåŠ ä¸¤ä¸ªä¸´æ—¶intå˜é‡ \int_new:N \l_tmpc_int \int_new:N \l_tmpd_int \int_new:N \l_tmpe_int % å¢žåŠ ä¸¤ä¸ªä¸´æ—¶tlå˜é‡ \tl_new:N \l_tmpc_tl \tl_new:N \l_tmpd_tl \tl_new:N \l_tmpe_tl % ============å®åŒ…选项================= \keys_define:nn { cchess } { draft .choice:, draft / true .code:n = { \bool_set_true:N \g__cchess_draft_bool }, draft / false .code:n = { \bool_set_false:N \g__cchess_draft_bool }, draft .default:n = true, draft .initial:n = false, unknown .code:n = { \msg_error:nn { cchess } { unknown-option } } } % å°†æ–‡æ¡£ç±»é€‰é¡¹ä¼ ç»™cchess % \ProcessKeysOptions { cchess } % 棋åç›’åç”±l3draw实现, % 棋å外围盒ååŠç¼©æ”¾è®¾è®¡æ€è·¯æ¥è‡ªzitieå®åŒ… % (\url{https://www.ctan.org/pkg/zitie})。 % =============颜色处ç†å‡½æ•°============= % 填充色辅助函数 \cs_new_nopar:Nn \__cchess_aux_color_boxfill: { } % 颜色命å函数 % #1 颜色åç§° % #2 é¢œè‰²è¡¨è¾¾å¼ \cs_set_nopar:Npn \__cchess_color_select:nn #1#2 { \color_set:nn {#1} {#2} } \cs_generate_variant:Nn \__cchess_color_select:nn {nx} % 颜色命å函数 % #1 颜色åç§° % #2 颜色空间 % #3 颜色分é‡å€¼ \cs_set_nopar:Npn \__cchess_color_select:nnn #1#2#3 { \color_set:nnn {#1} {#2} {#3} } \cs_generate_variant:Nn \__cchess_color_select:nnn {nnx} % =============基础尺寸计算函数============= % ç›’å容器总高度计算函数 \cs_new_nopar:Npn \__cchess_coffin_ht_plus_dp:N #1 { \coffin_ht:N #1 + \coffin_dp:N #1 } % 计算外框大å°(å¤–æŽ¥æ£æ–¹å½¢è¾¹é•¿å’Œå¤–接圆åŠå¾„) \cs_new:Npn \__cchess_calc_piece_box_size: { % 设置计算基础盒å \hbox_set:Nn \l_tmpa_box { xx } % ç›’å宽度 \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box } % ç›’å高度 \dim_set:Nn \l_tmpb_dim { \box_ht_plus_dp:N \l_tmpa_box } % æ£æ–¹å½¢è¾¹é•¿ \dim_compare:nNnTF \l_tmpa_dim > \l_tmpb_dim { \dim_gset_eq:NN \charboxsize \l_tmpa_dim } { \dim_gset_eq:NN \charboxsize \l_tmpb_dim } \dim_gadd:Nn \charboxsize { 2pt } % 包围盒åŠé•¿ \dim_gset:Nn \semicharboxsize { \fp_to_dim:n { \fp_eval:n { \charboxsize / 2 } } % \charboxsize / 2 } % 外接圆åŠå¾„ \dim_gset:Nn \l__cchess_piece_box_radius_dim { \fp_to_dim:n { \fp_eval:n { \charboxsize * sqrt(2)/ 2 } } % \fp_to_dim:n { \fp_eval:n { \charboxsize * 0.707106781 } } } } % =============æž„é€ æ£‹å函数============= % å—ç¬¦ç›’åæž„é€ ç±»åž‹å‡½æ•°å称生æˆå‡½æ•° % #1 缩放比例 \cs_new_nopar:Npn \__cchess_piece_box_type:n #1 { __cchess_piece_box_construct_type_ #1 :n } % å—ç¬¦ç›’åæž„é€ ç±»åž‹å‡½æ•°å称命令生æˆå‡½æ•° % #1 缩放比例 \cs_new_nopar:Npn \__cchess_piece_box_type_c:n #1 { \use:c { __cchess_piece_box_construct_type_ #1 :n } } % å—ç¬¦ç›’åæž„é€ ç±»åž‹å‡½æ•°å†…éƒ¨ç”Ÿæˆå™¨å‡½æ•° % #1 类型åç§° \cs_new:Npn \__cchess_new_piece_box_private_construct:nn #1 { % 类似\cs_new:cn __cchess_piece_box_construct_type_none:n \cs_new:cn { \__cchess_piece_box_type:n {#1} } } \cs_generate_variant:Nn \__cchess_new_piece_box_private_construct:nn { V } \cs_generate_variant:Nn \__cchess_new_piece_box_private_construct:nn { x } % å—ç¬¦ç›’åæž„é€ ç±»åž‹å‡½æ•°ç”Ÿæˆå™¨å‡½æ•° % #1 类型åç§° \cs_new:Npn \__cchess_new_piece_box_construct:nn #1 { % 将类型åç§°è®°å…¥clist \clist_put_right:Nn \g__cchess_piece_box_list_clist {#1} % 类似\cs_new:cn __cchess_piece_box_construct_type_none:n \cs_new:cn { \__cchess_piece_box_type:n {#1} } } \cs_generate_variant:Nn \__cchess_new_piece_box_construct:nn { V } \cs_generate_variant:Nn \__cchess_new_piece_box_construct:nn { x } % 定义å—符边框盒å类型内部函数 % æ— è¾¹æ¡† \__cchess_new_piece_box_construct:nn { none } { } % 底层填充外接圆 \__cchess_new_piece_box_private_construct:nn { __outerlowerfilledcircle } { \draw_scope_begin: \color_fill:n { lowerbgboxfill } \draw_path_circle:nn { \semicharboxsize, \semicharboxsize } { \l__cchess_piece_box_radius_dim*#1 } \draw_path_use_clear:n { fill } \draw_scope_end: } % 顶层填充外接圆 \__cchess_new_piece_box_private_construct:nn { __outerupperfilledcircle } { \draw_scope_begin: \color_fill:n { upperbgboxfill } \draw_path_circle:nn { \semicharboxsize, \semicharboxsize } { \l__cchess_piece_box_radius_dim*#1 } \draw_path_use_clear:n { fill } \draw_scope_end: } % 圆环层填充外接圆 \__cchess_new_piece_box_private_construct:nn { __outerdonutfilledcircle } { \draw_scope_begin: \color_fill:n { donutboxfill } \draw_path_circle:nn { \semicharboxsize, \semicharboxsize } { \l__cchess_piece_box_radius_dim*#1 } \draw_path_use_clear:n { fill } \draw_scope_end: } % 阴影填充外接圆 \__cchess_new_piece_box_private_construct:nn { __outershadowfilledcircle } { \draw_scope_begin: \color_fill:n { shadowboxfill } \draw_transform_shift:n { \charboxsize*0.1, -\charboxsize*0.1 } \draw_path_circle:nn { \semicharboxsize, \semicharboxsize } { \l__cchess_piece_box_radius_dim*#1 } \draw_path_use_clear:n { fill } \draw_scope_end: } % 外接圆边框 \__cchess_new_piece_box_private_construct:nn { __outercirclebox } { \draw_scope_begin: \color_stroke:n { cchesspieceboxcolor } \draw_path_circle:nn { \semicharboxsize, \semicharboxsize } { \l__cchess_piece_box_radius_dim*#1 } \draw_path_use_clear:n { stroke } \draw_scope_end: } % 填充外接圆å åŠ å¤–æŽ¥åœ†è¾¹æ¡† \__cchess_new_piece_box_construct:nn { o } { \__cchess_piece_box_type_c:n { __outerupperfilledcircle } {0.82} \__cchess_piece_box_type_c:n { __outercirclebox } {0.82} } % 填充外接圆å åŠ åŒå¿ƒ82%外接圆边框 \__cchess_new_piece_box_construct:nn { oo } { \__cchess_piece_box_type_c:n { __outerupperfilledcircle } {#1} \__cchess_piece_box_type_c:n { __outercirclebox } {#1} \__cchess_piece_box_type_c:n { __outercirclebox } {0.82} } % 3åŒå¿ƒåœ†å åŠ (阴影) \__cchess_new_piece_box_construct:nn { ooo } { % 绘制填充外接圆阴影 \__cchess_piece_box_type_c:n { __outershadowfilledcircle } {1.0} % 绘制填充外接圆外圈背景 \__cchess_piece_box_type_c:n { __outerlowerfilledcircle } {1.0} % 绘制填充外接边环背景 \__cchess_piece_box_type_c:n { __outerdonutfilledcircle } {0.88} % 绘制填充外接圆内圈背景 \__cchess_piece_box_type_c:n { __outerupperfilledcircle } {0.72} % 绘制åŒè¾¹åˆ»çŽ¯çº¿ \__cchess_piece_box_type_c:n { __outercirclebox } {0.88} \__cchess_piece_box_type_c:n { __outercirclebox } {0.72} } \msg_new:nnn { cchess } { box-exists } { The~ box~ type~ `#1~ not~ exists. } % =============æž„é€ æ£‹ç›˜å‡½æ•°============= % æ£‹ç›˜éƒ¨ä»¶æž„é€ å‡½æ•°å‡½æ•°å称生æˆå‡½æ•° % åç§°ä¸2ä¸ªå‚æ•°åˆ†åˆ«è¡¨ç¤ºï¼š % #1 xæ–¹å‘缩放比例(暂未使用, ä¿ç•™å‚æ•°) % #2 yæ–¹å‘缩放比例(暂未使用, ä¿ç•™å‚æ•°) \cs_new_nopar:Npn \__cchess_board_type:n #1 { __cchess_board_construct_type_ #1 :nn } % å称命令ä¸2ä¸ªå‚æ•°åˆ†åˆ«è¡¨ç¤ºï¼š % #1 xæ–¹å‘缩放比例(暂未使用, ä¿ç•™å‚æ•°) % #2 yæ–¹å‘缩放比例(暂未使用, ä¿ç•™å‚æ•°) \cs_new_nopar:Npn \__cchess_board_type_c:n #1 { \use:c { __cchess_board_construct_type_ #1 :nn } } % 棋盘类型函数生æˆå™¨å†…部函数 % #1 类型åç§° \cs_new:Npn \__cchess_new_board_private_construct:nn #1 { % 类似\cs_new:cn __cchess_board_construct_type_none:nn \cs_new:cn { \__cchess_board_type:n {#1} } } \cs_generate_variant:Nn \__cchess_new_board_private_construct:nn { V } \cs_generate_variant:Nn \__cchess_new_board_private_construct:nn { x } % 棋盘类型函数生æˆå™¨å‡½æ•° % #1 类型åç§° \cs_new:Npn \__cchess_new_board_construct:nn #1 { % 将类型åç§°è®°å…¥clist \clist_put_right:Nn \g__cchess_board_list_clist {#1} % 类似\cs_new:cn __cchess_board_construct_type_none:nn \cs_new:cn { \__cchess_board_type:n {#1} } } \cs_generate_variant:Nn \__cchess_new_board_construct:nn { V } \cs_generate_variant:Nn \__cchess_new_board_construct:nn { x } % 空棋盘 \__cchess_new_board_construct:nn { none } { } % ä»…æ ¼å线åŠéƒ¨æ£‹ç›˜ \__cchess_new_board_private_construct:nn { __semiboard } { \draw_scope_begin: \color_stroke:n { cchessboardlinecolor } % ç»˜åˆ¶æ£‹ç›˜ç½‘æ ¼ \draw_path_grid:nnnn { \gridsize } { \gridsize } { 0, 0 } { \gridsize * 8, \gridsize * 4 } % 绘制åŠé•¿è¾¹æ ¼çº¿ \draw_path_moveto:n { 0 , \gridsize * 4 } \draw_path_lineto:n { 0 , \gridsize * 4.5 } \draw_path_moveto:n { \gridsize * 8, \gridsize * 4 } \draw_path_lineto:n { \gridsize * 8, \gridsize * 4.5 } \draw_path_use_clear:n { stroke } \draw_scope_end: } % å…µã€ç‚®4åˆ†ä½æ ‡å¿—(å³ä¸Š) \__cchess_new_board_private_construct:nn { __quaterpos } { % è®¡ç®—æ ‡å¿—é•¿åº¦ \dim_set:Nn \l_tmpa_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * 0.10 } } } \draw_scope_begin: \color_stroke:n { cchessboardlinecolor } \draw_path_scope_begin: \draw_linewidth:n { \l__cchess_cross_linewidth_dim } \draw_path_moveto:n { 0pt , \l_tmpa_dim } \draw_path_lineto:n { 0pt , 0pt } \draw_path_lineto:n { \l_tmpa_dim, 0pt } \draw_path_use_clear:n { stroke } \draw_path_scope_end: \draw_scope_end: } % å…µã€ç‚®å…¨ä½æ ‡å¿— \__cchess_new_board_private_construct:nn { __fullpos } { \draw_scope_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_cross_sep_dim, \l__cchess_cross_sep_dim } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { -\l__cchess_cross_sep_dim, \l__cchess_cross_sep_dim } \draw_transform_rotate:n { 90 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { -\l__cchess_cross_sep_dim, -\l__cchess_cross_sep_dim } \draw_transform_rotate:n { 180 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_cross_sep_dim, -\l__cchess_cross_sep_dim } \draw_transform_rotate:n { 270 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_scope_end: } % å³å‘å…µåŠä½æ ‡å¿— \__cchess_new_board_private_construct:nn { __rightsemipos } { \draw_scope_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_cross_sep_dim, \l__cchess_cross_sep_dim } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_cross_sep_dim, -\l__cchess_cross_sep_dim } \draw_transform_rotate:n { -90 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_scope_end: } % å·¦å‘å…µåŠä½æ ‡å¿— \__cchess_new_board_private_construct:nn { __leftsemipos } { \draw_scope_begin: \draw_path_scope_begin: \draw_transform_shift:n { -\l__cchess_cross_sep_dim, \l__cchess_cross_sep_dim } \draw_transform_rotate:n { 90 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { -\l__cchess_cross_sep_dim, -\l__cchess_cross_sep_dim } \draw_transform_rotate:n { 180 } \__cchess_board_type_c:n { __quaterpos } {#1} {#2} \draw_path_scope_end: \draw_scope_end: } % å…µã€ç‚®æ ‡å¿—(åŠæ£‹ç›˜) \__cchess_new_board_private_construct:nn { __semipos } { \hcoffin_set:Nn \l_tmpa_coffin { \draw_scope_begin: % 绘制兵ã€ç‚®å®šä½æ ‡å¿— \clist_map_variable:nNn {{1,2},{7,2},{2,3},{4,3},{6,3}} \l_tmpa_tl { \clist_set:NV \l_tmpa_clist \l_tmpa_tl \dim_set:Nn \l_tmpa_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * \clist_item:Nn \l_tmpa_clist { 1 } } } } \dim_set:Nn \l_tmpb_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * \clist_item:Nn \l_tmpa_clist { 2 } } } } \draw_path_scope_begin: \draw_transform_shift:n { \l_tmpa_dim, \l_tmpb_dim } \__cchess_board_type_c:n { __fullpos } {#1} {#2} \draw_path_scope_end: } \draw_path_scope_begin: \draw_transform_shift:n { 0, \gridsize * 3 } \__cchess_board_type_c:n { __rightsemipos } {#1} {#2} \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 3 } \__cchess_board_type_c:n { __leftsemipos } {#1} {#2} \draw_path_scope_end: \draw_scope_end: } % 使用盒å容器 \draw_path_scope_begin: \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % æ— å…µã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_private_construct:nn { __semiboardwithpos } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboard } {#1} {#2} \__cchess_board_type_c:n { __semipos } {#1} {#2} } % 使用盒å容器 \draw_path_scope_begin: \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % ä¹å®«å¯¹è§’线 \__cchess_new_board_private_construct:nn { __dguardcross } { \draw_scope_begin: \color_stroke:n { cchessboardlinecolor } \draw_path_scope_begin: \draw_linewidth:n { \l__cchess_cross_linewidth_dim } \draw_transform_shift:n { \gridsize * 3, 0 } \draw_path_moveto:n { 0 , \gridsize * 2 } \draw_path_lineto:n { \gridsize * 2, 0 } \draw_path_moveto:n { 0 , 0 } \draw_path_lineto:n { \gridsize * 2, \gridsize * 2 } \draw_path_use_clear:n { stroke } \draw_path_scope_end: \draw_scope_end: } % 象ä½è™šçº¿ \__cchess_new_board_private_construct:nn { __elephantcross } { \draw_scope_begin: \color_stroke:n { cchessboardlinecolor } \draw_path_scope_begin: \draw_linewidth:n { \l__cchess_cross_linewidth_dim } \draw_dash_pattern:nn { 0.5mm , 0.5mm , 0.5mm , 0.5mm } { 0cm } \draw_path_moveto:n { \gridsize * 2, 0 } \draw_path_lineto:n { \gridsize * 6, \gridsize * 4 } \draw_path_lineto:n { \gridsize * 8, \gridsize * 2 } \draw_path_lineto:n { \gridsize * 6, 0 } \draw_path_lineto:n { \gridsize * 2, \gridsize * 4 } \draw_path_lineto:n { 0 , \gridsize * 2 } \draw_path_lineto:n { \gridsize * 2, 0 } \draw_path_use_clear:n { stroke } \draw_path_scope_end: \draw_scope_end: } % 带炮ã€å…µä½æ ‡å¿—å’Œä¹å®«å¯¹è§’çº¿çš„åŠæ£‹ç›˜ \__cchess_new_board_private_construct:nn { __semiboardposdguardcross } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboardwithpos } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} } % 使用盒å容器 \draw_path_scope_begin: \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % 使用盒å容器函数å˜ä½“ \cs_generate_variant:Nn \draw_coffin_use:Nnn { c } % 构建楚河汉界 \__cchess_new_board_private_construct:nn { __midseptext } { \color_select:n { cchessboardlinecolor } \hcoffin_set:Nn \l_char_tmpa_coffin { 楚 } \hcoffin_set:Nn \l_char_tmpb_coffin { æ²³ } \hcoffin_set:Nn \l_char_tmpc_coffin { æ¼¢ } \hcoffin_set:Nn \l_char_tmpd_coffin { 界 } \clist_map_inline:nn { a, b } { \coffin_rotate:cn { l_char_tmp ##1 _coffin } { -90 } } \clist_map_inline:nn { c, d } { \coffin_rotate:cn { l_char_tmp ##1 _coffin } { 90 } } % 测é‡ç›’å容器总高度 \dim_set:Nn \l_tmpa_dim { \__cchess_coffin_ht_plus_dp:N \l_char_tmpa_coffin } \dim_set:Nn \l_tmpb_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * 0.45 } } } % 缩放盒å容器 \clist_map_inline:nn { a, b, c, d } { \coffin_scale:cnn { l_char_tmp ##1 _coffin } { \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } }{ \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } } } % æŽ’ç‰ˆæ–‡å— \draw_scope_begin: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 2, \gridsize * 4.5 } \draw_transform_shift:n { -\gridsize / 2, 0pt } \draw_coffin_use:cnn { l_char_tmpb_coffin } { hc } { vc } \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 2, \gridsize * 4.5 } \draw_transform_shift:n { \gridsize / 2, 0pt } \draw_coffin_use:cnn { l_char_tmpa_coffin } { hc } { vc } \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 6, \gridsize * 4.5 } \draw_transform_shift:n { -\gridsize / 2, 0pt } \draw_coffin_use:cnn { l_char_tmpc_coffin } { hc } { vc } \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 6, \gridsize * 4.5 } \draw_transform_shift:n { \gridsize / 2, 0pt } \draw_coffin_use:cnn { l_char_tmpd_coffin } { hc } { vc } \draw_path_scope_end: \draw_scope_end: } % æž„å»ºæ•°å—æ ‡è¯† \__cchess_new_board_private_construct:nn { __tbnumtext } { \dim_set:Nn \l__cchess_tmpc_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * 9 + \gridsize * 0.7 } } } \dim_set:Nn \l__cchess_tmpd_dim { \fp_to_dim:n { \fp_eval:n { -\gridsize * 0.7 } } } \color_select:n { cchessboardlinecolor } \clist_set:Nn \l_tmpa_clist { 1,2,3,4,5,6,7,8,9 } \clist_set:Nn \l_tmpb_clist { ä¹,å…«,七,å…,五,å››,三,二,一 } \hcoffin_set:Nn \l_tmpa_coffin { 五 } % 测é‡ç›’å容器总高度 \dim_set:Nn \l_tmpa_dim { \__cchess_coffin_ht_plus_dp:N \l_tmpa_coffin } \dim_set:Nn \l_tmpb_dim { \fp_to_dim:n { \fp_eval:n { \gridsize * 0.25 } } } \draw_scope_begin: \int_set:Nn \l_tmpa_int { 0 } \clist_map_inline:Nn \l_tmpa_clist { \clist_pop:NN \l_tmpb_clist \l_tmpa_tl \hcoffin_set:Nn \l_tmpa_coffin { ##1 } \hcoffin_set:Nn \l_tmpb_coffin { \l_tmpa_tl } \coffin_scale:Nnn \l_tmpa_coffin { \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } }{ \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } } \coffin_scale:Nnn \l_tmpb_coffin { \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } }{ \dim_ratio:nn { \l_tmpb_dim } { \l_tmpa_dim } } \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * \l_tmpa_int, \l__cchess_tmpc_dim } \draw_coffin_use:Nnn \l_tmpa_coffin { hc } { vc } \draw_path_scope_end: \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * \l_tmpa_int, \l__cchess_tmpd_dim } \draw_coffin_use:Nnn \l_tmpb_coffin { hc } { vc } \draw_path_scope_end: \int_incr:N \l_tmpa_int } \draw_scope_end: } % æ— å…µã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_private_construct:nn { __none } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboard } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % æ— å…µã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_construct:nn { x } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboard } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % 有兵ã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_construct:nn { x+ } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboardwithpos } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: } % 有兵ã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_construct:nn { x+t } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboardwithpos } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: \__cchess_board_type_c:n { __midseptext } {#1} {#2} } % 有兵ã€ç‚®æ ‡å¿—全棋盘 \__cchess_new_board_construct:nn { x+tn } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboardwithpos } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: \__cchess_board_type_c:n { __midseptext } {#1} {#2} \__cchess_board_type_c:n { __tbnumtext } {#1} {#2} } % 有兵ã€ç‚®æ ‡å¿—和象ä½çº¿çš„全棋盘 \__cchess_new_board_construct:nn { x+Xtn } { \hcoffin_set:Nn \l_tmpa_coffin { \__cchess_board_type_c:n { __semiboardwithpos } {#1} {#2} \__cchess_board_type_c:n { __dguardcross } {#1} {#2} \__cchess_board_type_c:n { __elephantcross } {#1} {#2} } % 下åŠéƒ¨ \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } % 上åŠéƒ¨ \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * 8, \gridsize * 9 } \draw_transform_rotate:n { 180 } \draw_coffin_use:Nnn \l_tmpa_coffin { l } { b } \draw_path_scope_end: \__cchess_board_type_c:n { __midseptext } {#1} {#2} \__cchess_board_type_c:n { __tbnumtext } {#1} {#2} } \msg_new:nnn { cchess } { board-exists } { The~ board~ type~ `#1~ not~ exists. } % =============缩放处ç†å‡½æ•°============= % 缩放类型å称生æˆå‡½æ•° \cs_new_nopar:Npn \__cchess_resize:n #1 { __cchess_processor_resize_ #1 :w } % 缩放类型函数å称命令生æˆå‡½æ•° \cs_new_nopar:Npn \__cchess_resize_c:n #1 { \use:c { __cchess_processor_resize_ #1 :w } } % 缩放代ç 生æˆå‡½æ•° % #1 dim长度å˜é‡1 % #2 dim长度å˜é‡2 % #3 缩放代ç 1 % #4 缩放代ç 2 % #5 缩放代ç 3 % #6 缩放代ç 4 % 如果 #1 > 0 且 #2 > 0 ,å–#3代ç % 如果 #1 > 0 且 #2 <= 0,å–#4代ç % 如果 #1 <= 0 且 #2 > 0 ,å–#5代ç % 如果 #1 <= 0 且 #2 <= 0,å–#6代ç \cs_new:Npn \__cchess_dim_gezero_dispatch:NNnnnn #1#2 #3#4#5#6 { \dim_compare:nNnTF #1 > \c_zero_dim { \dim_compare:nNnTF #2 > \c_zero_dim { #3 } { #4 } } { \dim_compare:nNnTF #2 > \c_zero_dim { #5 } { #6 } } } % 缩放代ç 生æˆå‡½æ•°(分别按高宽ã€é«˜åº¦ã€å®½åº¦æˆ–实际尺寸缩放) \cs_new:Npn \__cchess_force_size_dispatch:nnnn % both, height, width, none { % \dim_show:N \l__cchess_manual_width_dim \__cchess_dim_gezero_dispatch:NNnnnn \l__cchess_manual_height_dim \l__cchess_manual_width_dim } % æž„é€ ç¼©æ”¾ç±»åž‹ \cs_new:Npn \__cchess_new_resize_method:nn #1 { \clist_put_right:Nn \g__cchess_resize_method_clist {#1} \cs_new:cpn { \__cchess_resize:n {#1} } } % æ— ç¼©æ”¾ \__cchess_new_resize_method:nn { none } { } % æŒ‰å®žé™…å‚æ•°ç¼©æ”¾ \__cchess_new_resize_method:nn { real } { \__cchess_force_size_dispatch:nnnn {% ç›’å宽高缩放 \coffin_resize:Nnn \l__cchess_manual_coffin \l__cchess_manual_width_dim \l__cchess_manual_height_dim } {% 指定高度为比例缩放 \coffin_scale:Nnn \l__cchess_manual_coffin { \dim_ratio:nn { \l__cchess_manual_height_dim } { \__cchess_coffin_ht_plus_dp:N \l__cchess_manual_coffin } } { \dim_ratio:nn { \l__cchess_manual_height_dim } { \__cchess_coffin_ht_plus_dp:N \l__cchess_manual_coffin } } } {% 指定宽度为比例缩放 \coffin_scale:Nnn \l__cchess_manual_coffin { \dim_ratio:nn { \l__cchess_manual_width_dim } { \coffin_wd:N \l__cchess_manual_coffin } } { \dim_ratio:nn { \l__cchess_manual_width_dim } { \coffin_wd:N \l__cchess_manual_coffin } } } {% 实际宽ã€é«˜æ¯”例缩放 \coffin_scale:Nnn \l__cchess_manual_coffin { \l__cchess_x_scale_tl } { \l__cchess_y_scale_tl } } } \msg_new:nnn { cchess } { resize-type } { using~ `#1'~ resize. } % 笔画设置函数 \cs_new:Npn \__cchess_pieces_stroke:nn #1#2 { \special { pdf:code ~ q ~ #1 } #2 \special { pdf:code ~ Q } } % ç¬”ç”»æž„é€ å‡½æ•° \cs_new_protected:Npn \__cchess_pieces_stroke_construct:n #1 { \int_case:nn {\l__cchess_charstroke_type_int} { {1}{ #1 } {2}{ \__cchess_pieces_stroke:nn { 1~Tr~0.25~w~[]~0~d~1~J } {#1} } {3}{ \__cchess_pieces_stroke:nn { 2~Tr~0.25~w~[]~0~d~1~J~1~1~1~RG~1~1~1~rg } {#1} } {4}{ \__cchess_pieces_stroke:nn { 2~Tr~0.25~w } {#1} } {5}{ \__cchess_pieces_stroke:nn { 3 ~ Tr } {#1} } } } \cs_generate_variant:Nn \__cchess_pieces_stroke_construct:n { V } \cs_generate_variant:Nn \__cchess_pieces_stroke_construct:n { x } % =============æ£‹åæ–‡å—设置函数============= % 设置棋åçš„æ–‡å— % 红棋编ç ç”¨å¤§å†™å—æ¯ï¼Œé»˜è®¤ï¼š % K=帅,A=仕,E/B=相,R=车,C=ç ²,H/N=马,P=å…µ % 黑棋编ç 用å°å—å—æ¯ï¼Œé»˜è®¤ï¼š % k=å°†,a=士,e/b=象,r=車,c=ç‚®,h/n=馬,p=å’ % #1 棋åç¼–ç % #2 棋åå—符 \cs_new_nopar:Npn \__cchess_piece_char_setup:nn #1#2 { \clist_if_in:NnF \c__cchess_pieces_name_clist { #1 } { \msg_error:nnx { cchess } { piecename-exists } { #1 } } \prop_gput:Nnn \c__cchess_board_pieces_alph_name_prop { #1 } { #2 } } % key_value选项设计 \keys_define:nn { cchess } { % ç¼©æ”¾å‚æ•° gridsize .code:n = { \dim_set:Nn \gridsize { #1 } % 棋å尺寸 \dim_set:Nn \piecesize { \fp_to_dim:n { \fp_eval:n { \gridsize * 0.9 } } } } , gridsize .initial:n = 10mm , % 棋盘类型 boardtype .code:n = { \exp_args:NNx \clist_if_in:NnTF \g__cchess_board_list_clist {#1} { \tl_set:Nx \l__cchess_board_type_tl {#1} } { \msg_error:nnx { cchess } { board-exists } {#1} } }, % 棋盘线线宽 boardlinewd .code:n = { \dim_set:Nn \l__cchess_board_linewidth_dim {#1} % ä¹å®«çº¿ä¸Žè±¡ä½çº¿çº¿å®½ \dim_gset:Nn \l__cchess_cross_linewidth_dim { \fp_to_dim:n { \fp_eval:n { \l__cchess_board_linewidth_dim * 0.50 } } } % 炮兵ä½ç½®çº¿ä¸Žæ£‹ç›˜çº¿é—´è· \dim_gset:Nn \l__cchess_cross_sep_dim { \fp_to_dim:n { \fp_eval:n { \l__cchess_board_linewidth_dim * 1.80 } } } }, boardlinewd .initial:n = 0.4pt , % 棋盘线颜色 boardlinecolor .code:n = { \__cchess_color_select:nn { cchessboardlinecolor } {#1} } , boardlinecolor .initial:n = black , boardlinecolor* .code:n = { \__cchess_color_select:nnn { cchessboardlinecolor } #1 } , % 棋盘背景图片 boardbg .tl_set:N = \l__cchess_board_background_tl , boardbg .initial:n = {} , % 设置棋åå—符 piecechar .code:n = { \__cchess_piece_char_setup:nn #1 }, piecechar .initial:n = {K}{\c__cchess_K_tl} , % å—ç¬¦æ ¼å¼ piecefont .code:n = { \tl_set:Nn \l__cchess_piece_char_format_tl {#1} \__cchess_calc_piece_box_size: }, % 边框类型 piecetype .code:n = { \exp_args:NNx \clist_if_in:NnTF \g__cchess_piece_box_list_clist {#1} { \tl_set:Nx \l__cchess_piece_box_type_tl {#1} } { \msg_error:nnx { cchess } { box-exists } {#1} } }, % å—符边框线宽 boxlinewd .dim_set:N = \l__cchess_box_linewidth_dim , boxlinewd .initial:n = 0.4pt , % 边框线颜色 boxcolor .code:n = { \__cchess_color_select:nn { cchesspieceboxcolor } {#1} } , boxcolor .initial:n = black , boxcolor* .code:n = { \__cchess_color_select:nnn { cchesspieceboxcolor } #1 } , % å—符颜色 redpiece .code:n = { \__cchess_color_select:nn { cchessredpiececolor } {#1} } , redpiece .initial:n = red , redpiece* .code:n = { \__cchess_color_select:nnn { cchessredpiececolor } #1 } , blkpiece .code:n = { \__cchess_color_select:nn { cchessblkpiececolor } {#1} } , blkpiece .initial:n = black , blkpiece* .code:n = { \__cchess_color_select:nnn { cchessblkpiececolor } #1 } , % 棋å背景底层填充颜色 lower .code:n = { \exp_args:Nx \tl_if_empty:nTF {#1} { \__cchess_color_select:nn { lowerbgboxfill } { yellow!70!red } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { yellow!70!red } } }{ \__cchess_color_select:nn { lowerbgboxfill } { #1 } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { #1 } } } } , lower .initial:n = {} , % æ— å色时上层盒å背景填充颜色 donut .code:n = { \exp_args:Nx \tl_if_empty:nTF {#1} { \__cchess_color_select:nn { donutboxfill } { yellow!80!black } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { yellow!80!black } } }{ \__cchess_color_select:nn { donutboxfill } { #1 } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { #1 } } } } , donut .initial:n = {} , % 棋å背景底层填充颜色 redupper .code:n = { \exp_args:Nx \tl_if_empty:nTF {#1} { \__cchess_color_select:nn { redupperbgboxfill } { yellow!70!red } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { yellow!70!red } } }{ \__cchess_color_select:nn { redupperbgboxfill } { #1 } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { #1 } } } } , redupper .initial:n = {} , % 棋å背景底层填充颜色 blkupper .code:n = { \exp_args:Nx \tl_if_empty:nTF {#1} { \__cchess_color_select:nn { blkupperbgboxfill } { yellow!70!red } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { yellow!70!red } } }{ \__cchess_color_select:nn { blkupperbgboxfill } { #1 } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { #1 } } } } , blkupper .initial:n = {} , % ç›’å阴影填充颜色 shadow .code:n = { \exp_args:Nx \tl_if_empty:nTF {#1} { \__cchess_color_select:nn { shadowboxfill } { black!35!white } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { black!35!white } } }{ \__cchess_color_select:nn { shadowboxfill } { #1 } \cs_set_nopar:Npn \__cchess_aux_color_boxfill: { \color_fill:n { #1 } } } } , shadow .initial:n = {} , % ç¬”ç”»å‚æ•° charstroke .choice:, charstroke .value_required:n = true, charstroke .choices:nn = { none, solid, white, bold, invisible } { \int_set_eq:NN \l__cchess_charstroke_type_int \l_keys_choice_int }, charstroke .initial:n = bold, unknown .code:n = { \msg_error:nn { cchess } { unknown-option } } } \msg_new:nnn { cchess } { unknown-option } { package~ option~ "\l_keys_key_tl"~ is~ unknown. } \keys_set:nn { cchess } { piecefont = \kaishu, piecetype = ooo, boardtype = x+tn, } \ProcessKeysOptions { cchess } % key_value选项设计(打谱man) \keys_define:nn { cchess / man } { % 打谱环境交å‰å¼•ç”¨æ ‡ç¾ label .tl_gset:N = \l__cchess_setman_label_tl , label .initial:n = {} , % æ¯è¡Œæ£‹è°±æ¥æ•° nums .tl_gset:N = \l__cchess_mans_per_line_int , nums .initial:n = 2 , unknown .code:n = { \msg_error:nn { cchess } { unknown-man-option } } } \msg_new:nnn { cchess } { unknown-man-option } { package~ manual~ option~ "\l_keys_key_tl"~ is~ unknown. } % key_value选项设计(缩放resize) \keys_define:nn { cchess / resize } { % ç¼©æ”¾æ–¹å¼ type .code:n = { \exp_args:NNx \clist_if_in:NnTF \g__cchess_resize_method_clist {#1} { \tl_set:Nx \l__cchess_resize_method_tl {#1} } { \msg_error:nnx { cchess } { resize-method } {#1} } }, % ç¼©æ”¾å‚æ•° xscale .tl_set:N = \l__cchess_x_scale_tl , xscale .initial:n = 1 , yscale .tl_set:N = \l__cchess_y_scale_tl , yscale .initial:n = 1 , scale .meta:n = { xscale = #1 , yscale = #1 } , width .dim_set:N = \l__cchess_manual_width_dim , height .dim_set:N = \l__cchess_manual_height_dim , unknown .code:n = { \msg_error:nn { cchess } { unknown-resize-option } } } \msg_new:nnn { cchess } { unknown-resize-option } { package~ resize~ option~ "\l_keys_key_tl"~ is~ unknown. } \keys_set:nn { cchess / resize } { type = none, } % =============判æ–选项是å¦å˜åœ¨============= % 状æ€è®°å½•boolå˜é‡ \bool_new:N \g__cchess_is_board_option_bool \bool_new:N \g__cchess_is_piece_option_bool % åˆ¤æ–æ˜¯å¦æœ‰æ£‹ç›˜å¤–è§‚å‚æ•° \cs_new:Npn \__cchess_board_option_if_in:n #1 { \bool_set_false:N \g__cchess_is_board_option_bool \clist_map_inline:nn { board,gridsize } { \tl_if_in:nnT { #1 } { ##1 } { \bool_set_true:N \g__cchess_is_board_option_bool \clist_map_break: } } } % åˆ¤æ–æ˜¯å¦æœ‰æ£‹åå¤–è§‚å‚æ•° \cs_new:Npn \__cchess_piece_option_if_in:n #1 { \bool_set_false:N \g__cchess_is_piece_option_bool \clist_map_inline:nn { piece,lower,donut,upper,shadow,box,charstroke } { \tl_if_in:nnT { #1 } { ##1 } { \bool_set_true:N \g__cchess_is_piece_option_bool \clist_map_break: } } } % æ£‹ç›˜å‚æ•°åˆ¤æ– \prg_set_conditional:Npnn \__cchess_board_option_if_in:n #1 { p, T, F, TF } { \__cchess_board_option_if_in:n { #1 } \bool_if:NTF \g__cchess_is_board_option_bool { \prg_return_true: }{ \prg_return_false: } } % 棋å傿•°åˆ¤æ– \prg_set_conditional:Npnn \__cchess_piece_option_if_in:n #1 { p, T, F, TF } { \__cchess_piece_option_if_in:n { #1 } \bool_if:NTF \g__cchess_is_piece_option_bool { \prg_return_true: }{ \prg_return_false: } } % é€‰é¡¹è®¾ç½®ç”¨æˆ·æŽ¥å£ \NewDocumentCommand \cchessset { m } { \IfNoValueF { #1} { \keys_set:nn { cchess } { #1 } % 有draft傿•°ï¼Œéœ€è¦é‡æž„棋å和棋盘 \tl_if_in:nnT { #1 } { draft } { % 构建棋盘 \__cchess_board_construct: % 构建红黑å„9个棋å \__cchess_pieces_construct: } \bool_if:NF \g__cchess_draft_bool { % 构建棋盘 \__cchess_board_option_if_in:nT { #1 } { \__cchess_board_construct: } % 构建红黑å„9个棋å \__cchess_piece_option_if_in:nT { #1 } { \__cchess_pieces_construct: } } } } % =============创建棋åcoffins============= % 黑白棋åå—ç¬¦é¢œè‰²åŠæ£‹å颜色选择 \cs_new:Npn \__cchess_pieces_color_select:n #1 { \regex_match:NnTF \l__capital_regex { #1 } { \color_set_eq:nn { cchesspiececolor } { cchessredpiececolor } \color_set_eq:nn { upperbgboxfill } { redupperbgboxfill } }{ \color_set_eq:nn { cchesspiececolor } { cchessblkpiececolor } \color_set_eq:nn { upperbgboxfill } { blkupperbgboxfill } } } % 构建棋åç›’å容器 \cs_new:Nn \__cchess_pieces_construct: { \group_begin: \prop_map_inline:Nn \c__cchess_board_pieces_alph_name_prop { % 选择颜色 \__cchess_pieces_color_select:n { ##1 } % æ£‹åæ–‡å— \tl_gset:Nx \l__cchess_piece_tl { ##2 } % 构建棋åç›’å容器 \hcoffin_set:Nn \l__cchess_piece_coffin { \__cchess_piece_construct:N \l__cchess_piece_tl } % 缩放棋åç›’å容器 \coffin_resize:Nnn \l__cchess_piece_coffin { \piecesize }{ \piecesize } % ä¿å˜ç»“æžœ \coffin_gset_eq:cN { l__cchess_piece_ ##1 _coffin } \l__cchess_piece_coffin } \group_end: } % æž„é€ å¸¦åœˆå—符 % #1 需è¦å¤„ç†çš„å—符(串)å˜é‡ \cs_new:Npn \__cchess_piece_construct:N #1 { % æŒ‰æŒ‡å®šé¢œè‰²å’Œæ ¼å¼æž„é€ æ£‹åå—符盒å容器 \hcoffin_gset:Nn \l__cchess_box_coffin { \bool_if:NTF \g__cchess_draft_bool { \color_select:n { cchesspiececolor } #1 }{ \color_select:n { cchesspiececolor } \tl_use:N \l__cchess_piece_char_format_tl % ç¬”åˆ’å¤„ç† \__cchess_pieces_stroke_construct:n { #1 } } } % æž„é€ æž„é€ æ£‹åå—符盒å容器边框 \__cchess_single_box_construct: } % gridsize,boardtype,boardlinewd,boardlinecolor,boardbg, % piecechar,piecefont,piecetype,boxlinewd,boxcolor,redpiece,blkpiece, % lower,donut,redupper,blkupper,shadow,charstroke % å—符盒ååŠè¾¹æ¡†ç»„åˆç›’åå®¹å™¨æž„é€ å‡½æ•° \cs_new:Npn \__cchess_single_box_construct: { \bool_if:NTF \g__cchess_draft_bool { \coffin_typeset:cnnnn { l__cchess_box_coffin } { l } { b } { 0pt } { 0pt } }{ % 绘制å—符外框并拼装结果 \draw_begin: \draw_linewidth:n { \l__cchess_box_linewidth_dim } \draw_path_scope_begin: \__cchess_piece_box_type_c:n { \l__cchess_piece_box_type_tl } { 1.0 } \draw_transform_shift:n {\charboxsize / 2.0, \charboxsize / 2.0 } \draw_coffin_use:Nnn \l__cchess_box_coffin { hc } { vc } \draw_path_scope_end: \draw_end: } } % =============创建棋åå ä½coffins============= % 缩放空白棋å \cs_new:Nn \__cchess_board_piece_z_resize: { \coffin_resize:Nnn \l__cchess_piece_z_coffin { \piecesize } { \piecesize } } % 缩放空白棋å \__cchess_board_piece_z_resize: % 将棋åç›’å容器布置到棋盘指定ä½ç½®(用于棋谱和棋盘排版) % #1 棋å傿•° % 棋å傿•°çš„å½¢å¼ä¸º{{0,0}{k},{0,1}{K}},注æ„需è¦åŒ…å«å¤§æ‹¬å·ï¼Œ % ä¸åŒæ£‹å之间用英文逗å·åˆ†éš” \cs_new:Npn \__cchess_board_piece_pos_construct:n #1 { \hcoffin_gset:Nn \l__cchess_board_pieces_pos_coffin { \draw_begin: % 在四个角布置空白棋å实现å ä½(用于撑满棋å画布) \clist_set:Nn \l_tmpa_clist { {0, 0}{z}, {8, 0}{z}, {0, 9}{z}, {8, 9}{z}} \clist_map_inline:Nn \l_tmpa_clist { \__cchess_piece_set_handle:nn ##1 } % 在指定ä½ç½®å¸ƒç½®æ£‹å \clist_set:Nn \l_tmpa_clist { #1 } \clist_map_inline:Nn \l_tmpa_clist { \__cchess_piece_set_handle:nn ##1 } \draw_end: } } % =============创建棋盘背景coffin============= % 载入背景图片 \cs_new:Nn \__cchess_board_backgroud_construct: { \hcoffin_set:Nn \l__cchess_board_background_coffin { % 如果文件åä¸ä¸ºç©ºåˆ™è½½å…¥å›¾ç‰‡ï¼Œå¦åˆ™åˆ›å»ºä¸€ä¸ªç©ºç›’å容器 \tl_if_empty:NTF \l__cchess_board_background_tl { \phantom{a} }{ \includegraphics{\l__cchess_board_background_tl} } } } % 组装背景图片 \cs_new:Nn \__cchess_board_assemble: { % 计算棋盘+棋ååŽçš„æ€»å®½å’Œæ€»é«˜ \dim_gset:Nn \l_tmpa_dim { \coffin_wd:N \l__cchess_manual_coffin } \dim_gset:Nn \l_tmpb_dim { \__cchess_coffin_ht_plus_dp:N \l__cchess_manual_coffin } % 放大一个棋å的长度 \dim_add:Nn \l_tmpa_dim { \piecesize / 2 } \dim_add:Nn \l_tmpb_dim { \piecesize / 2 } \bool_if:NF \g__cchess_draft_bool { % 构建背景图片coffin \__cchess_board_backgroud_construct: % 缩放背景图片coffin \coffin_resize:Nnn \l__cchess_board_background_coffin { \l_tmpa_dim } { \l_tmpb_dim } } % 绘制总边框外线 \hcoffin_set:Nn \l__cchess_tmpa_coffin { \draw_begin: \draw_linewidth:n { \l__cchess_board_linewidth_dim * 2 } \draw_path_rectangle:nn { 0pt, 0pt } { \l_tmpa_dim * 0.99, \l_tmpb_dim * 0.99 } \draw_path_use_clear:n { draw } \draw_end: } % 绘制总边框内线 \hcoffin_set:Nn \l__cchess_tmpb_coffin { \draw_begin: \draw_linewidth:n { \l__cchess_board_linewidth_dim * 1 } \draw_path_rectangle:nn { 0pt, 0pt } { \l_tmpa_dim * 0.97, \l_tmpb_dim * 0.97 } \draw_path_use_clear:n { draw } \draw_end: } % 拼装结果 \hcoffin_set:Nn \l__cchess_manual_coffin { \draw_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l_tmpa_dim / 2, \l_tmpa_dim / 2 } \bool_if:NF \g__cchess_draft_bool { \draw_coffin_use:Nnn \l__cchess_board_background_coffin { hc } { vc } } \draw_coffin_use:Nnn \l__cchess_tmpa_coffin { hc } { vc } \draw_coffin_use:Nnn \l__cchess_tmpb_coffin { hc } { vc } \draw_coffin_use:Nnn \l__cchess_manual_coffin { hc } { vc } \draw_path_scope_end: \draw_end: } } % =============创建棋盘coffins============= \cs_new:Nn \__cchess_board_construct: { % 按指定类型创建棋盘 \hcoffin_set:Nn \l__cchess_board_coffin { \draw_begin: \draw_linewidth:n { \l__cchess_board_linewidth_dim } \draw_path_scope_begin: \bool_if:NTF \g__cchess_draft_bool { \__cchess_board_type_c:n { x } { 1.0 } { 1.0 } }{ \__cchess_board_type_c:n { \l__cchess_board_type_tl } { 1.0 } { 1.0 } } \draw_path_scope_end: \draw_end: } % 计算棋盘总宽和总高 \dim_gset:Nn \l__cchess_board_width_dim { \coffin_wd:N \l__cchess_board_coffin } \dim_gset:Nn \l__cchess_board_height_dim { \__cchess_coffin_ht_plus_dp:N \l__cchess_board_coffin } } % åœ¨æ£æ–‡ä¸æŽ’版棋å \cs_new:Npn \__cchess_getpiece_handle:nn #1#2 { % 构建红黑å„9个棋å % \__cchess_pieces_construct: % è®¾ç½®æŒ‡å®šæ ¼å¼çš„基å—符盒å \hbox_set:Nn \l_tmpa_box { #1 å°† } % ç›’å高度 \dim_set:Nn \l_tmpa_dim { \box_ht_plus_dp:N \l_tmpa_box } % 棋å高度 \dim_set:Nn \l_tmpb_dim { \__cchess_coffin_ht_plus_dp:N \l__cchess_piece_K_coffin } % 缩放棋å \coffin_scale:cnn { l__cchess_piece_ #2 _coffin } { \dim_ratio:nn { \l_tmpa_dim } { \l_tmpb_dim } }{ \dim_ratio:nn { \l_tmpa_dim } { \l_tmpb_dim } } % ç›’åæ·±åº¦ \dim_set:Nn \l_tmpb_dim { \box_dp:N \l_tmpa_box } % 输出盒å(下沉深度è·ç¦») \coffin_typeset:cnnnn { l__cchess_piece_ #2 _coffin } { l } { b } { 0pt } { -\l_tmpb_dim } } % 构建棋盘 \__cchess_board_construct: % 构建红黑å„9个棋å \__cchess_pieces_construct: % =============排版棋谱============= % 棋谱排版 \cs_new:Npn \__cchess_manual_output:n #1 { % 构建棋盘 % \__cchess_board_construct: % 构建红黑å„9个棋å % \__cchess_pieces_construct: % 构建棋å画布盒å容器 \__cchess_board_piece_pos_construct:n { #1 } % 将棋盘与棋å画布居ä¸å¯¹é½åŽè¿›è¡Œæ‹¼è£… \hcoffin_set:Nn \l__cchess_manual_coffin { \draw_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_board_width_dim / 2, \l__cchess_board_height_dim / 2 } \draw_coffin_use:Nnn \l__cchess_board_coffin { hc } { vc } \draw_coffin_use:Nnn \l__cchess_board_pieces_pos_coffin { hc } { vc } \draw_path_scope_end: \draw_end: } % 按指定方å¼è¿›è¡Œç¼©æ”¾ \__cchess_resize_c:n { \l__cchess_resize_method_tl } % æ·»åŠ èƒŒæ™¯å’Œå¤–æ¡† \__cchess_board_assemble: % 输出结果 \coffin_typeset:Nnnnn \l__cchess_manual_coffin { l }{ b } { 0pt } { 0pt } } % 排版棋盘 \cs_new:Nn \__cchess_board_output: { % 创建棋盘 % \__cchess_board_construct: % 是å¦éœ€è¦æ£‹å \bool_if:NT \l__cchess_board_pieces_bool { % 构建红黑å„9个棋å % \__cchess_pieces_construct: % 创建32个棋å画布盒å容器 \__cchess_board_piece_pos_construct:n { { {0,0}{R} }, { {1,0}{H} }, { {2,0}{E} }, { {3,0}{A} }, { {4,0}{K} }, { {5,0}{A} }, { {6,0}{E} }, { {7,0}{H} }, { {8,0}{R} }, { {1,2}{C} }, { {7,2}{C} }, { {0,3}{P} }, { {2,3}{P} }, { {4,3}{P} }, { {6,3}{P} }, { {8,3}{P} }, { {0,9}{r} }, { {1,9}{h} }, { {2,9}{e} }, { {3,9}{a} }, { {4,9}{k} }, { {5,9}{a} }, { {6,9}{e} }, { {7,9}{h} }, { {8,9}{r} }, { {1,7}{c} }, { {7,7}{c} }, { {0,6}{p} }, { {2,6}{p} }, { {4,6}{p} }, { {6,6}{p} }, { {8,6}{p} } } } % 拼装结果 \hcoffin_set:Nn \l__cchess_manual_coffin { \draw_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_board_width_dim / 2, \l__cchess_board_height_dim / 2 } \draw_coffin_use:Nnn \l__cchess_board_coffin { hc } { vc } \bool_if:NT \l__cchess_board_pieces_bool { \draw_coffin_use:Nnn \l__cchess_board_pieces_pos_coffin { hc } { vc } } \draw_path_scope_end: \draw_end: } % 按指定方å¼ç¼©æ”¾ \__cchess_resize_c:n { \l__cchess_resize_method_tl } % æ·»åŠ èƒŒæ™¯å’Œå¤–æ¡† \__cchess_board_assemble: % 输出结果 \coffin_typeset:Nnnnn \l__cchess_manual_coffin { l }{ b } { 0pt } { 0pt } } % 设置æ£åˆ™åŒ¹é…函数å˜ä½“函数 \cs_generate_variant:Nn \regex_match:NnT { NV } \cs_generate_variant:Nn \regex_match:NnF { NV } % 利用æ£åˆ™åŒ¹é…和属性表, % 将嗿¯æˆ–æ•°å—表示的棋ååæ ‡è½¬æ¢ä¸ºæ•°å—表示 \cs_new:Npn \__cchess_piece_set_handle:nn #1#2 { \clist_set:Nn \l_tmpa_clist { #1 } \clist_pop:NN \l_tmpa_clist \l_tmpa_tl \clist_pop:NN \l_tmpa_clist \l_tmpb_tl % 判æ–è¾“å…¥åˆæ³•性 \clist_if_in:NVF \c__cchess_pos_x_index_clist \l_tmpa_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpa_tl } } \clist_if_in:NVF \c__cchess_pos_y_index_clist \l_tmpb_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpb_tl } } \clist_if_in:NnF \c__cchess_pieces_name_clist { #2 } { \msg_error:nnx { cchess } { piecename-exists } { #2 } } % 转æ¢åæ ‡ä¸ºæ•°å— \regex_match:NVT \l__alph_regex \l_tmpa_tl { \prop_get:NVN \c__cchess_board_pos_alph_num_prop \l_tmpa_tl \l_tmpa_tl } \regex_match:NVT \l__alph_regex \l_tmpb_tl { \prop_get:NVN \c__cchess_board_pos_alph_num_prop \l_tmpb_tl \l_tmpb_tl } % 用数å—åæ ‡å®šä½å¸ƒç½®æ£‹å \__cchess_piece_set:VVn \l_tmpa_tl \l_tmpb_tl { #2 } } % 在指定ä½ç½®å¸ƒç½®æ£‹å % #1 xæ–¹å‘æ•°å—åž‹åæ ‡å€¼(0-8) % #2 yæ–¹å‘æ•°å—åž‹åæ ‡å€¼(0-9) % #3 棋ååç§°(å•è‹±æ–‡å—æ¯) \cs_new:Npn \__cchess_piece_set:nnn #1#2#3 { \draw_path_scope_begin: \draw_transform_shift:n { \gridsize * #1, \gridsize * #2 } \draw_coffin_use:cnn { l__cchess_piece_ #3 _coffin } { hc } { vc } \draw_path_scope_end: } \cs_generate_variant:Nn \__cchess_piece_set:nnn {VV} % ====================================================== % ===é‡‡ç”¨æ£‹åæ›¿æ¢æ–¹å¼åˆ›å»ºæ£‹å画布coffin(用于打谱排版)=== % ====================================================== % ç¼©æ”¾å æ£‹åç›’å容器 \cs_new:Nn \__cchess_board_pieces_resize: { % 空白棋å \coffin_resize:Nnn \l__cchess_board_piece_z_coffin { \piecesize } { \piecesize } % 其它棋å,按行(a-i)列(a-j)ç¼–å·å‘½å。 \clist_map_inline:Nn \c__cchess_board_pos_x_clist { \clist_map_inline:Nn \c__cchess_board_pos_y_clist { \coffin_resize:cnn { l__cchess_board_piece_ ##1 _ ####1 _coffin } { \piecesize } { \piecesize } } } } % åˆ›å»ºå—æ¯è¡Œåˆ—ç¼–å·å‘½å棋åçš„å 使£‹å画布 \cs_new:Nn \__cchess_board_pieces_seat: { % 缩放å 使£‹å \__cchess_board_pieces_resize: % 利用åŒé‡å¾ªçŽ¯åˆ›å»ºæ£‹å画布 \hcoffin_gset:Nn \l__cchess_board_pieces_pos_coffin { \draw_begin: \int_zero:N \l_tmpa_int % 扫æa-i横å‘ä½ç½®ç¼–å·åˆ—表 \clist_map_inline:Nn \c__cchess_board_pos_x_clist { \int_zero:N \l_tmpb_int % 扫æa-j纵å‘ä½ç½®ç¼–å·åˆ—表 \clist_map_inline:Nn \c__cchess_board_pos_y_clist { \draw_path_scope_begin: % åæ ‡å¹³ç§» \draw_transform_shift:n { \gridsize * \l_tmpa_int, \gridsize * \l_tmpb_int } % 布置棋å \draw_coffin_use:cnn { l__cchess_board_piece_ ##1 _ ####1 _coffin } { hc } { vc } \draw_path_scope_end: \int_incr:N \l_tmpb_int } \int_incr:N \l_tmpa_int } \draw_end: } } % 棋åç”»å¸ƒæ£‹åæ›¿æ¢å¥æŸ„函数 % 利用æ£åˆ™åŒ¹é…和属性表, % 将嗿¯æˆ–æ•°å—表示的棋ååæ ‡è½¬æ¢ä¸ºå—æ¯è¡¨ç¤º \cs_new:Npn \__cchess_piece_replace_handle:nn #1#2 { \clist_set:Nn \l_tmpa_clist { #1 } \clist_pop:NN \l_tmpa_clist \l_tmpa_tl \clist_pop:NN \l_tmpa_clist \l_tmpb_tl % 判æ–è¾“å…¥åˆæ³•性 \clist_if_in:NVF \c__cchess_pos_x_index_clist \l_tmpa_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpa_tl } } \clist_if_in:NVF \c__cchess_pos_y_index_clist \l_tmpb_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpb_tl } } \clist_if_in:NnF \c__cchess_pieces_name_clist { #2 } { \msg_error:nnx { cchess } { piecename-exists } { #2 } } % 转æ¢åæ ‡ä¸ºå—æ¯ \regex_match:NVT \l__digit_regex \l_tmpa_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpa_tl \l_tmpa_tl } \regex_match:NVT \l__digit_regex \l_tmpb_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpb_tl \l_tmpb_tl } % ç”¨å—æ¯åæ ‡å®šä½å¸ƒç½®æ£‹å \__cchess_piece_replace:VVn \l_tmpa_tl \l_tmpb_tl { #2 } } % 棋åå 使›¿æ¢å‡½æ•° % #1 横å‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #2 纵å‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #3 棋ååç§°(å•è‹±æ–‡å—æ¯) \cs_new:Npn \__cchess_piece_replace:nnn #1#2#3 { \coffin_gset_eq:cc { l__cchess_board_piece_ #1 _ #2 _coffin } { l__cchess_piece_ #3 _coffin } } \cs_generate_variant:Nn \__cchess_piece_replace:nnn {VV} % 棋ååˆ é™¤å¥æŸ„函数 % 利用æ£åˆ™åŒ¹é…和属性表, % 将嗿¯æˆ–æ•°å—表示的棋ååæ ‡è½¬æ¢ä¸ºå—æ¯è¡¨ç¤º \cs_new:Npn \__cchess_piece_remove_handle:n #1 { \clist_set:Nn \l_tmpa_clist { #1 } \clist_pop:NN \l_tmpa_clist \l_tmpa_tl \clist_pop:NN \l_tmpa_clist \l_tmpb_tl % 判æ–è¾“å…¥åˆæ³•性 \clist_if_in:NVF \c__cchess_pos_x_index_clist \l_tmpa_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpa_tl } } \clist_if_in:NVF \c__cchess_pos_y_index_clist \l_tmpb_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpb_tl } } % 转æ¢åæ ‡ä¸ºå—æ¯ \regex_match:NVT \l__digit_regex \l_tmpa_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpa_tl \l_tmpa_tl } \regex_match:NVT \l__digit_regex \l_tmpb_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpb_tl \l_tmpb_tl } % ç”¨å—æ¯åæ ‡å®šä½å¸ƒç½®æ£‹å \__cchess_piece_remove:VV \l_tmpa_tl \l_tmpb_tl } % 棋ååˆ é™¤å‡½æ•° % #1 横å‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #2 纵方å‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #3 棋ååç§°(å•è‹±æ–‡å—æ¯) \cs_new:Npn \__cchess_piece_remove:nn #1#2 { \coffin_gset_eq:cN { l__cchess_board_piece_ #1 _ #2 _coffin } \l__cchess_board_piece_z_coffin } \cs_generate_variant:Nn \__cchess_piece_remove:nn {VV} % 棋åç§»åŠ¨å¥æŸ„函数 % 利用æ£åˆ™åŒ¹é…和属性表, % 将嗿¯æˆ–æ•°å—表示的棋ååæ ‡è½¬æ¢ä¸ºå—æ¯è¡¨ç¤º \cs_new:Npn \__cchess_piece_move_handle:nnn #1#2#3 { \clist_set:Nn \l_tmpa_clist { #2 } \clist_pop:NN \l_tmpa_clist \l_tmpa_tl \clist_pop:NN \l_tmpa_clist \l_tmpb_tl \clist_set:Nn \l_tmpa_clist { #3 } \clist_pop:NN \l_tmpa_clist \l_tmpc_tl \clist_pop:NN \l_tmpa_clist \l_tmpd_tl % 判æ–è¾“å…¥åˆæ³•性 \clist_if_in:NVF \c__cchess_pos_x_index_clist \l_tmpa_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpa_tl } } \clist_if_in:NVF \c__cchess_pos_y_index_clist \l_tmpb_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpb_tl } } \clist_if_in:NVF \c__cchess_pos_x_index_clist \l_tmpc_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpc_tl } } \clist_if_in:NVF \c__cchess_pos_y_index_clist \l_tmpd_tl { \msg_error:nnx { cchess } { piecename-exists } { \l_tmpd_tl } } \clist_if_in:NnF \c__cchess_pieces_name_clist { #1 } { \msg_error:nnx { cchess } { piecename-exists } { #1 } } % 转æ¢åæ ‡ä¸ºå—æ¯ \regex_match:NVT \l__digit_regex \l_tmpa_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpa_tl \l_tmpa_tl } \regex_match:NVT \l__digit_regex \l_tmpb_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpb_tl \l_tmpb_tl } \regex_match:NVT \l__digit_regex \l_tmpc_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpc_tl \l_tmpc_tl } \regex_match:NVT \l__digit_regex \l_tmpd_tl { \prop_get:NVN \c__cchess_board_pos_num_alph_prop \l_tmpd_tl \l_tmpd_tl } % ç”¨å—æ¯åæ ‡å®šä½å¸ƒç½®æ£‹å \__cchess_piece_move:VVVVn \l_tmpa_tl \l_tmpb_tl \l_tmpc_tl \l_tmpd_tl { #1 } } % 棋å移动函数 % #1 原ä½ç½®æ¨ªå‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #2 原ä½ç½®çºµå‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #3 æ–°ä½ç½®æ¨ªå‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #4 æ–°ä½ç½®çºµå‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #5 棋ååç§°(å•è‹±æ–‡å—æ¯) \cs_new:Npn \__cchess_piece_move:nnnnn #1#2#3#4#5 { % åˆ é™¤åŽŸä½ç½®æ£‹å \__cchess_piece_remove:nn { #1 } { #2 } % 在新ä½ç½®å¸ƒç½®æ£‹å \__cchess_piece_replace:nnn { #3 } { #4 } { #5 } % ç”Ÿæˆæ‰“谱棋谱记录 \bool_if:NT \l__cchess_with_setman_bool { \__cchess_piece_manual_str_construct:nnnnn { #1 }{ #2 }{ #3 }{ #4 }{ #5 } } } \cs_generate_variant:Nn \__cchess_piece_move:nnnnn {VVVV} % ç”Ÿæˆæ‰“谱棋谱记录 % TODO:暂未实现纵å‘åŒç±»æ£‹åå‰åŽåˆ¤æ– % #1 原ä½ç½®æ¨ªå‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #2 原ä½ç½®çºµå‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #3 æ–°ä½ç½®æ¨ªå‘å—ç¬¦åž‹åæ ‡å€¼(a-i) % #4 æ–°ä½ç½®çºµå‘å—ç¬¦åž‹åæ ‡å€¼(a-j) % #5 棋ååç§°(å•è‹±æ–‡å—æ¯) \cs_new:Npn \__cchess_piece_manual_str_construct:nnnnn #1#2#3#4#5 { % å°†å—ç¬¦åæ ‡æ•°æ®è½¬æ¢ä¸ºæ•´æ•°åæ ‡ \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #1 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #2 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #3 } \l_tmpc_tl \prop_get:NnN \c__cchess_board_pos_alph_num_prop { #4 } \l_tmpd_tl \int_set:Nn \l_tmpa_int { \l_tmpa_tl } \int_set:Nn \l_tmpb_int { \l_tmpb_tl } \int_set:Nn \l_tmpc_int { \l_tmpc_tl } \int_set:Nn \l_tmpd_int { \l_tmpd_tl } % è¡Œæ£‹åˆ†æž \int_compare:nNnTF { \l_tmpc_int } = { \l_tmpa_int } { % 纵å‘移动 \int_compare:nNnTF { \l_tmpd_int } > { \l_tmpb_int } { % åæ ‡å‘上 \int_set:Nn \l_tmpe_int { \l_tmpd_int - \l_tmpb_int } \tl_set:Nx \l_tmpe_tl { \int_use:N \l_tmpe_int } \regex_match:NnTF \l__capital_regex { #5 } { % 红棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NVN \c__cchess_board_pos_arabic_zh_prop \l_tmpe_tl \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl è¿› \l_tmpc_tl } }{ % 黑棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #1 } \l_tmpb_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl 退 \int_use:N \l_tmpe_int } } }{ % åæ ‡å‘下 \int_set:Nn \l_tmpe_int { \l_tmpb_int - \l_tmpd_int } \tl_set:Nx \l_tmpe_tl { \int_use:N \l_tmpe_int } \regex_match:NnTF \l__capital_regex { #5 } { % 红棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NVN \c__cchess_board_pos_arabic_zh_prop \l_tmpe_tl \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl 退 \l_tmpc_tl } }{ % 黑棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #1 } \l_tmpb_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl è¿› \int_use:N \l_tmpe_int } } } }{ % éžçºµå‘移动 \int_compare:nNnTF { \l_tmpd_int } = { \l_tmpb_int } { % 水平移动 \regex_match:NnTF \l__capital_regex { #5 } { % 黑棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl å¹³ \l_tmpc_tl } }{ % 红棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl å¹³ \l_tmpc_tl } } }{ % éžçºµéžæ¨ªå‘移动 \int_compare:nNnTF { \l_tmpd_int } > { \l_tmpb_int } { % 纵å‘å‘上 \regex_match:NnTF \l__capital_regex { #5 } { % 红棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl è¿› \l_tmpc_tl } }{ % 黑棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl 退 \l_tmpc_tl } } }{ % 纵å‘å‘下 \regex_match:NnTF \l__capital_regex { #5 } { % 红棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_red_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl 退 \l_tmpc_tl } }{ % 黑棋 \prop_get:NnN \c__cchess_board_pieces_alph_name_prop { #5 } \l_tmpa_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #1 } \l_tmpb_tl \prop_get:NnN \c__cchess_board_black_x_idx_prop { #3 } \l_tmpc_tl \clist_put_right:Nx \l__cchess_manual_clist { \l_tmpa_tl \l_tmpb_tl è¿› \l_tmpc_tl } } } } } } \cs_generate_variant:Nn \__cchess_piece_manual_str_construct:nnnnn {VVVV} % 打谱环境å‰å¤„ç†å‡½æ•° % #1 打谱命令 \cs_new:Npn \__cchess_setcchessman_pre_setup:n #1 { % 构建棋盘 % \__cchess_board_construct: % 构建红黑å„9个棋å % \__cchess_pieces_construct: % åˆ é™¤çŽ¯å¢ƒä¸çš„代ç ä¸çš„空白 \tl_set:Nn \l_tmpa_tl { #1 } \tl_remove_all:Nn \l_tmpa_tl {~} % 执行环境ä¸çš„代ç \tl_use:N \l_tmpa_tl } % 定义\label命令的å˜ä½“函数 %\label { #1 } \cs_set_eq:NN \__cchess_setman_label:n \label \cs_generate_variant:Nn \__cchess_setman_label:n { x } % 打谱环境åŽå¤„ç†å‡½æ•° \cs_new:Nn \__cchess_setcchessman_post_setup: { % 布置棋å \__cchess_board_pieces_seat: % 将棋盘与打谱结果盒å容器居ä¸å¯¹é½åŽè¿›è¡Œæ‹¼è£… \hcoffin_set:Nn \l__cchess_manual_coffin { \draw_begin: \draw_path_scope_begin: \draw_transform_shift:n { \l__cchess_board_width_dim / 2, \l__cchess_board_height_dim / 2 } \draw_coffin_use:Nnn \l__cchess_board_coffin { hc } { vc } \draw_coffin_use:Nnn \l__cchess_board_pieces_pos_coffin { hc } { vc } \draw_path_scope_end: \draw_end: } % 缩放拼装结果 \__cchess_resize_c:n { \l__cchess_resize_method_tl } % æ·»åŠ èƒŒæ™¯å’Œå¤–æ¡† \__cchess_board_assemble: % 星å·çŽ¯å¢ƒéœ€è¦è¾“出打谱记录 \bool_if:NT \l__cchess_with_setman_bool { % 递增计数器 \refstepcounter{setman} % 设置labelæ ‡ç¾ \__cchess_setman_label:x { \l__cchess_setman_label_tl } % æž„é€ ä¸´æ—¶æ–‡ä»¶ \iow_open:Nn \g_tmpa_iow { \c_sys_jobname_str\l__cchess_setman_label_tl\thesetman .man } % é历打谱记录列表,输出打谱记录到临时文件 \bool_until_do:nn { \clist_if_empty_p:N \l__cchess_manual_clist } { \clist_pop:NN \l__cchess_manual_clist \l_tmpa_tl \tl_set:Nx \l_tmpb_tl {\l_tmpa_tl} \iow_now:Nx \g_tmpa_iow { \l_tmpb_tl } } % 关闿–‡ä»¶ \iow_close:N \g_tmpa_iow } % 输出结果盒å容器 \coffin_typeset:Nnnnn \l__cchess_manual_coffin { l }{ b } { 0pt } { 0pt } } % å‚考雾月的回å¤ï¼šhttps://ask.latexstudio.net/ask/question/7430.html % LaTeX3 并未定义 \use_i:nnnnn \cs_set:Npn \use_i:nnnnn #1#2#3#4#5 {#1} % 打谱棋谱排版æè¿°å¤„ç† \cs_new:Npn \__cchess_setman_print:n #1 { % æ ¹æ®æ£‹è°±label构建文件å \cs_if_exist:cTF { r@#1 } { % è¿™ä¸€æ¥æ˜¯å¾—到 ref,它ä¿å˜åœ¨ \r@#1 ä¸ã€‚ % \r@#1 有两项,当使用 hyperref 时, % \r@#1 有 5 项,这里使用 \empty 统一解决 \tl_set:Nx \l_tmpa_tl { \c_sys_jobname_str #1 \exp_args:NNc \exp_after:wN \use_i:nnnnn { r@ #1 } \c_empty_tl \c_empty_tl \c_empty_tl .man } % æ‰“å¼€æ–‡ä»¶è¯»å–æ•°æ®å¹¶è¾“出结果 \ior_open:NnTF \g_tmpb_ior { \l_tmpa_tl } { % 循环计数 \int_set:Nn \l_tmpa_int { 1 } % 循环读å–一行棋谱 \ior_str_map_variable:NNn \g_tmpb_ior \l_tmpb_str { % 转æ¢ä¸ºtoken \tl_set_rescan:Nno \l_tmpb_tl { \char_set_catcode_letter:N \_ \char_set_catcode_letter:N : }{ \l_tmpb_str } % 输出结果 \tl_use:N \l_tmpb_tl % æ ¹æ®æ¯è¡Œæ¥æ•°ç¡®å®šè¾“出\quad或是\par \int_set:Nn \l_tmpb_int { \int_mod:nn { \l_tmpa_int } { \l__cchess_mans_per_line_int } } \int_compare:nNnTF { \l_tmpb_int } = { 0 } { \par } { \quad } \int_incr:N \l_tmpa_int } } { \msg_error:nnx { cchess } { file-not-found } { \l_tmpa_tl } } % 关闿–‡ä»¶ \iow_close:N \g_tmpa_ior }{ \G@refundefinedtrue }% 引用未定义 } \endinput