%%
%% This is file `weiqi.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% weiqi.dtx  (with options: `package')
%% 
%%
%% 文件：weiqi.dtx
%%
%% 版权 (C) 2023-2024 By Ms_yam
%%
%% 它可以在 LaTeX 项目公共许可（LPPL）1.3c 及之后的任意版本（随你的意见）下分发或修改。
%% 这个许可的最新版本在如下文件中：
%%
%%   https://www.latex-project.org/lppl.txt
%%
%% 本宏包为作者练习 epxl3 和编写 dtx 文件所编写，里面的接口及方法并不是最优的。
%% 仅供参考。
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesExplPackage{weiqi}{2024-02-22}{0.1}
  {drawing weiqi using expl3}
\RequirePackage{l3draw}[2024-01-04]
\ExplSyntaxOn
\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 }
\int_const:Nn \c__weiqi_normal_size_int { 19 }
\int_const:Nn \c__weiqi_mid_size_int { 13 }
\int_const:Nn \c__weiqi_small_size_int { 9 }
\clist_const:Nn \c__weiqi_normal_star_clist
  { d4, j4, p4, d10, j10, p10, d16, j16, p16 }
\clist_const:Nn \c__weiqi_mid_star_clist
  { c3, g3, k3, c7, g7, k7, c11, g11, k11 }
\clist_const:Nn \c__weiqi_small_star_clist { c3, k3, c7, k7 }
\int_const:Nn \c__weiqi_max_step_int { 500 }
\str_const:Nn \c__weiqi_normal_mode_str { normal }
\str_const:Nn \c__weiqi_sgf_mode_str { sgf }
\int_new:N \g__weiqi_x_direction_int
\int_new:N \g__weiqi_y_direction_int
\bool_new:N \g__weiqi_swap_xy_bool
\fp_new:N \g__weiqi_scale_fp
\int_new:N \g__weiqi_min_width_int
\int_new:N \g__weiqi_min_hight_int
\bool_new:N \g__weiqi_show_loc_bool
\str_new:N \g__weiqi_loc_mode_str
\int_gset:Nn \g__weiqi_x_direction_int { 1 }
\int_gset:Nn \g__weiqi_y_direction_int { 1 }
\bool_gset_false:N \g__weiqi_swap_xy_bool
\fp_gset:Nn \g__weiqi_scale_fp { 1 }
\int_gset:Nn \g__weiqi_min_width_int { 3 }
\int_gset:Nn \g__weiqi_min_hight_int { 2 }
\bool_gset_true:N \g__weiqi_show_loc_bool
\str_gset_eq:NN \g__weiqi_loc_mode_str \c__weiqi_normal_mode_str
\int_new:N \l__weiqi_x_direction_int
\int_new:N \l__weiqi_y_direction_int
\bool_new:N \l__weiqi_swap_xy_bool
\fp_new:N \l__weiqi_scale_fp
\int_new:N \l__weiqi_min_width_int
\int_new:N \l__weiqi_min_hight_int
\bool_new:N \l__weiqi_show_loc_bool
\str_new:N \l__weiqi_loc_mode_str
\int_new:N \g__weiqi_default_size_int
\int_gset_eq:NN \g__weiqi_default_size_int \c__weiqi_normal_size_int
\int_new:N \g__weiqi_size_int
\int_new:N \g__weiqi_step_count_int
\intarray_new:Nn \g__weiqi_x_intarray { \c__weiqi_max_step_int }
\intarray_new:Nn \g__weiqi_y_intarray { \c__weiqi_max_step_int }
\intarray_new:Nn \g__weiqi_player_intarray { \c__weiqi_max_step_int }
\seq_new:N \g__weiqi_label_seq
\seq_new:N \g__weiqi_die_seq
\clist_new:N \g__weiqi_red_point_clist
\clist_new:N \g__weiqi_green_point_clist
\clist_new:N \g__weiqi_blue_point_clist
\int_new:N \l__weiqi_x_min_int
\int_new:N \l__weiqi_x_max_int
\int_new:N \l__weiqi_y_min_int
\int_new:N \l__weiqi_y_max_int
\bool_new:N \l__weiqi_left_bool
\bool_new:N \l__weiqi_right_bool
\bool_new:N \l__weiqi_up_bool
\bool_new:N \l__weiqi_down_bool
\fp_new:N \l__weiqi_x_min_fp
\fp_new:N \l__weiqi_x_max_fp
\fp_new:N \l__weiqi_y_min_fp
\fp_new:N \l__weiqi_y_max_fp
\str_new:N \l__weiqi_label_str
\int_new:N \l__weiqi_x_int
\int_new:N \l__weiqi_y_int
\int_new:N \l__weiqi_player_int
\fp_new:N \l__weiqi_x_fp
\fp_new:N \l__weiqi_y_fp
\clist_new:N \l__weiqi_point_clist
\int_new:N \l__weiqi_tmp_int
\str_new:N \l__weiqi_tmp_str
\bool_new:N \l__weiqi_tmp_bool
\seq_new:N \l__weiqi_tmp_seq
\cs_new:Npn \__weiqi_new_game:n #1
  {
    \int_set_eq:NN \l__weiqi_x_direction_int \g__weiqi_x_direction_int
    \int_set_eq:NN \l__weiqi_y_direction_int \g__weiqi_y_direction_int
    \bool_set_eq:NN \l__weiqi_swap_xy_bool \g__weiqi_swap_xy_bool
    \fp_set_eq:NN \l__weiqi_scale_fp \g__weiqi_scale_fp
    \int_set_eq:NN \l__weiqi_min_width_int \g__weiqi_min_width_int
    \int_set_eq:NN \l__weiqi_min_hight_int \g__weiqi_min_hight_int
    \bool_set_eq:NN \l__weiqi_show_loc_bool \g__weiqi_show_loc_bool
    \str_set_eq:NN \l__weiqi_loc_mode_str \g__weiqi_loc_mode_str
    \int_gset:Ne \g__weiqi_size_int { #1 }
    \int_gset:Nn \g__weiqi_step_count_int { 0 }
    \intarray_gzero:N \g__weiqi_x_intarray
    \intarray_gzero:N \g__weiqi_y_intarray
    \intarray_gzero:N \g__weiqi_player_intarray
    \seq_gclear:N \g__weiqi_label_seq
    \seq_gclear:N \g__weiqi_die_seq
    \clist_gclear:N \g__weiqi_red_point_clist
    \clist_gclear:N \g__weiqi_green_point_clist
    \clist_gclear:N \g__weiqi_blue_point_clist
  }
\cs_new:Npn \__weiqi_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__weiqi_x_int { 0 }
        \int_set:Nn \l__weiqi_y_int { 0 }
      }
      {
        \int_set:Ne \l__weiqi_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__weiqi_y_int { \g__weiqi_size_int - \l_tmpa_int + 1 }
          }
          {
            \int_set:Ne \l__weiqi_y_int
              { \str_range:Nnn \l_tmpa_str { 2 } { 5 } }
          }
      }
  }
