\ProvidesFile{pgf-go-players.sty}[2026/10/23 v0.2026.10.23 pgf-go: players]
\ExplSyntaxOn
\cs_generate_variant:Nn \keys_define:nn {ee, en, ne}
\cs_generate_variant:Nn \keys_set:nn {ne}
\keys_define:nn {pgfgo} {players .code:n = {\keys_set:nn {pgfgo/players} {#1}}}
%NUMEROS EN KANJI (format = kanji Y LAS COORDENADAS DEL BORDE): 1 A 9, 十 (10), 十一 (11), 二十 (20), ...,
%百 (100), 二百三 (203); 0 ES 〇. NECESITAN UNA FUENTE QUE LOS TENGA.
\tl_const:Nn \c__pgfgo_kanji_tl {{一}{二}{三}{四}{五}{六}{七}{八}{九}}
\cs_new:Npn \pgfgo_int_to_kanji:n #1 {
\int_compare:nNnTF {#1} = {0} {〇} {
\__pgfgo_kanji_place:nn {\int_div_truncate:nn {#1} {100}} {百}
\__pgfgo_kanji_place:nn {\int_mod:nn {\int_div_truncate:nn {#1} {10}} {10}} {十}
\int_compare:nNnT {\int_mod:nn {#1} {10}} > {0}
{\tl_item:Nn \c__pgfgo_kanji_tl {\int_mod:nn {#1} {10}}}
}
}
%LA CIFRA #1 DE UN LUGAR #2 (百, 十): NADA SI ES 0, SOLO #2 SI ES 1.
\cs_new:Npn \__pgfgo_kanji_place:nn #1#2 {
\int_compare:nNnT {#1} > {1} {\tl_item:Nn \c__pgfgo_kanji_tl {#1}}
\int_compare:nNnT {#1} > {0} {#2}
}
%CUANTOS KANJI TIENE #1 ESCRITO ASI.
\cs_new:Npn \pgfgo_kanji_length:n #1 {
\int_eval:n {
\int_compare:nNnTF {#1} = {0} {1} {
\__pgfgo_kanji_place_length:n {\int_div_truncate:nn {#1} {100}}
+ \__pgfgo_kanji_place_length:n {\int_mod:nn {\int_div_truncate:nn {#1} {10}} {10}}
+ \int_compare:nNnTF {\int_mod:nn {#1} {10}} > {0} {1} {0}
}
}
}
\cs_new:Npn \__pgfgo_kanji_place_length:n #1 {\int_compare:nNnTF {#1} > {1} {2} {\int_compare:nNnTF {#1} > {0} {1} {0}}}
%LA FUNCION DE UN FORMATO DE NUMEROS (arabic, alph, Alph, roman, Roman, kanji).
\cs_new:Npn \__pgfgo_players_format_cs:n #1 {\str_if_eq:nnTF {#1} {kanji} {pgfgo_int_to_kanji:n} {int_to_ #1 :n}}
\cs_generate_variant:Nn \__pgfgo_players_format_cs:n {V}
%EL LARGO DE UN NUMERO #2 CON EL FORMATO #1 PARA ELEGIR EL TAMANO: LOS CARACTERES ALFANUMERICOS DEL TEXTO
%#3, O CON kanji, DOS POR KANJI (UN KANJI ES TAN ANCHO COMO DOS CIFRAS).
\regex_const:Nn \c__pgfgo_players_char_regex {[a-zA-Z\d]}
\cs_new_protected:Npn \pgfgo_players_label_length:NnnN #1#2#3#4 {
\cs_if_eq:NNTF #1 \pgfgo_int_to_kanji:n
{\int_set:Nn #4 {2 * \pgfgo_kanji_length:n {#2}}}
{\regex_count:NnN \c__pgfgo_players_char_regex {#3} #4}
}
\cs_generate_variant:Nn \pgfgo_players_label_length:NnnN {NnVN, NVVN}
\def\pgfgosetplayer#1#2{\pgfgoset{players = {#1 = {#2}}}}
\def\pgfgocopyplayers#1#2#3{
\pgfgocopyplayer{neutral} {#1}
\pgfgocopyplayer{black} {#2}
\pgfgocopyplayer{white} {#3}
}
%LAS VARIABLES DE CADA JUGADOR, COMO {TIPO}{PREFIJO}{NOMBRE}. LA DEL JUGADOR
ES _
%Y LA DEL JUGADOR ACTUAL, . A #1 SE LE AGREGAN LOS TRES ARGUMENTOS DE CADA UNA.
\cs_new:Npn \__pgfgo_players_fields:n #1 {
#1 {dim} {l_pgfgo_players_} {stone_radius_dim}
#1 {fp} {l_pgfgo_players_} {stone_scale_fp}
#1 {bool} {l_pgfgo_players_} {stone_line_bool}
#1 {tl} {l_pgfgo_players_} {stone_line_color_tl}
#1 {dim} {l_pgfgo_players_} {stone_line_width_dim}
#1 {fp} {l_pgfgo_players_} {stone_line_opacity_fp}
#1 {bool} {l_pgfgo_players_} {stone_fill_bool}
#1 {tl} {l_pgfgo_players_} {stone_fill_color_tl}
#1 {fp} {l_pgfgo_players_} {stone_fill_opacity_fp}
#1 {bool} {l_pgfgo_players_} {stone_shadow_bool}
#1 {fp} {l_pgfgo_players_} {stone_shadow_angle_fp}
#1 {dim} {l_pgfgo_players_} {stone_shadow_offset_dim}
#1 {fp} {l_pgfgo_players_} {stone_shadow_opacity_fp}
#1 {tl} {l_pgfgo_players_} {stone_shadow_color_tl}
#1 {fp} {l_pgfgo_players_} {stone_shadow_scale_fp}
#1 {tl} {l_pgfgo_players_} {stone_shadow_image_tl}
#1 {tl} {l_pgfgo_players_} {stone_shadow_image_width_tl}
#1 {tl} {l_pgfgo_players_} {stone_shadow_image_rotate_tl}
#1 {bool} {l_pgfgo_players_} {stone_shadow_image_silhouette_bool}
#1 {bool} {l_pgfgo_players_} {stone_shine_bool}
#1 {fp} {l_pgfgo_players_} {stone_shine_angle_fp}
#1 {fp} {l_pgfgo_players_} {stone_shine_opacity_fp}
#1 {tl} {l_pgfgo_players_} {stone_shine_color_tl}
#1 {tl} {l_pgfgo_players_} {stone_shine_image_tl}
#1 {tl} {l_pgfgo_players_} {stone_shine_image_width_tl}
#1 {tl} {l_pgfgo_players_} {stone_shine_image_rotate_tl}
#1 {bool} {l_pgfgo_players_} {stone_shine_image_silhouette_bool}
#1 {seq} {l_pgfgo_players_} {stone_image_seq}
#1 {tl} {l_pgfgo_players_} {stone_image_width_tl}
#1 {tl} {l_pgfgo_players_} {stone_image_rotate_tl}
#1 {tl} {l_pgfgo_players_} {stone_image_opacity_tl}
#1 {tl} {l_pgfgo_players_} {stone_prisoner_tl}
#1 {tl} {l_pgfgo_players_} {move_label_font_tl}
#1 {tl} {l_pgfgo_players_} {move_label_font_size_tl}
#1 {tl} {l_pgfgo_players_} {move_label_color_tl}
#1 {tl} {l_pgfgo_players_} {move_label_opacity_tl}
#1 {cs} {pgfgo_players_} {move_label_format:n}
#1 {fp} {l_pgfgo_players_} {mark_scale_fp}
#1 {tl} {l_pgfgo_players_} {mark_line_color_tl}
#1 {dim} {l_pgfgo_players_} {mark_line_width_dim}
#1 {tl} {l_pgfgo_players_} {mark_line_opacity_tl}
#1 {tl} {l_pgfgo_players_} {mark_fill_color_tl}
#1 {bool} {l_pgfgo_players_} {mark_fill_bool}
#1 {tl} {l_pgfgo_players_} {mark_fill_opacity_tl}
#1 {tl} {l_pgfgo_players_} {mark_label_color_tl}
#1 {bool} {l_pgfgo_players_} {mark_sequence_bool}
#1 {int} {l_pgfgo_} {mark_sequence_from_int}
#1 {cs} {pgfgo_players_} {mark_sequence_format:n}
#1 {tl} {l_pgfgo_players_} {mark_label_font_tl}
#1 {tl} {l_pgfgo_players_} {mark_label_font_size_tl}
}
%COPIA TODAS LAS VARIABLES DEL JUGADOR #2 EN LAS DEL JUGADOR #1.
\def\pgfgocopyplayer#1#2{\__pgfgo_players_fields:n {\__pgfgo_players_copy_field:nnnnn {#1} {#2}}}
\cs_new_protected:Npn \__pgfgo_players_copy_field:nnnnn #1#2#3#4#5 {
\use:c {#3_set_eq:cc} {#4 #1 _ #5} {#4 #2 _ #5}
}
%LAS VARIABLES DEL JUGADOR ACTUAL (LAS QUE USA EL DIBUJO).
\dim_new:N \l_pgfgo_players_stone_radius_dim
\fp_new:N \l_pgfgo_players_stone_scale_fp
\bool_new:N \l_pgfgo_players_stone_line_bool
\tl_new:N \l_pgfgo_players_stone_line_color_tl
\dim_new:N \l_pgfgo_players_stone_line_width_dim
\fp_new:N \l_pgfgo_players_stone_line_opacity_fp
\bool_new:N \l_pgfgo_players_stone_fill_bool
\tl_new:N \l_pgfgo_players_stone_fill_color_tl
\fp_new:N \l_pgfgo_players_stone_fill_opacity_fp
\bool_new:N \l_pgfgo_players_stone_shadow_bool
\fp_new:N \l_pgfgo_players_stone_shadow_angle_fp
\dim_new:N \l_pgfgo_players_stone_shadow_offset_dim
\fp_new:N \l_pgfgo_players_stone_shadow_opacity_fp
\tl_new:N \l_pgfgo_players_stone_shadow_color_tl
\fp_new:N \l_pgfgo_players_stone_shadow_scale_fp
\tl_new:N \l_pgfgo_players_stone_shadow_image_tl
\tl_new:N \l_pgfgo_players_stone_shadow_image_width_tl
\tl_new:N \l_pgfgo_players_stone_shadow_image_rotate_tl
\bool_new:N \l_pgfgo_players_stone_shadow_image_silhouette_bool
\bool_new:N \l_pgfgo_players_stone_shine_bool
\fp_new:N \l_pgfgo_players_stone_shine_angle_fp
\fp_new:N \l_pgfgo_players_stone_shine_opacity_fp
\tl_new:N \l_pgfgo_players_stone_shine_color_tl
\tl_new:N \l_pgfgo_players_stone_shine_image_tl
\tl_new:N \l_pgfgo_players_stone_shine_image_width_tl
\tl_new:N \l_pgfgo_players_stone_shine_image_rotate_tl
\bool_new:N \l_pgfgo_players_stone_shine_image_silhouette_bool
\seq_new:N \l_pgfgo_players_stone_image_seq
\tl_new:N \l_pgfgo_players_stone_image_width_tl
\tl_new:N \l_pgfgo_players_stone_image_rotate_tl
\tl_new:N \l_pgfgo_players_stone_image_opacity_tl
\tl_new:N \l_pgfgo_players_stone_prisoner_tl
\tl_new:N \l_pgfgo_players_move_label_font_tl
\tl_new:N \l_pgfgo_players_move_label_font_size_tl
\tl_new:N \l_pgfgo_players_move_label_color_tl
\tl_new:N \l_pgfgo_players_move_label_opacity_tl
\fp_new:N \l_pgfgo_players_mark_scale_fp
\tl_new:N \l_pgfgo_players_mark_line_color_tl
\dim_new:N \l_pgfgo_players_mark_line_width_dim
\tl_new:N \l_pgfgo_players_mark_line_opacity_tl
\tl_new:N \l_pgfgo_players_mark_fill_color_tl
\bool_new:N \l_pgfgo_players_mark_fill_bool
\tl_new:N \l_pgfgo_players_mark_fill_opacity_tl
\tl_new:N \l_pgfgo_players_mark_label_color_tl
\bool_new:N \l_pgfgo_players_mark_sequence_bool
\int_new:N \l_pgfgo_mark_sequence_from_int
\tl_new:N \l_pgfgo_players_mark_label_font_tl
\tl_new:N \l_pgfgo_players_mark_label_font_size_tl
%COPIA LOS VALORES DE UN JUGADOR PARA USARLOS. CADA JUGADOR TIENE SU PROPIA FUNCION DE COPIA
%(\__pgfgo_players_get_:), ARMADA AL CREARLO CON LOS NOMBRES DE LAS VARIABLES YA RESUELTOS.
\cs_new_protected:Npn \pgfgo_get_values_from_player:n #1 {\use:c {__pgfgo_players_get_ #1 :}}
%#1: EL JUGADOR. #2,#3,#4: LA VARIABLE (VER \__pgfgo_players_fields:n).
\cs_new:Npn \__pgfgo_players_get_field:nnnn #1#2#3#4 {
\exp_not:c {#2_set_eq:NN} \exp_not:c {#3 #4} \exp_not:c {#3 #1 _ #4}
}
%EL JUGADOR DE LA PIEDRA, LA JUGADA O LA MARCA ACTUAL: black, white O neutral.
\cs_new:Npn \__pgfgo_players_current: {
\bool_if:NTF \l_pgfgo_players_black_bool {black}
{\bool_if:NTF \l_pgfgo_players_white_bool {white} {neutral}}
}
\cs_new_protected:Npn \pgfgo_get_variables_from_current_player: {
\use:c {__pgfgo_players_get_ \__pgfgo_players_current: :}
}
\cs_generate_variant:Nn \keys_set_exclude_groups:nnn {enn}
%HACE QUE #1 (black, white O neutral) SEA EL JUGADOR ACTUAL.
\cs_new_protected:Npn \pgfgo_players_set_current:n #1 {
\bool_set_false:N \l_pgfgo_players_black_bool
\bool_set_false:N \l_pgfgo_players_white_bool
\bool_set_false:N \l_pgfgo_players_neutral_bool
\bool_set_true:c {l_pgfgo_players_ #1 _bool}
}
%LAS CLAVES black, b, white, w, neutral Y n DEL MODULO #1, EN EL GRUPO player-id: CADA UNA LLAMA A #2
%CON SU JUGADOR.
\cs_new_protected:Npn \pgfgo_players_define_id_keys:nN #1#2 {
\clist_map_inline:nn {{black} {b}, {white} {w}, {neutral} {n}}
{\__pgfgo_players_id_keys:nNnn {#1} #2 ##1}
}
\cs_new_protected:Npn \__pgfgo_players_id_keys:nNnn #1#2#3#4 {
\keys_define:nn {#1} {
#3 .code:n = {#2 {#3}},
#3 .groups:n = {player-id},
#4 .code:n = {#2 {#3}},
#4 .groups:n = {player-id},
}
}
\keys_define:nn {pgfgo / players} {
all .code:n = {
\keys_set:nn {pgfgo / players / neutral} {#1}
\keys_set:nn {pgfgo / players / black} {#1}
\keys_set:nn {pgfgo / players / white} {#1}
}
}
%LAS OPCIONES DE UNA MARCA QUE NO SON DEL ESTILO DEL JUGADOR (LA FORMA, custom, EL JUGADOR) SOLO VALEN
%MIENTRAS SE DIBUJA UNA MARCA (\l_pgfgo_players_mark_options_bool, VER pgf-go-marks.sty): EN
%\pgfgoset{players = ...} CAMBIARIAN LA MARCA DE LOS TRES JUGADORES. #1: EL JUGADOR. #2: LA CLAVE.
\bool_new:N \l_pgfgo_players_mark_options_bool
\msg_new:nnn {pgfgo} {player-mark-key}
{'#2'~is~not~a~key~of~/pgfgo/players/#1/mark.~Mark~shapes~go~in~the~options~of~a~mark~or~in~/pgfgo/mark.}
\cs_new_protected:Npn \__pgfgo_players_mark_other:nn #1#2 {
\bool_if:NTF \l_pgfgo_players_mark_options_bool
{\keys_set:nn {pgfgo / mark} {#2}}
{\msg_error:nnnn {pgfgo} {player-mark-key} {#1} {#2}}
}
\cs_generate_variant:Nn \__pgfgo_players_mark_other:nn {ne}
\def\pgfgonewplayers#1{\clist_map_function:nN {#1} \__pgfgo_players_new:n}
%LAS CLAVES Y VARIABLES DEL JUGADOR #1 (tests/check_docs.py LEE players/#1 COMO players/).
%CLAVES: /pgfgo/players/
\cs_new_protected:Npn \__pgfgo_players_new:n #1 {
%SIRVE PARA DETERMINAR SI UNA PIEDRA ES O NO DE ESTE JUGADOR
\bool_new:c {l_pgfgo_players_ #1 _bool}
\keys_define:nn {pgfgo / players}
{#1 .code:n = {\keys_set:nn {pgfgo / players / #1} {##1}}}
\keys_define:nn { pgfgo / players / #1 } {
stone .code:n = {\keys_set:nn {pgfgo / players / #1 / stone} {##1}},
move .code:n = {\keys_set:nn {pgfgo / players / #1 / move} {##1}},
mark .code:n = {\keys_set:nn {pgfgo / players / #1 / mark} {##1}},
territory .code:n = {\keys_set:nn {pgfgo / players / #1 / territory} {##1}},
%EL PERFIL DE JUGADOR (VER pgf-go-profiles.sty).
profile .code:n = {\pgfgo_profile_use_player:nn {#1} {##1}},
}
%----------------------------------------------------------------------------------------------------
%PIEDRA
\dim_new:c {l_pgfgo_players_ #1 _stone_radius_dim}
\fp_new:c {l_pgfgo_players_ #1 _stone_scale_fp}
%EL ESTILO DE SUS PRISIONEROS (VER \__pgfgo_stone_prisoner_style:n EN pgf-go-stones.sty).
\tl_new:c {l_pgfgo_players_ #1 _stone_prisoner_tl}
\keys_define:nn { pgfgo / players / #1 / stone } {
prisoner .tl_set:c = {l_pgfgo_players_ #1 _stone_prisoner_tl},
prisoner .groups:n = { external },
line .code:n = {\keys_set:nn { pgfgo / players / #1 / stone / line } {##1}},
line .default:n = {true},
fill .code:n = {\keys_set:nn { pgfgo / players / #1 / stone / fill } {##1}},
fill .default:n = {true},
radius .code:n = {\dim_set:cn{l_pgfgo_players_ #1 _stone_radius_dim}{##1}},
radius .initial:n = {5.5pt},
scale .code:n = {\fp_set:cn{l_pgfgo_players_ #1 _stone_scale_fp}{##1}},
scale .initial:n = {1},
shadow .code:n = {\keys_set:nn{ pgfgo / players / #1 / stone / shadow }{##1}},
shadow .default:n = {true},
shine .code:n = {\keys_set:nn{ pgfgo / players / #1 / stone / shine }{##1}},
shine .default:n = {true},
image .code:n = {\keys_set:nn{ pgfgo / players / #1 / stone / image }{##1}},
%LAS DEMAS OPCIONES DE \stones Y \moves.
mark .groups:n = { external },
black .groups:n = { external },
b .groups:n = { external },
white .groups:n = { external },
w .groups:n = { external },
neutral .groups:n = { external },
n .groups:n = { external },
forget .groups:n = { external },
label .groups:n = { external },
from .groups:n = { external },
numbers .groups:n = { external },
}
\bool_new:c {l_pgfgo_players_ #1 _stone_line_bool}
\bool_set_true:c {l_pgfgo_players_ #1 _stone_line_bool}
\tl_new:c {l_pgfgo_players_ #1 _stone_line_color_tl}
\dim_new:c {l_pgfgo_players_ #1 _stone_line_width_dim}
\fp_new:c {l_pgfgo_players_ #1 _stone_line_opacity_fp}
\keys_define:nn { pgfgo / players / #1 / stone / line } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _stone_line_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _stone_line_bool}},
color .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_line_color_tl}{##1}},
color .initial:n = {black},
width .code:n = {\dim_set:cn {l_pgfgo_players_ #1 _stone_line_width_dim}{##1}},
width .initial:n = {0.7pt},
opacity .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_line_opacity_fp}{##1}},
opacity .initial:n = {1}
}
\bool_new:c {l_pgfgo_players_ #1 _stone_fill_bool}
\bool_set_true:c {l_pgfgo_players_ #1 _stone_fill_bool}
\tl_new:c {l_pgfgo_players_ #1 _stone_fill_color_tl}
\fp_new:c {l_pgfgo_players_ #1 _stone_fill_opacity_fp}
\keys_define:nn { pgfgo / players / #1 / stone / fill } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _stone_fill_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _stone_fill_bool}},
color .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_fill_color_tl}{##1}},
color .initial:n = {gray},
opacity .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_fill_opacity_fp}{##1}},
opacity .initial:n = {1}
}
\bool_new:c {l_pgfgo_players_ #1 _stone_shadow_bool}
\fp_new:c {l_pgfgo_players_ #1 _stone_shadow_angle_fp}
\dim_new:c {l_pgfgo_players_ #1 _stone_shadow_offset_dim}
\fp_new:c {l_pgfgo_players_ #1 _stone_shadow_opacity_fp}
\tl_new:c {l_pgfgo_players_ #1 _stone_shadow_color_tl}
\fp_new:c {l_pgfgo_players_ #1 _stone_shadow_scale_fp}
\tl_new:c {l_pgfgo_players_ #1 _stone_shadow_image_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_shadow_image_width_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_shadow_image_rotate_tl}
\bool_new:c {l_pgfgo_players_ #1 _stone_shadow_image_silhouette_bool}
%LA SOMBRA, DEBAJO DE LA PIEDRA: SU SILUETA (EL CIRCULO O LA FORMA DE stone/image) O LA IMAGEN image,
%CORRIDA offset HACIA angle Y AGRANDADA scale.
\keys_define:nn { pgfgo / players / #1 / stone / shadow } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _stone_shadow_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _stone_shadow_bool}},
angle .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_shadow_angle_fp}{##1}},
angle .initial:n = {0},
offset .code:n = {\dim_set:cn {l_pgfgo_players_ #1 _stone_shadow_offset_dim}{##1}},
offset .initial:n = {1pt},
opacity .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_shadow_opacity_fp}{##1}},
opacity .initial:n = {0.5},
color .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shadow_color_tl}{##1}},
color .initial:n = {black},
scale .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_shadow_scale_fp}{##1}},
scale .initial:n = {1},
image .code:n = {\keys_set:nn { pgfgo / players / #1 / stone / shadow / image } {##1}},
}
%SIN width, EL DIAMETRO DE LA PIEDRA. rotate: UN ANGULO, EL MISMO EN TODAS LAS PIEDRAS. CON silhouette,
%SOLO LA FORMA DE LA IMAGEN, DEL COLOR color.
\keys_define:nn { pgfgo / players / #1 / stone / shadow / image } {
file .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shadow_image_tl}{##1}},
width .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shadow_image_width_tl}{##1}},
rotate .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shadow_image_rotate_tl}{##1}},
silhouette .bool_set:c = {l_pgfgo_players_ #1 _stone_shadow_image_silhouette_bool},
false .code:n = {\tl_clear:c {l_pgfgo_players_ #1 _stone_shadow_image_tl}},
}
%EL BRILLO, ENCIMA DE LA PIEDRA (CIRCULO O IMAGEN). NO GIRA CON stone/image/rotate. CON image, UNA IMAGEN
%CENTRADA EN LA PIEDRA EN LUGAR DEL BRILLO DIBUJADO.
\bool_new:c {l_pgfgo_players_ #1 _stone_shine_bool}
\fp_new:c {l_pgfgo_players_ #1 _stone_shine_angle_fp}
\fp_new:c {l_pgfgo_players_ #1 _stone_shine_opacity_fp}
\tl_new:c {l_pgfgo_players_ #1 _stone_shine_color_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_shine_image_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_shine_image_width_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_shine_image_rotate_tl}
\bool_new:c {l_pgfgo_players_ #1 _stone_shine_image_silhouette_bool}
\keys_define:nn { pgfgo / players / #1 / stone / shine } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _stone_shine_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _stone_shine_bool}},
angle .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_shine_angle_fp}{##1}},
angle .initial:n = {0},
opacity .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _stone_shine_opacity_fp}{##1}},
opacity .initial:n = {1},
color .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shine_color_tl}{##1}},
color .initial:n = {gray!50!white},
image .code:n = {\keys_set:nn { pgfgo / players / #1 / stone / shine / image } {##1}},
}
%SIN width, EL DIAMETRO DE LA PIEDRA. rotate: UN ANGULO, EL MISMO EN TODAS LAS PIEDRAS. CON silhouette,
%SOLO LA FORMA DE LA IMAGEN, DEL COLOR color.
\keys_define:nn { pgfgo / players / #1 / stone / shine / image } {
file .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shine_image_tl}{##1}},
width .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shine_image_width_tl}{##1}},
rotate .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_shine_image_rotate_tl}{##1}},
silhouette .bool_set:c = {l_pgfgo_players_ #1 _stone_shine_image_silhouette_bool},
false .code:n = {\tl_clear:c {l_pgfgo_players_ #1 _stone_shine_image_tl}},
}
%IMAGEN EN LUGAR DEL CIRCULO. CON VARIOS ARCHIVOS, CADA PUNTO USA SIEMPRE EL MISMO (VER pgf-go-stones.sty).
%SIN width, EL DIAMETRO DE LA PIEDRA. rotate: UN ANGULO, random O : (UN ANGULO POR PUNTO, SIEMPRE EL MISMO).
\seq_new:c {l_pgfgo_players_ #1 _stone_image_seq}
\tl_new:c {l_pgfgo_players_ #1 _stone_image_width_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_image_rotate_tl}
\tl_new:c {l_pgfgo_players_ #1 _stone_image_opacity_tl}
\keys_define:nn { pgfgo / players / #1 / stone / image } {
file .code:n = {\seq_set_from_clist:cn {l_pgfgo_players_ #1 _stone_image_seq}{##1}},
width .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_image_width_tl}{##1}},
rotate .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_image_rotate_tl}{##1}},
opacity .code:n = {\tl_set:cn {l_pgfgo_players_ #1 _stone_image_opacity_tl}{##1}},
opacity .initial:n = {1},
false .code:n = {\seq_clear:c {l_pgfgo_players_ #1 _stone_image_seq}},
}
%--------------------------------------------------------------------------------------------
%MOVE
\keys_define:nn { pgfgo / players / #1 / move } {
label .code:n = {\keys_set:nn { pgfgo / players / #1 / move / label } {##1}},
label .groups:n = {label},
from .groups:n = {external},
black .groups:n = {external},
b .groups:n = {external},
white .groups:n = {external},
w .groups:n = {external},
forget .groups:n = {external},
%NO ES DE UN JUGADOR: VALE PARA TODAS LAS JUGADAS (VER pgfgo/move/numbers).
numbers .code:n = {\keys_set:nn { pgfgo / move } {numbers = ##1}},
numbers .default:n = {true},
numbers .groups:n = {external},
%EL ESTILO DE LA PIEDRA Y LA MARCA DE \moves (LOS PONE pgfgo/players//stone).
line .groups:n = {external},
fill .groups:n = {external},
radius .groups:n = {external},
scale .groups:n = {external},
shadow .groups:n = {external},
shine .groups:n = {external},
image .groups:n = {external},
prisoner .groups:n = {external},
mark .groups:n = {external},
}
%font~size VACIO: EL TAMANO SE AJUSTA SOLO SEGUN LA CANTIDAD DE CARACTERES DE LA ETIQUETA.
\tl_new:c {l_pgfgo_players_ #1 _move_label_font_tl}
\tl_new:c {l_pgfgo_players_ #1 _move_label_font_size_tl}
\tl_new:c {l_pgfgo_players_ #1 _move_label_color_tl}
\tl_new:c {l_pgfgo_players_ #1 _move_label_opacity_tl}
\keys_define:nn { pgfgo / players / #1 / move / label } {
font .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _move_label_font_tl}{##1}},
font .initial:n = {\bfseries},
font~size .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _move_label_font_size_tl}{##1}},
color .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _move_label_color_tl}{##1}},
color .initial:n = {black},
opacity .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _move_label_opacity_tl}{##1}},
opacity .initial:n = {1},
forget .code:n = {\bool_set_false:N \l_pgfgo_goban_remember_move_label_bool},
format .choices:nn = {arabic, alph, Alph, roman, Roman, kanji}
{\cs_set_eq:cc {pgfgo_players_ #1 _move_label_format:n} {\__pgfgo_players_format_cs:V \l_keys_choice_tl}},
format .initial:n = {arabic},
}
%--------------------------------------------------------------------------------------------
%MARK
\fp_new:c {l_pgfgo_players_ #1 _mark_scale_fp}
\keys_define:nn { pgfgo / players / #1 / mark } {
line .code:n = {\keys_set:nn { pgfgo / players / #1 / mark / line } {##1}},
fill .code:n = {\keys_set:nn { pgfgo / players / #1 / mark / fill } {##1}},
fill .default:n = {true},
label .code:n = {\keys_set:nn { pgfgo / players / #1 / mark / label } {##1}},
sequence .code:n = {\keys_set:nn { pgfgo / players / #1 / mark / sequence } {##1}},
sequence .default:n = {from = 1},
sequence .groups:n = {sequence},
%EL TAMANO DE LA MARCA, RESPECTO DEL DE SIEMPRE.
scale .code:n = {\fp_set:cn {l_pgfgo_players_ #1 _mark_scale_fp} {##1}},
scale .initial:n = {1},
%EL RESTO (FORMAS, custom, JUGADOR, ...) VA A /pgfgo/mark.
unknown .code:n = {
\__pgfgo_players_mark_other:ne {#1}
{\l_keys_key_str \tl_if_empty:nF {##1} {= {\exp_not:n {##1}}}}
}
}
\tl_new:c {l_pgfgo_players_ #1 _mark_line_color_tl}
\dim_new:c {l_pgfgo_players_ #1 _mark_line_width_dim}
\tl_new:c {l_pgfgo_players_ #1 _mark_line_opacity_tl}
\keys_define:nn { pgfgo / players / #1 / mark / line } {
color .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_line_color_tl}{##1}},
color .initial:n = {black},
width .code:n = {\dim_set:cn{l_pgfgo_players_ #1 _mark_line_width_dim}{##1}},
width .initial:n = {1pt},
opacity .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_line_opacity_tl}{##1}},
opacity .initial:n = {1},
}
%LAS MARCAS RELLENAS (filled~square, filled~circle, hatched~lines) Y EL COLOR pgfgomarkfill DE LAS
%MARCAS PROPIAS. CON false, LAS MARCAS RELLENAS NO SE VEN.
\bool_new:c {l_pgfgo_players_ #1 _mark_fill_bool}
\bool_set_true:c {l_pgfgo_players_ #1 _mark_fill_bool}
\tl_new:c {l_pgfgo_players_ #1 _mark_fill_color_tl}
\tl_new:c {l_pgfgo_players_ #1 _mark_fill_opacity_tl}
\keys_define:nn { pgfgo / players / #1 / mark / fill } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _mark_fill_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _mark_fill_bool}},
color .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_fill_color_tl}{##1}},
color .initial:n = {gray},
opacity .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_fill_opacity_tl}{##1}},
opacity .initial:n = {1},
}
\tl_new:c {l_pgfgo_players_ #1 _mark_label_color_tl}
\tl_new:c {l_pgfgo_players_ #1 _mark_label_font_tl}
\tl_new:c {l_pgfgo_players_ #1 _mark_label_font_size_tl}
\keys_define:nn { pgfgo / players / #1 / mark / label } {
color .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_label_color_tl}{##1}},
color .initial:n = {black},
font .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_label_font_tl}{##1}},
%VACIO: EL TAMANO SE AJUSTA SOLO SEGUN LA CANTIDAD DE CARACTERES.
font~size .code:n = {\tl_set:cn{l_pgfgo_players_ #1 _mark_label_font_size_tl}{##1}},
format .choices:nn = {arabic, alph, Alph, roman, Roman, kanji}
{\cs_set_eq:cc {pgfgo_players_ #1 _mark_sequence_format:n} {\__pgfgo_players_format_cs:V \l_keys_choice_tl}},
format .initial:n = {arabic},
}
\bool_new:c {l_pgfgo_players_ #1 _mark_sequence_bool}
\int_new:c {l_pgfgo_ #1 _mark_sequence_from_int}
\int_set:cn {l_pgfgo_ #1 _mark_sequence_from_int} {1}
\keys_define:nn { pgfgo / players / #1 / mark / sequence } {
true .code:n = {\bool_set_true:c {l_pgfgo_players_ #1 _mark_sequence_bool}},
false .code:n = {\bool_set_false:c {l_pgfgo_players_ #1 _mark_sequence_bool}},
%ALIAS DOCUMENTADO DE mark/label/format
format .code:n = {
\bool_set_true:c {l_pgfgo_players_ #1 _mark_sequence_bool}
\keys_set:nn { pgfgo / players / #1 / mark / label } {format = ##1}
},
from .code:n = {
\bool_set_true:c {l_pgfgo_players_ #1 _mark_sequence_bool}
\int_set:cn {l_pgfgo_ #1 _mark_sequence_from_int} {##1}
},
}
%LA FUNCION QUE COPIA LAS VARIABLES DEL JUGADOR EN LAS DEL JUGADOR ACTUAL.
\cs_new_protected:cpe {__pgfgo_players_get_ #1 :}
{\__pgfgo_players_fields:n {\__pgfgo_players_get_field:nnnn {#1}}}
}
%LOS JUGADORES REALES. TODO SE ASIGNA ACA
\pgfgonewplayers{neutral, black, white}
\pgfgocopyplayers{neutral}{black}{white}
\ExplSyntaxOff