\cs_generate_variant:Nn \__weiqi_loc_to_xy:n { V }
\cs_new:Npn \__weiqi_xy_to_loc:N #1
  {
    \int_compare:nNnTF { \l__weiqi_x_int } = { 0 }
      { \str_set:Nn #1 { - } }
      {
        \str_set:Nx \l_tmpa_str
          { \int_to_alph:n { \l__weiqi_x_int } }
        \str_compare:eNeTF
          { \l__weiqi_loc_mode_str } = { \c__weiqi_sgf_mode_str }
          {
            \int_set:Nn \l_tmpa_int
              { \g__weiqi_size_int - \l__weiqi_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__weiqi_y_int } }
        \str_set_eq:NN #1 \l_tmpa_str
      }
  }
\cs_new:Npn \__weiqi_add_stone:nnn #1#2#3
  {
    \int_gincr:N \g__weiqi_step_count_int
    \intarray_gset:Nnn \g__weiqi_player_intarray
      \g__weiqi_step_count_int { #1 }
    \__weiqi_loc_to_xy:n { #2 }
    \intarray_gset:Nnn \g__weiqi_x_intarray
      \g__weiqi_step_count_int \l__weiqi_x_int
    \intarray_gset:Nnn \g__weiqi_y_intarray
      \g__weiqi_step_count_int \l__weiqi_y_int
    \str_if_eq:nnTF { #3 } { 0 }
      { \seq_put_right:Nn \g__weiqi_label_seq {} }
      { \seq_put_right:Nn \g__weiqi_label_seq { #3 } }
  }
\cs_generate_variant:Nn \__weiqi_add_stone:nnn {nnV, nVV}
\cs_new:Npn \__weiqi_add_stones:nnn #1#2#3
  {
    \int_set:Nn \l__weiqi_player_int { #1 }
    \clist_set:Nn \l__weiqi_position_clsit { #2 }
    \bool_set_false:N \l__weiqi_tmp_bool
    \str_if_empty:nTF { #3 }
      { \str_set:Nn \l__weiqi_tmp_str {} }
      {
        \regex_match:nnTF { [^0-9]+ } { #3 }
          { \str_set:Nx \l__weiqi_tmp_str { #3 } }
          {
            \bool_set_true:N \l__weiqi_tmp_bool
            \int_set:Nn \l__weiqi_tmp_int { #3 }
          }
      }
    \clist_map_inline:Nn \l__weiqi_position_clsit
      {
        \bool_if:nTF \l__weiqi_tmp_bool
          {
            \__weiqi_add_stone:nnV
              { \l__weiqi_player_int }
              { ##1 }
              { \l__weiqi_tmp_int }
            \int_case:nn { \l__weiqi_player_int }
              {
                { 1 } { \int_set:Nn \l__weiqi_player_int { 2 } }
                { 2 } { \int_set:Nn \l__weiqi_player_int { 1 } }
                { 3 } { \int_set:Nn \l__weiqi_player_int { 3 } }
              }
            \int_compare:nNnT { \l__weiqi_tmp_int } > { 0 }
              { \int_incr:N \l__weiqi_tmp_int }
          }
          { \__weiqi_add_stone:nnV { #1 } { ##1 } { \l__weiqi_tmp_str } }
      }
  }
\cs_new:Npn \__weiqi_add_sgf_stones:nn #1#2
  {
    \regex_extract_all:nnN { ;[BW]\[[a-z]{2}\] } { #1 } \l__weiqi_tmp_seq
    \clist_set_from_seq:NN \l__weiqi_point_clist \l__weiqi_tmp_seq
    \bool_set_false:N \l__weiqi_tmp_bool
    \str_if_empty:nTF { #2 }
      { \str_set:Nn \l__weiqi_tmp_str {} }
      {
        \regex_match:nnTF { [^0-9]+ } { #2 }
          { \str_set:Nx \l__weiqi_tmp_str { #2 } }
          {
            \bool_set_true:N \l__weiqi_tmp_bool
            \int_set:Nn \l__weiqi_tmp_int { #2 }
          }
      }
    \clist_map_inline:Nn \l__weiqi_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__weiqi_player_int { 1 } }
          { W } { \int_set:Nn \l__weiqi_player_int { 2 } }
        }
        \bool_if:nTF \l__weiqi_tmp_bool
          {
            \__weiqi_add_stone:nVV { \l__weiqi_player_int }
              { \l_tmpb_str } { \l__weiqi_tmp_int }
            \int_compare:nNnT { \l__weiqi_tmp_int } > { 0 }
              { \int_incr:N \l__weiqi_tmp_int }
          }
          {
            \__weiqi_add_stone:nVV { \l__weiqi_player_int }
              { \l_tmpb_str } { \l__weiqi_tmp_str }
          }
      }
  }
\cs_generate_variant:Nn  \__weiqi_add_sgf_stones:nn { VV }
\cs_new:Npn \__weiqi_reset_stone_number:n #1
  {
    \int_set:Ne \l__weiqi_tmp_int { 1 - #1 }
    \int_step_inline:nn { \c__weiqi_max_step_int }
      {
        \bool_lazy_or:nnF
          {
            \int_compare_p:nNn
              { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } } = { 0 }
          }
          {
            \int_compare_p:nNn
              { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } } = { 3 }
          }
          {
            \int_incr:N \l__weiqi_tmp_int
            \int_compare:nNnTF { \l__weiqi_tmp_int } > { 0 }
              { \seq_gset_item:NnV \g__weiqi_label_seq { ##1 } { \l__weiqi_tmp_int } }
              { \seq_gset_item:Nnn \g__weiqi_label_seq { ##1 } {} }
          }
      }
  }
\cs_new:Npn \__weiqi_change_stone:n #1
  {
    \int_case:nn
      { \intarray_item:Nn \g__weiqi_player_intarray { #1 } }
      {
        { 1 } { \intarray_gset:Nnn \g__weiqi_player_intarray { #1 } { 2 } }
        { 2 } { \intarray_gset:Nnn \g__weiqi_player_intarray { #1 } { 1 } }
      }
  }
\cs_new:Npn \__weiqi_remove_stone:n #1
  {
    \intarray_gset:Nnn \g__weiqi_x_intarray  { #1 } { 0 }
    \intarray_gset:Nnn \g__weiqi_y_intarray  { #1 } { 0 }
    \intarray_gset:Nnn \g__weiqi_player_intarray  { #1 } { 0 }
    \seq_gset_item:Nnn \g__weiqi_label_seq { #1} { }
  }
\cs_new:Npn \__weiqi_die_stone:n #1
  {
    \seq_if_in:NnF \g__weiqi_die_seq { #1 }
      {
        \seq_put_right:Nn \g__weiqi_die_seq { #1 }
        \prg_break:
      }
  }
\cs_new:Npn \__weiqi_modify_stone:N #1
  {
    \int_step_inline:nn { \c__weiqi_max_step_int }
      {
        \bool_lazy_and:nnT
        {
          \int_compare_p:n
            { \intarray_item:Nn \g__weiqi_x_intarray { ##1 } = \l__weiqi_x_int }
        }
        {
          \int_compare_p:n
            { \intarray_item:Nn \g__weiqi_y_intarray { ##1 } = \l__weiqi_y_int }
        }
        { #1 { ##1 } }
      }
      \prg_break_point:
  }
\cs_new:Npn \__weiqi_modify_stones:nN #1#2
  {
    \clist_set:Nn \l__weiqi_position_clsit { #1 }
    \clist_map_inline:Nn \l__weiqi_position_clsit
      {
        \__weiqi_loc_to_xy:n { ##1 }
        \int_compare:nNnF { \l__weiqi_x_int } = { 0 }
          { \__weiqi_modify_stone:N { #2 } }
      }
  }
\cs_new:Nn \__weiqi_clear_labels:
  {
    \int_step_inline:nn { \c__weiqi_max_step_int }
      {
        \int_compare:nNnT
          { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } } = { 3 }
          {
            \intarray_gset:Nnn \g__weiqi_x_intarray  { ##1 } { 0 }
            \intarray_gset:Nnn \g__weiqi_y_intarray  { ##1 } { 0 }
            \intarray_gset:Nnn \g__weiqi_player_intarray  { ##1 } { 0 }
            \seq_gset_item:Nnn \g__weiqi_label_seq { ##1 } {}
          }
      }
  }
\cs_new:Npn \__weiqi_add_points:nn #1#2
  {
    \str_case:nn { #1 }
      {
        { red }
        { \clist_gput_right:Nn \g__weiqi_red_point_clist { #2 } }
        { green }
        { \clist_gput_right:Nn \g__weiqi_green_point_clist { #2 } }
        { blue }
        { \clist_gput_right:Nn \g__weiqi_blue_point_clist { #2 } }
      }
  }
\cs_new:Nn \__weiqi_clear_points:
  {
    \clist_clear:N \g__weiqi_red_point_clist
    \clist_clear:N \g__weiqi_green_point_clist
    \clist_clear:N \g__weiqi_blue_point_clist
  }
\cs_new:Npn \__weiqi_transform_xy:NN #1#2
  {
    \int_set:Ne \l_tmpa_int { #1 * \l__weiqi_x_direction_int }
    \int_set:Ne \l_tmpb_int { #2 * \l__weiqi_y_direction_int }
    \bool_if:NTF \l__weiqi_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
      }
  }
\cs_new:Nn \__weiqi_calc_range:
  {
    \int_set:Nn \l__weiqi_x_min_int { 99 }
    \int_set:Nn \l__weiqi_y_min_int { 99 }
    \int_set:Nn \l__weiqi_x_max_int { 0 }
    \int_set:Nn \l__weiqi_y_max_int { 0 }
    \int_step_inline:nn  {\g__weiqi_step_count_int}
      {
        \int_set:Ne \l__weiqi_x_int
          { \intarray_item:Nn \g__weiqi_x_intarray { ##1 } }
        \int_set:Ne \l__weiqi_y_int
          { \intarray_item:Nn \g__weiqi_y_intarray { ##1 } }
        \int_compare:nNnF
          { \l__weiqi_x_int } = { 0 }
          {
            \int_compare:nNnT
              \l__weiqi_x_min_int > \l__weiqi_x_int
              { \int_set_eq:NN \l__weiqi_x_min_int \l__weiqi_x_int }
            \int_compare:nNnT
              \l__weiqi_x_max_int < \l__weiqi_x_int
              { \int_set_eq:NN \l__weiqi_x_max_int \l__weiqi_x_int }
            \int_compare:nNnT
              \l__weiqi_y_min_int > \l__weiqi_y_int
              { \int_set_eq:NN \l__weiqi_y_min_int \l__weiqi_y_int }
            \int_compare:nNnT
              \l__weiqi_y_max_int < \l__weiqi_y_int
              { \int_set_eq:NN \l__weiqi_y_max_int \l__weiqi_y_int }
          }
      }
  \int_compare:nNnT
    { \l__weiqi_x_min_int } = { 99 }
    {
      \int_set:Nn \l__weiqi_x_min_int { 1 }
      \int_set:Nn \l__weiqi_y_min_int { 1 }
      \int_set_eq:NN \l__weiqi_x_max_int \g__weiqi_size_int
      \int_set_eq:NN \l__weiqi_y_max_int \g__weiqi_size_int
    }
    \int_set:Ne \l_tmpa_int
      { \int_min:nn { \g__weiqi_size_int } { \l__weiqi_min_width_int } }
    \int_compare:nNnTF
      { \g__weiqi_size_int - \l__weiqi_x_max_int } > { \l__weiqi_x_min_int - 1 }
      {
        \int_set:Nn \l__weiqi_x_min_int { 1 }
        \int_set:Ne \l__weiqi_x_max_int
          { \int_max:nn { \l__weiqi_x_max_int + 1 } { \l_tmpa_int } }
      }
      {
        \int_set_eq:NN \l__weiqi_x_max_int \g__weiqi_size_int
        \int_compare:nNnF
          { \l__weiqi_x_min_int } = { 1 }
          {
            \int_set:Ne \l__weiqi_x_min_int
              {
                \int_min:nn
                  { \l__weiqi_x_min_int - 1 }
                  { \g__weiqi_size_int -  \l_tmpa_int + 1 }
              }
          }
      }
    \int_set:Ne \l_tmpa_int
      { \int_min:nn { \g__weiqi_size_int } { \l__weiqi_min_hight_int } }
    \int_compare:nNnTF
      { \g__weiqi_size_int - \l__weiqi_y_max_int } > { \l__weiqi_y_min_int - 1 }
      {
        \int_set:Nn \l__weiqi_y_min_int { 1 }
        \int_set:Ne \l__weiqi_y_max_int
          { \int_max:nn { \l__weiqi_y_max_int + 1 } { \l_tmpa_int } }
      }
      {
        \int_set_eq:NN \l__weiqi_y_max_int \g__weiqi_size_int
        \int_compare:nNnF
          { \l__weiqi_y_min_int } = { 1 }
          {
            \int_set:Ne \l__weiqi_y_min_int
              {
                \int_min:nn
                  { \l__weiqi_y_min_int - 1 }
                  { \g__weiqi_size_int - \l_tmpa_int + 1 }
              }
          }
      }
    \__weiqi_transform_xy:NN \l__weiqi_x_min_int \l__weiqi_y_min_int
    \__weiqi_transform_xy:NN \l__weiqi_x_max_int \l__weiqi_y_max_int
  }
\cs_new:Npn \__weiqi_set_range:n #1
  {
    \str_compare:eNeTF
      { \str_lowercase:n { #1 } } = { full }
      {
        \int_set:Nn \l__weiqi_x_min_int { 1 }
        \int_set:Nn \l__weiqi_y_min_int { 1 }
        \int_set_eq:NN \l__weiqi_x_max_int \g__weiqi_size_int
        \int_set_eq:NN \l__weiqi_y_max_int \g__weiqi_size_int
      }
      {
        \clist_set:Nn \l__weiqi_position_clsit { #1 }
        \clist_pop:NN \l__weiqi_position_clsit \l_tmpa_tl
        \__weiqi_loc_to_xy:V { \l_tmpa_tl }
        \int_set_eq:NN \l__weiqi_x_min_int \l__weiqi_x_int
        \int_set_eq:NN \l__weiqi_y_min_int \l__weiqi_y_int
        \clist_pop:NN \l__weiqi_position_clsit \l_tmpa_tl
        \__weiqi_loc_to_xy:V { \l_tmpa_tl }
        \int_set_eq:NN \l__weiqi_x_max_int \l__weiqi_x_int
        \int_set_eq:NN \l__weiqi_y_max_int \l__weiqi_y_int
      }
    \int_compare:nNnT { \l__weiqi_x_min_int } > { \l__weiqi_x_max_int }
    {
      \int_set_eq:NN \l_tmpa_int \l__weiqi_x_min_int
      \int_set_eq:NN \l__weiqi_x_min_int \l__weiqi_x_max_int
      \int_set_eq:NN \l__weiqi_x_max_int \l_tmpa_int
    }
    \int_compare:nNnT { \l__weiqi_y_min_int } > { \l__weiqi_y_max_int }
    {
      \int_set_eq:NN \l_tmpa_int \l__weiqi_y_min_int
      \int_set_eq:NN \l__weiqi_y_min_int \l__weiqi_y_max_int
      \int_set_eq:NN \l__weiqi_y_max_int \l_tmpa_int
    }
    \__weiqi_transform_xy:NN \l__weiqi_x_min_int \l__weiqi_y_min_int
    \__weiqi_transform_xy:NN \l__weiqi_x_max_int \l__weiqi_y_max_int
  }
\cs_new:Nn \__weiqi_calc_board_border:
  {
    \int_compare:nNnTF
      { \int_abs:n { \l__weiqi_x_min_int } } = { 1 }
      {
        \bool_set_true:N \l__weiqi_left_bool
        \fp_set:Nn \l__weiqi_x_min_fp
          { \l__weiqi_x_min_int }
      }
      {
        \bool_set_false:N \l__weiqi_left_bool
        \fp_set:Nn \l__weiqi_x_min_fp
          { \l__weiqi_x_min_int - 0.3 * \int_sign:n { \l__weiqi_x_min_int } }
      }
    \int_compare:nNnTF
      { \int_abs:n { \l__weiqi_x_max_int } } = { \g__weiqi_size_int }
      {
        \bool_set_true:N \l__weiqi_right_bool
        \fp_set:Nn \l__weiqi_x_max_fp
          { \l__weiqi_x_max_int }
      }
      {
        \bool_set_false:N \l__weiqi_right_bool
        \fp_set:Nn \l__weiqi_x_max_fp
          { \l__weiqi_x_max_int + 0.3 * \int_sign:n { \l__weiqi_x_max_int } }
      }
    \int_compare:nNnTF
      { \int_abs:n { \l__weiqi_y_min_int } } = { 1 }
      {
        \bool_set_true:N \l__weiqi_down_bool
        \fp_set:Nn \l__weiqi_y_min_fp
          { \l__weiqi_y_min_int }
      }
      {
        \bool_set_false:N \l__weiqi_down_bool
        \fp_set:Nn \l__weiqi_y_min_fp
          { \l__weiqi_y_min_int - 0.3 * \int_sign:n { \l__weiqi_y_min_int } }
      }
    \int_compare:nNnTF
      { \int_abs:n { \l__weiqi_y_max_int } } = { \g__weiqi_size_int }
      {
        \bool_set_true:N \l__weiqi_up_bool
        \fp_set:Nn \l__weiqi_y_max_fp
          { \l__weiqi_y_max_int }
      }
      {
        \bool_set_false:N \l__weiqi_up_bool
        \fp_set:Nn \l__weiqi_y_max_fp
          { \l__weiqi_y_max_int + 0.3 * \int_sign:n { \l__weiqi_y_max_int } }
      }
  }
\prg_set_conditional:Npnn \__weiqi_within_range:nn #1#2 { p, T }
  {
    \fp_set:Nn \l_tmpa_fp { abs( \l__weiqi_x_min_fp - #1 ) }
    \fp_add:Nn \l_tmpa_fp { abs( \l__weiqi_x_max_fp - #1 ) }
    \fp_sub:Nn \l_tmpa_fp { abs( \l__weiqi_x_max_fp - \l__weiqi_x_min_fp ) }
    \fp_add:Nn \l_tmpa_fp { abs( \l__weiqi_y_min_fp - #2 ) }
    \fp_add:Nn \l_tmpa_fp { abs( \l__weiqi_y_max_fp - #2 ) }
    \fp_sub:Nn \l_tmpa_fp { abs( \l__weiqi_y_max_fp - \l__weiqi_y_min_fp ) }
    \fp_compare:nNnTF
      { \l_tmpa_fp } < { 0.1 }
      { \prg_return_true: }
      { \prg_return_false: }
  }
\cs_new:Nn \__weiqi_draw_board_grid:
  {
    \int_set:Ne \l__weiqi_tmp_int
      { \int_sign:n { \l__weiqi_x_max_int - \l__weiqi_x_min_int } }
    \int_step_inline:nnnn
      { \l__weiqi_x_min_int } { \l__weiqi_tmp_int } { \l__weiqi_x_max_int }
      {
        \draw_path_moveto:n { ##1 cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { ##1 cm, \l__weiqi_y_max_fp cm }
      }
    \int_set:Ne \l__weiqi_tmp_int
      { \int_sign:n { \l__weiqi_y_max_int - \l__weiqi_y_min_int } }
    \int_step_inline:nnnn
      { \l__weiqi_y_min_int } { \l__weiqi_tmp_int } { \l__weiqi_y_max_int }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, ##1 cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, ##1 cm }
      }
  }
\cs_new:Nn \__weiqi_draw_board_border:
  {
    \bool_if:nT { \l__weiqi_left_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_max_fp cm }
      }
    \bool_if:nT { \l__weiqi_right_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_max_fp cm }
      }
    \bool_if:nT { \l__weiqi_down_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_min_fp cm }
      }
    \bool_if:nT { \l__weiqi_up_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_max_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_max_fp cm }
      }
  }
\cs_new:Nn \__weiqi_draw_board_corner:
  {
    \bool_if:nT { \l__weiqi_left_bool && \l__weiqi_down_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_max_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_min_fp cm }
      }
    \bool_if:nT { \l__weiqi_right_bool && \l__weiqi_down_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_max_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_min_fp cm }
      }
    \bool_if:nT { \l__weiqi_right_bool && \l__weiqi_up_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_max_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_max_fp cm }
      }
    \bool_if:nT { \l__weiqi_left_bool && \l__weiqi_up_bool }
      {
        \draw_path_moveto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_min_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_min_fp cm, \l__weiqi_y_max_fp cm }
        \draw_path_lineto:n { \l__weiqi_x_max_fp cm, \l__weiqi_y_max_fp cm }
      }
  }
\cs_new:Npn \__weiqi_draw_point:n #1
  {
    \__weiqi_loc_to_xy:n { #1 }
    \__weiqi_transform_xy:NN \l__weiqi_x_int \l__weiqi_y_int
    \__weiqi_within_range:nnT { \l__weiqi_x_int } { \l__weiqi_y_int }
      {
        \draw_path_circle:nn
          { \l__weiqi_x_int  cm, \l__weiqi_y_int cm } { 1mm }
      }
  }
\cs_new:Nn \__weiqi_draw_board_star:
  {
    \clist_clear:N \l__weiqi_point_clist
    \int_case:nn { \g__weiqi_size_int }
      {
        { \c__weiqi_normal_size_int }
        { \clist_set_eq:NN \l__weiqi_point_clist \c__weiqi_normal_star_clist }
        { \c__weiqi_mid_size_int }
        { \clist_set_eq:NN \l__weiqi_point_clist \c__weiqi_mid_star_clist }
        { \c__weiqi_small_size_int }
        { \clist_set_eq:NN \l__weiqi_point_clist \c__weiqi_small_star_clist }
      }
    \clist_map_function:NN \l__weiqi_point_clist \__weiqi_draw_point:n
  }
\cs_new:Npn \__weiqi_set_loc_label:nn #1#2
  {
    \str_case_e:nn { #1 }
    {
      { A }
      { \str_set:Nx \l__weiqi_label_str { \int_to_Alph:n { #2 } } }
      { \c__weiqi_normal_mode_str }
      { \str_set:NV \l__weiqi_label_str { #2 } }
      { \c__weiqi_sgf_mode_str }
      {
        \int_set:Nn \l_tmpa_int { \g__weiqi_size_int - #2 + 1 }
        \str_set:Nx\l__weiqi_label_str { \int_to_alph:n { \l_tmpa_int } }
      }
    }
  }
\cs_new:Nn \__weiqi_draw_board_loc:
  {
    \int_gset:Nn \g_tmpa_int
      { \int_sign:n { \l__weiqi_x_max_int - \l__weiqi_x_min_int } }
    \int_gset:Nn \g_tmpb_int
      { \int_sign:n { \l__weiqi_y_max_int - \l__weiqi_y_min_int } }
    \int_step_inline:nnnn
      { \l__weiqi_x_min_int } { \g_tmpa_int } { \l__weiqi_x_max_int }
      {
        \int_set:Ne \l__weiqi_tmp_int { \int_abs:n { ##1 } }
        \bool_if:NTF \l__weiqi_swap_xy_bool
          { \__weiqi_set_loc_label:nn { \l__weiqi_loc_mode_str } { \l__weiqi_tmp_int } }
          { \__weiqi_set_loc_label:nn { A } { \l__weiqi_tmp_int } }
        \hbox_set:Nn \l_tmpa_box { \l__weiqi_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__weiqi_up_bool
          {
            \draw_box_use:Nn \l_tmpa_box
              {
                ##1 cm - 0.5 * { \box_wd:N \l_tmpa_box },
                (\l__weiqi_y_max_fp + \l_tmpa_fp ) cm - abs(\l_tmpb_fp) + \l_tmpb_fp
              }
          }
        \bool_if:NT \l__weiqi_down_bool
          {
            \draw_box_use:Nn \l_tmpa_box
              {
                ##1 cm - 0.5 * { \box_wd:N \l_tmpa_box },
                (\l__weiqi_y_min_fp - \l_tmpa_fp ) cm - abs(\l_tmpb_fp) - \l_tmpb_fp
              }
          }
      }
    \int_step_inline:nnnn
      { \l__weiqi_y_min_int } { \g_tmpb_int } { \l__weiqi_y_max_int }
      {
        \int_set:Ne \l__weiqi_tmp_int { \int_abs:n { ##1 } }
        \bool_if:NTF \l__weiqi_swap_xy_bool
          { \__weiqi_set_loc_label:nn { A } { \l__weiqi_tmp_int } }
          { \__weiqi_set_loc_label:nn { \l__weiqi_loc_mode_str } { \l__weiqi_tmp_int } }
        \hbox_set:Nn \l_tmpa_box { \l__weiqi_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__weiqi_left_bool
          {
            \draw_box_use:Nn \l_tmpa_box
              {
                (\l__weiqi_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__weiqi_right_bool
          {
            \draw_box_use:Nn \l_tmpa_box
              {
                (\l__weiqi_y_max_fp + \l_tmpa_fp) cm  - abs(\l_tmpb_fp) + \l_tmpb_fp,
                ##1 cm - 0.5 * { \box_ht:N \l_tmpa_box }
              }
          }
      }
  }
\cs_new:Nn \__weiqi_draw_board:
  {
    \__weiqi_calc_board_border:
    \draw_linewidth:n { 0.7 }
    \color_select:n { black }
    \__weiqi_draw_board_grid:
    \draw_path_use_clear:n { stroke }
    \draw_linewidth:n { 2 }
    \__weiqi_draw_board_border:
    \draw_path_use_clear:n { stroke }
    \__weiqi_draw_board_corner:
    \draw_path_use_clear:n { stroke }
    \color_select:n { black }
    \__weiqi_draw_board_star:
    \draw_path_use_clear:n { draw, fill }
    \color_select:n { black!50 }
    \bool_if:NT \l__weiqi_show_loc_bool
      { \__weiqi_draw_board_loc: }
    \draw_path_use_clear:n { stroke }
  }
\cs_new:Npn \__weiqi_draw_points:
  {
    \color_select:n { red }
    \clist_map_function:NN \g__weiqi_red_point_clist \__weiqi_draw_point:n
    \draw_path_use_clear:n { draw, fill }
    \color_select:n { green }
    \clist_map_function:NN \g__weiqi_green_point_clist \__weiqi_draw_point:n
    \draw_path_use_clear:n { draw, fill }
    \color_select:n { blue }
    \clist_map_function:NN \g__weiqi_blue_point_clist \__weiqi_draw_point:n
    \draw_path_use_clear:n { draw, fill }
  }
\cs_new:Npn \__weiqi_draw_stone:nnnn #1#2#3#4
  {
    \int_compare:nNnF { #1 } = { 3 }
      {
        \color_fill:n { white }
        \draw_path_circle:nn { #2cm, #3cm } { 4.4mm }
        \draw_path_use_clear:n { fill }
      }
    \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 }
    \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 }
      }
  }
\cs_new:Nn \__weiqi_draw_stones:
  {
    \draw_linewidth:n { 1 }
    \int_step_inline:nn  {\g__weiqi_step_count_int}
      {
        \int_set:Ne \l__weiqi_x_int
          { \intarray_item:Nn \g__weiqi_x_intarray { ##1 } }
        \int_set:Ne \l__weiqi_y_int
          { \intarray_item:Nn \g__weiqi_y_intarray { ##1 } }
        \int_set:Ne \l__weiqi_player_int
          { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } }
        \str_set:Nx \l__weiqi_tmp_str
          { \seq_item:Nn \g__weiqi_label_seq { ##1 } }
        \seq_if_in:NnT \g__weiqi_die_seq { ##1 }
          { \int_set:Nn \l__weiqi_x_int { 0 } }
        \int_if_zero:nF { \l__weiqi_x_int }
          {
            \__weiqi_transform_xy:NN \l__weiqi_x_int \l__weiqi_y_int
            \__weiqi_within_range:nnT
              { \l__weiqi_x_int } { \l__weiqi_y_int }
              {
                \__weiqi_draw_stone:nnnn { \l__weiqi_player_int }
                  { \l__weiqi_x_int } { \l__weiqi_y_int } { \l__weiqi_tmp_str }
              }
          }
      }
  }
\cs_new:Nn \__weiqi_draw_specific_stone:
  {
    \color_select:n { black }
    \int_case:nn { \l__weiqi_player_int }
      {
        { 1 } { \color_fill:n { black } }
        { 2 } { \color_fill:n { white } }
      }
    \draw_path_circle:nn{ \l__weiqi_x_fp cm, \l__weiqi_y_fp cm } { 4mm }
    \draw_path_use_clear:n { draw, fill }
    \int_case:nn { \l__weiqi_player_int }
      {
        { 1 } { \color_select:n { white } }
        { 2 } { \color_select:n { black } }
      }
    \__weiqi_xy_to_loc:N \l_tmpa_str
    \hbox_set:Nn \l_tmpa_box { \Large \textbf{ \l__weiqi_tmp_str } }
    \hbox_set:Nn \l_tmpb_box { \Large \texttt{ \l_tmpa_str } }
    \draw_box_use:Nn \l_tmpa_box
      {
        \l__weiqi_x_fp cm - 0.5 * { \box_wd:N \l_tmpa_box },
        \l__weiqi_y_fp cm - 0.5 * { \box_ht:N \l_tmpa_box }
      }
    \color_select:n { black }
    \draw_box_use:Nn \l_tmpb_box
      {
        \l__weiqi_x_fp cm + 6mm,
        \l__weiqi_y_fp cm - 0.5 * { \box_ht:N \l_tmpa_box }
      }
    \fp_set:Nn \l_tmpa_fp { min(\l__weiqi_x_min_fp, \l__weiqi_x_max_fp) }
    \fp_set:Nn \l_tmpb_fp { max(\l__weiqi_x_min_fp, \l__weiqi_x_max_fp) }
    \fp_add:Nn \l__weiqi_x_fp { 2 }
    \fp_compare:nNnT { \l__weiqi_x_fp } > { \l_tmpb_fp }
      {
        \fp_set_eq:NN \l__weiqi_x_fp \l_tmpa_fp
        \fp_sub:Nn \l__weiqi_y_fp { 1 }
      }
  }
\cs_new:Nn \__weiqi_draw_specific_stones:
  {
    \draw_linewidth:n { 1 }
    \fp_set:Nn \l__weiqi_x_fp { min(\l__weiqi_x_min_int, \l__weiqi_x_max_int) }
    \fp_set:Nn \l__weiqi_y_fp { min(\l__weiqi_y_min_int, \l__weiqi_y_max_int) - 1.2}
    \int_step_inline:nn  {\g__weiqi_step_count_int}
      {
        \int_set:Ne \l__weiqi_x_int
          { \intarray_item:Nn \g__weiqi_x_intarray { ##1 } }
        \int_set:Ne \l__weiqi_y_int
          { \intarray_item:Nn \g__weiqi_y_intarray { ##1 } }
        \int_set:Ne \l__weiqi_player_int
          { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } }
        \str_set:Nx \l__weiqi_tmp_str
          { \seq_item:Nn \g__weiqi_label_seq { ##1 } }
        \seq_if_in:NnTF \g__weiqi_die_seq { ##1 }
          { \int_set:Nn \l_tmpa_int { 0 } }
          { \int_set_eq:NN \l_tmpa_int \l__weiqi_x_int }
        \str_compare:eNeT { \l__weiqi_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__weiqi_player_int } > { 0 } }
            { \int_compare_p:nNn { \l__weiqi_player_int } < { 3 } }
          }
          { \__weiqi_draw_specific_stone: }
      }
  }
\cs_new:Nn \__weiqi_show:
  {
    \draw_begin:
      \group_begin:
        \draw_transform_scale:n { \l__weiqi_scale_fp }
        \__weiqi_draw_board:
        \__weiqi_draw_points:
        \__weiqi_draw_stones:
        \__weiqi_draw_specific_stones:
      \group_end:
    \draw_end:
  }
\NewDocumentCommand \newweiqi { s o }
  {
     \IfNoValueTF { #2 }
       { \__weiqi_new_game:n { \g__weiqi_default_size_int } }
       {
         \IfBooleanT { #1 } { \int_gset:Nn \g__weiqi_default_size_int { #2 } }
         \__weiqi_new_game:n { #2 }
       }
  }
\NewDocumentCommand \weiqisize { s m }
  {
    \IfBooleanT{ #1 }
      { \int_gset:Nn \g__weiqi_default_size_int { #2 } }
    \int_set:Nn \g__weiqi_size_int { #2 }
  }
\NewDocumentCommand \weiqiblack { s o m }
  {
    \IfNoValueTF { #2 }
      { \__weiqi_add_stones:nnn { 1 } { #3 } { } }
      { \__weiqi_add_stones:nnn { 1 } { #3 } { #2 } }
  }
\NewDocumentCommand \weiqiwhite { s o m }
  {
    \IfNoValueTF { #2 }
      { \__weiqi_add_stones:nnn { 2 } { #3 } { } }
      { \__weiqi_add_stones:nnn { 2 } { #3 } { #2 } }
  }
\NewDocumentCommand \weiqisgf { s o m }
  {
    \IfNoValueTF { #2 }
      { \__weiqi_add_sgf_stones:nn { #3 } { } }
      { \__weiqi_add_sgf_stones:nn { #3 } { #2 } }
  }
\NewDocumentCommand \inputsgf { s o m }
  {
    \ior_open:Nn \g_tmpa_ior { #3 }
    \str_set:Nn \l__weiqi_tmp_str {}
    \ior_str_map_inline:Nn \g_tmpa_ior
      {
        \str_put_right:Nx \l__weiqi_tmp_str { ##1 }
      }
    \ior_close:N \g_tmpa_ior
    \regex_extract_once:nVNTF { ;GM\[1\] } { \l__weiqi_tmp_str } \l_tmpa_seq
      {
        \regex_extract_once:nVNTF { SZ\[[0-9]+\] } { \l__weiqi_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__weiqi_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 } }
            \__weiqi_add_sgf_stones:VV { \l__weiqi_tmp_str } { \l_tmpa_int }
          }
          { 解析棋盘大小失败 }
      }
      { 不支持的棋谱 }
  }
\NewDocumentCommand \resetnumber { s o }
  {
    \IfNoValueTF { #2 }
      { \__weiqi_reset_stone_number:n { 1 } }
      { \__weiqi_reset_stone_number:n { #2 } }
  }
\NewDocumentCommand \weiqilabel { s o m }
  {
    \IfBooleanT{ #1 } { \__weiqi_clear_labels: }
    \IfNoValueTF { #2 }
      { \__weiqi_add_stones:nnn { 3 } { #3 } { a } }
      { \__weiqi_add_stones:nnn { 3 } { #3 } { #2 } }
  }
\NewDocumentCommand \clearlabel { }
  { \__weiqi_clear_labels: }
\NewDocumentCommand \weiqired { s m }
  {
    \IfBooleanT{ #1 } { \__weiqi_clear_points: }
    \__weiqi_add_points:nn { red } { #2 }
  }
\NewDocumentCommand \weiqigreen { s m }
  {
    \IfBooleanT{ #1 } { \__weiqi_clear_points: }
    \__weiqi_add_points:nn { green } { #2 }
  }
\NewDocumentCommand \weiqiblue { s m }
  {
    \IfBooleanT{ #1 } { \__weiqi_clear_points: }
    \__weiqi_add_points:nn { blue } { #2 }
  }
\NewDocumentCommand \clearpoint { }
  { \__weiqi_clear_points: }
\NewDocumentCommand \weiqidie { s m }
  {
    \__weiqi_modify_stones:nN { #2 } \__weiqi_die_stone:n
  }
\NewDocumentCommand \weiqiremove { s m }
  {
    \__weiqi_modify_stones:nN { #2 } \__weiqi_remove_stone:n
  }
\NewDocumentCommand \weiqichange { s m }
  {
    \__weiqi_modify_stones:nN { #2 } \__weiqi_change_stone:n
  }
\NewDocumentCommand \showweiqi { s o }
  {
    \IfNoValueTF { #2 }
      { \__weiqi_calc_range: }
      { \__weiqi_set_range:n { #2 } }
    \__weiqi_show:
    \IfBooleanF { #1 } { \newweiqi }
  }
\NewDocumentCommand \nonelocmode { s }
  {
    \bool_set_false:N \l__weiqi_show_loc_bool
    \IfBooleanT { #1 } { \bool_gset_false:N \g__weiqi_show_loc_bool }
  }
\NewDocumentCommand \normallocmode { s }
  {
    \bool_set_true:N \l__weiqi_show_loc_bool
    \str_set_eq:NN \l__weiqi_loc_mode_str \c__weiqi_normal_mode_str
    \IfBooleanT { #1 }
      {
        \bool_gset_true:N \g__weiqi_show_loc_bool
        \str_gset_eq:NN \g__weiqi_loc_mode_str \c__weiqi_normal_mode_str
      }
  }
\NewDocumentCommand \sgflocmode { s }
  {
    \bool_set_true:N \l__weiqi_show_loc_bool
    \str_set_eq:NN \l__weiqi_loc_mode_str \c__weiqi_sgf_mode_str
    \IfBooleanT { #1 }
      {
        \bool_gset_true:N \g__weiqi_show_loc_bool
        \str_gset_eq:NN \g__weiqi_loc_mode_str \c__weiqi_sgf_mode_str
      }
  }

\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__weiqi_swap_xy_bool
          \int_set:Ne \l_tmpb_int { \l__weiqi_x_direction_int }
          \int_set:Ne \l__weiqi_x_direction_int { \l__weiqi_y_direction_int }
          \int_set:Ne \l__weiqi_y_direction_int { 0 - \l_tmpb_int }
        }
        { 180 }
        {
          \int_set:Ne \l__weiqi_x_direction_int { 0 - \l__weiqi_x_direction_int }
          \int_set:Ne \l__weiqi_y_direction_int { 0 - \l__weiqi_y_direction_int }
        }
        { 270 }
        {
          \bool_set_inverse:N \l__weiqi_swap_xy_bool
          \int_set:Ne \l_tmpb_int { \l__weiqi_x_direction_int }
          \int_set:Ne \l__weiqi_x_direction_int { 0 - \l__weiqi_y_direction_int }
          \int_set:Ne \l__weiqi_y_direction_int { \l_tmpb_int }
        }
      }
    \IfBooleanT{ #1 }
      {
        \bool_gset_eq:NN \g__weiqi_swap_xy_bool \l__weiqi_swap_xy_bool
        \int_gset_eq:NN \g__weiqi_x_direction_int \l__weiqi_x_direction_int
        \int_gset_eq:NN \g__weiqi_y_direction_int \l__weiqi_y_direction_int
      }
  }
\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__weiqi_x_direction_int { 0 - \l__weiqi_x_direction_int }
      }
      { y }
      {
        \int_set:Ne \l__weiqi_y_direction_int { 0 - \l__weiqi_y_direction_int }
      }
      { xy }
      {
        \int_set:Ne \l__weiqi_x_direction_int { 0 - \l__weiqi_x_direction_int }
        \int_set:Ne \l__weiqi_y_direction_int { 0 - \l__weiqi_y_direction_int }
      }

    }
    \IfBooleanT{ #1 }
      {
        \bool_set_eq:NN \g__weiqi_swap_xy_bool \l__weiqi_swap_xy_bool
        \int_set_eq:NN \g__weiqi_x_direction_int \l__weiqi_x_direction_int
        \int_set_eq:NN \g__weiqi_y_direction_int \l__weiqi_y_direction_int
      }
  }
\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__weiqi_swap_xy_bool
          \int_set:Nn \l__weiqi_x_direction_int { 1 }
          \int_set:Nn \l__weiqi_y_direction_int { 1 }
        }
        { 90 }
        {
          \bool_set_true:N \l__weiqi_swap_xy_bool
          \int_set:Nn \l__weiqi_x_direction_int { 1 }
          \int_set:Nn \l__weiqi_y_direction_int { -1 }
        }
        { 180 }
        {
          \bool_set_false:N \l__weiqi_swap_xy_bool
          \int_set:Nn \l__weiqi_x_direction_int { -1 }
          \int_set:Nn \l__weiqi_y_direction_int { -1 }
        }
        { 270 }
        {
          \bool_set_true:N \l__weiqi_swap_xy_bool
          \int_set:Nn \l__weiqi_x_direction_int { -1 }
          \int_set:Nn \l__weiqi_y_direction_int { 1 }
        }
      }
    \IfBooleanT{ #1 }
      {
        \bool_gset_eq:NN \g__weiqi_swap_xy_bool \l__weiqi_swap_xy_bool
        \int_gset_eq:NN \g__weiqi_x_direction_int \l__weiqi_x_direction_int
        \int_gset_eq:NN \g__weiqi_y_direction_int \l__weiqi_y_direction_int
      }
  }
\NewDocumentCommand \weiqiscale { s o }
  {
    \IfNoValueTF { #2 }
      { \fp_set:Nn \l__weiqi_scale_fp { 1.0 } }
      { \fp_set:Nn \l__weiqi_scale_fp { #2 * \l__weiqi_scale_fp } }
    \IfBooleanT{ #1 }
      { \fp_set_eq:NN \g__weiqi_scale_fp \l__weiqi_scale_fp }
  }
\NewDocumentCommand \weiqiminsize { s m m }
  {
    \int_set:Nn \l__weiqi_min_width_int { #2 }
    \int_set:Nn \l__weiqi_min_hight_int { #3 }
    \IfBooleanT{ #1 }
      {
        \int_gset:Nn \g__weiqi_min_width_int { #2 }
        \int_gset:Nn \g__weiqi_min_hight_int { #3 }
      }
  }
\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__weiqi_size_int_\l_tmpa_str }
      {
        \int_new:c { g__weiqi_size_int_\l_tmpa_str }
        \int_new:c { g__weiqi_step_count_int_\l_tmpa_str }
        \intarray_new:cn { g__weiqi_x_intarray_\l_tmpa_str }
          { \c__weiqi_max_step_int }
        \intarray_new:cn { g__weiqi_y_intarray_\l_tmpa_str }
          { \c__weiqi_max_step_int }
        \intarray_new:cn { g__weiqi_player_intarray_\l_tmpa_str }
          { \c__weiqi_max_step_int }
        \seq_new:c { g__weiqi_label_seq_\l_tmpa_str }
        \seq_new:c { g__weiqi_die_seq_\l_tmpa_str }
      }
    \int_gset_eq:cN { g__weiqi_size_int_\l_tmpa_str } \g__weiqi_size_int
    \int_gset_eq:cN
      { g__weiqi_step_count_int_\l_tmpa_str } \g__weiqi_step_count_int
    \int_step_inline:nn { \c__weiqi_max_step_int }
      {
        \intarray_gset:cnn { g__weiqi_x_intarray_\l_tmpa_str } { ##1 }
          { \intarray_item:Nn \g__weiqi_x_intarray  { ##1 } }
        \intarray_gset:cnn { g__weiqi_y_intarray_\l_tmpa_str } { ##1 }
          { \intarray_item:Nn \g__weiqi_y_intarray  { ##1 } }
        \intarray_gset:cnn { g__weiqi_player_intarray_\l_tmpa_str } { ##1 }
          { \intarray_item:Nn \g__weiqi_player_intarray  { ##1 } }
      }
    \clist_gset_eq:cN { g__weiqi_label_seq_\l_tmpa_str } \g__weiqi_label_seq
    \clist_gset_eq:cN { g__weiqi_die_seq_\l_tmpa_str } \g__weiqi_die_seq
  }
\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__weiqi_size_int_\l_tmpa_str }
      { \__weiqi_new_game:n { \g__weiqi_default_size_int } }
      {
        \int_set_eq:Nc \l_tmpa_int { g__weiqi_size_int_\l_tmpa_str }
        \__weiqi_new_game:n { \l_tmpa_int }
        \int_gset_eq:Nc \g__weiqi_step_count_int
          { g__weiqi_step_count_int_\l_tmpa_str }
        \int_step_inline:nn { \c__weiqi_max_step_int }
          {
            \intarray_gset:Nnn \g__weiqi_x_intarray { ##1 }
              { \intarray_item:cn { g__weiqi_x_intarray_\l_tmpa_str }  { ##1 } }
            \intarray_gset:Nnn \g__weiqi_y_intarray { ##1 }
              { \intarray_item:cn { g__weiqi_y_intarray_\l_tmpa_str }  { ##1 } }
            \intarray_gset:Nnn \g__weiqi_player_intarray { ##1 }
              {
                \intarray_item:cn
                  { g__weiqi_player_intarray_\l_tmpa_str }  { ##1 }
              }
          }
        \clist_set_eq:Nc \g__weiqi_label_seq { g__weiqi_label_seq_\l_tmpa_str }
        \clist_set_eq:Nc \g__weiqi_die_seq { g__weiqi_die_seq_\l_tmpa_str }
      }
    \IfBooleanT{ #1 }
      {
        \__weiqi_clear_labels:
        \int_step_inline:nn { \g__weiqi_step_count_int }
          {
            \seq_gset_item:Nnn \g__weiqi_label_seq { ##1 } {}
          }
      }
  }
\NewDocumentCommand \weiqidata { s }
  {
    \noindent 棋盘大小：\int_use:N \g__weiqi_size_int~
    （默认：\int_use:N \g__weiqi_default_size_int）\\
    当前对局步数：\int_use:N \g__weiqi_step_count_int~（含纯标签及移除棋子）\\
    \int_compare:nNnT { \g__weiqi_step_count_int } > { 0 }
      { 序号：($x$,~$y$)，所属方，标签，备注\\ }
    \int_step_inline:nn  {\g__weiqi_step_count_int}
      {
        \int_set:Ne \l__weiqi_x_int
          { \intarray_item:Nn \g__weiqi_x_intarray { ##1 } }
        \int_set:Ne \l__weiqi_y_int
          { \intarray_item:Nn \g__weiqi_y_intarray { ##1 } }
        \int_set:Ne \l__weiqi_player_int
          { \intarray_item:Nn \g__weiqi_player_intarray { ##1 } }
        \str_set:Nx \l__weiqi_tmp_str
          { \seq_item:Nn \g__weiqi_label_seq { ##1 } }
        ##1：
        (\int_use:N \l__weiqi_x_int,~\int_use:N \l__weiqi_y_int)，
        \int_case:nn { \l__weiqi_player_int }
          {
            { 1 } { B }
            { 2 } { W }
            { 3 } { L }
            { 0 } { - }
          }，
        \str_if_empty:NTF \l__weiqi_tmp_str
          { \meta{空} }
          { \l__weiqi_tmp_str }，
        \int_compare:nNnTF
          { \l__weiqi_player_int } = { 0 }
          { \meta{无效} }
          {
            \seq_if_in:NnT \g__weiqi_die_seq { ##1 }
              {  \meta{死子} }
              {
                \int_compare:nNnT
                  { \l__weiqi_x_int } = { 0 }
                  {  \meta{虚着} }
              }
          }\\
      }
    红色指示点：
      \clist_if_empty:NTF \g__weiqi_red_point_clist
        { \meta{空} }
        { \clist_use:Nn \g__weiqi_red_point_clist {,~} }\\
    绿色指示点：
      \clist_if_empty:NTF \g__weiqi_green_point_clist
        { \meta{空} }
        { \clist_use:Nn \g__weiqi_green_point_clist {,~} }\\
    蓝色指示点：
      \clist_if_empty:NTF \g__weiqi_blue_point_clist
        { \meta{空} }
        { \clist_use:Nn \g__weiqi_blue_point_clist {,~} }\\
    方位信息：
      \int_use:N \l__weiqi_x_direction_int,~
      \int_use:N \l__weiqi_x_direction_int,~
      \bool_to_str:N \l__weiqi_swap_xy_bool；~
    （全局：
      \int_use:N \g__weiqi_x_direction_int,~
      \int_use:N \g__weiqi_x_direction_int,~
      \bool_to_str:N \g__weiqi_swap_xy_bool
    ）\\
    缩放比例：\fp_use:N \l__weiqi_scale_fp~
    （全局：\fp_use:N \g__weiqi_scale_fp）\\
    坐标刻度：\l__weiqi_loc_mode_str,~\bool_to_str:N \l__weiqi_show_loc_bool
    （全局：\g__weiqi_loc_mode_str,~\bool_to_str:N \g__weiqi_show_loc_bool）\\
    最小显示尺寸：
      \int_use:N \l__weiqi_min_width_int,~
      \int_use:N \l__weiqi_min_hight_int~
    （全局：
      \int_use:N \g__weiqi_min_width_int,~
      \int_use:N \g__weiqi_min_hight_int
    ）\\
    \IfBooleanT{ #1 }
      {
        棋子区间：
        (\int_use:N \l__weiqi_x_min_int,~\int_use:N \l__weiqi_y_max_int)，
        (\int_use:N \l__weiqi_x_max_int,~\int_use:N \l__weiqi_y_min_int)\\
        棋盘边界：
        (\fp_use:N \l__weiqi_x_min_fp,~\fp_use:N \l__weiqi_x_max_fp)，
        (\fp_use:N \l__weiqi_y_min_fp,~\fp_use:N \l__weiqi_y_max_fp)\\
        是否边路：
        \bool_to_str:N \l__weiqi_up_bool，
        \bool_to_str:N \l__weiqi_down_bool，
        \bool_to_str:N \l__weiqi_left_bool，
        \bool_to_str:N \l__weiqi_right_bool（上下左右）\\
      }
  }
\newweiqi
\ExplSyntaxOff
\endinput
%%
%% End of file `weiqi.sty'.
