From 03b4be96aeee93ca25a1578557e4618981420b99 Mon Sep 17 00:00:00 2001 From: "Trevor L. Davis" Date: Wed, 12 Mar 2025 19:18:31 -0700 Subject: [PATCH 1/3] fix: Expand drawing range for matchsticks (if necessary) * `cat_piece()` and `str_piece()` now expand the drawing range for longer (piecepack) matchsticks if necessary (#14). closes #14 --- DESCRIPTION | 2 +- NEWS.md | 3 +++ R/range.r | 20 ++++++++++++++++++++ R/str_piece.r | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 94a7398..374a354 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -2,7 +2,7 @@ Encoding: UTF-8 Package: ppcli Type: Package Title: Plaintext Board Game Visualizations -Version: 0.2.0-2 +Version: 0.2.0-3 Authors@R: c(person("Trevor L.", "Davis", role=c("aut", "cre"), email="trevor.l.davis@gmail.com", comment = c(ORCID = "0000-0001-6341-4639"))) diff --git a/NEWS.md b/NEWS.md index 99d6f06..764d690 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,9 @@ ppcli 0.2.0 (development) * `cat_piece()` and `str_piece()` gain arguments `xbreaks` and `ybreaks` to provide a subset (of integers) to provide axis labels for if `annotate` is `TRUE` (#17). +* `cat_piece()` and `str_piece()` now expand the drawing range for longer + (piecepack) matchsticks if necessary (#14). + ppcli 0.1.1 =========== diff --git a/R/range.r b/R/range.r index dbe83ff..f51267d 100644 --- a/R/range.r +++ b/R/range.r @@ -37,5 +37,25 @@ range_heuristic <- function(df) { ybot <- ifelse(is_board2, df$y-df$rank, ybot) ytop <- ifelse(is_board2, df$y+df$rank, ytop) + # matchsticks + m_offset <- pmax(floor(df$rank / 2) - 1, 0) / 2 # 1:6 -> 0, 0, 0, 0.5, 0.5, 1 + is_matchsticks_horizontal <- grepl("matchstick", df$piece_side) & + (df$angle == 90 | df$angle == 270) + xleft <- ifelse(is_matchsticks_horizontal, df$x - m_offset, xleft) + xright <- ifelse(is_matchsticks_horizontal, df$x + m_offset, xright) + + is_matchsticks_vertical <- grepl("matchstick", df$piece_side) & + (df$angle == 0 | df$angle == 180) + ybot <- ifelse(is_matchsticks_vertical, df$y - m_offset, ybot) + ytop <- ifelse(is_matchsticks_vertical, df$y + m_offset, ytop) + + m_offset_d <- floor(df$rank / 4) # 1:6 -> 0, 0, 0, 1, 1, 1 + is_matchsticks_diagonal <- grepl("matchstick", df$piece_side) & + !is_matchsticks_horizontal & !is_matchsticks_vertical + xleft <- ifelse(is_matchsticks_diagonal, df$x - m_offset_d, xleft) + xright <- ifelse(is_matchsticks_diagonal, df$x + m_offset_d, xright) + ybot <- ifelse(is_matchsticks_diagonal, df$y - m_offset_d, ybot) + ytop <- ifelse(is_matchsticks_diagonal, df$y + m_offset_d, ytop) + list(xmin = min(xleft), xmax = max(xright), ymin = min(ybot), ymax = max(ytop)) } diff --git a/R/str_piece.r b/R/str_piece.r index 5c675ea..d8b120f 100644 --- a/R/str_piece.r +++ b/R/str_piece.r @@ -521,6 +521,7 @@ add_matchstick_face4 <- function(cm, x, y, angle, fg) { cm } add_matchstick_face5 <- add_matchstick_face4 + add_matchstick_face6 <- function(cm, x, y, angle, fg) { if (angle %in% c(0, 180)) { cm$char[y+-2:2, x] <- "\u2503" From 937442f97e307d982a2cef28eaae97aaae768c2b Mon Sep 17 00:00:00 2001 From: "Trevor L. Davis" Date: Wed, 12 Mar 2025 21:14:12 -0700 Subject: [PATCH 2/3] chore: Add some {pkgdown} CSS styling for better fonts --- .Rbuildignore | 1 + pkgdown/extra.css | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 pkgdown/extra.css diff --git a/.Rbuildignore b/.Rbuildignore index fbebd2a..4abca8d 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -7,6 +7,7 @@ noto.style rule_ideas.rst html others +^pkgdown$ raw-data tmp .*.epub diff --git a/pkgdown/extra.css b/pkgdown/extra.css new file mode 100644 index 0000000..0c92419 --- /dev/null +++ b/pkgdown/extra.css @@ -0,0 +1,5 @@ +pre { + font-family: Dejavu Sans Mono,FreeMono,monospace; + line-height: 1.0; + font-size: 100%; +} From d13d7009a95e7ae58d6f9260522bc7ab12ba02f6 Mon Sep 17 00:00:00 2001 From: "Trevor L. Davis" Date: Wed, 12 Mar 2025 21:14:56 -0700 Subject: [PATCH 3/3] fix(str_piece()): Have `NULL` `color` fall back to `FALSE` * `str_piece()`'s `color` argument if `NULL` now falls back to `FALSE` (instead of throwing an error). * Also add basic man page examples. closes #10 --- NEWS.md | 17 +++++++++++++---- R/cat_piece.r | 14 ++++++++++++++ R/str_piece.r | 16 ++++++++++++++++ man/cat_piece.Rd | 15 +++++++++++++++ man/str_piece.Rd | 16 ++++++++++++++++ 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 764d690..5bc48af 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,9 @@ ppcli 0.2.0 (development) ========================= +New features +------------ + * `cat_piece()` and `str_piece()` adds support for the following game pieces (#4): + "alquerque" bit and board pieces. @@ -8,21 +11,27 @@ ppcli 0.2.0 (development) - However we currently do not distinguish between the nine marble bit ranks. -* "white" `go` and `checkers` bits should now render the same - whether `piece_side` is `"bit_back"` or `"bit_face"`. - * `cat_piece()` and `str_piece()` gain arguments `xbreaks` and `ybreaks` to provide a subset (of integers) to provide axis labels for if `annotate` is `TRUE` (#17). +Bug fixes and minor improvements +-------------------------------- + +* "white" `go` and `checkers` bits should now render the same + whether `piece_side` is `"bit_back"` or `"bit_face"`. + * `cat_piece()` and `str_piece()` now expand the drawing range for longer (piecepack) matchsticks if necessary (#14). +* `str_piece()`'s `color` argument if `NULL` now falls back to `FALSE` + (instead of throwing an error). + ppcli 0.1.1 =========== * ``cat_piece()`` prints out Unicode plaintext boardgame diagrams. - + It supports the same data frame arguments also supported by + + It supports the same data frame arguments also supported by ``piecepackr::pmap_piece()`` / ``piecepackr::render_piece()`` as well as the board game setup functions in `{ppdf}`. + It is an extraction and refinement of ``ppgames::cat_piece()``. diff --git a/R/cat_piece.r b/R/cat_piece.r index bc0200c..bdc59e1 100644 --- a/R/cat_piece.r +++ b/R/cat_piece.r @@ -12,6 +12,20 @@ #' @return String of text diagram (returned invisibly). #' As a side effect prints out the text diagram using [cat()]. #' @seealso [str_piece()] for just the character vector. See for more information about the \dQuote{Game Bit} family of fonts. +#' @examples +#' dfb <- data.frame(piece_side = "board_face", x= 3, y = 3, suit = 3) +#' dfsw <- data.frame(piece_side = "bit_back", +#' x = c(1:5, 1:5, 4:5), +#' y = rep.int(1:3, c(5L, 5L, 2L)), +#' suit = 6L) +#' dfsb <- data.frame(piece_side = "bit_back", +#' x = c(1:5, 1:5, 1:2), +#' y = rep.int(5:3, c(5L, 5L, 2L)), +#' suit = 2L) +#' df <- rbind(dfb, dfsw, dfsb) +#' df$cfg <- "alquerque" +#' cat_piece(df) +#' cat_piece(df, annotate = TRUE) #' @export cat_piece <- function(df, color = NULL, reorient = "none", annotate = FALSE, ..., file = "", annotation_scale = NULL, diff --git a/R/str_piece.r b/R/str_piece.r index d8b120f..97b8b59 100644 --- a/R/str_piece.r +++ b/R/str_piece.r @@ -29,6 +29,21 @@ #' @return Character vector for text diagram. #' @seealso [cat_piece()] for printing to the terminal. #' See for more information about the \dQuote{Game Bit} family of fonts. +#' @examples +#' dfb <- data.frame(piece_side = "board_face", x= 3, y = 3, suit = 3) +#' dfsw <- data.frame(piece_side = "bit_back", +#' x = c(1:5, 1:5, 4:5), +#' y = rep.int(1:3, c(5L, 5L, 2L)), +#' suit = 6L) +#' dfsb <- data.frame(piece_side = "bit_back", +#' x = c(1:5, 1:5, 1:2), +#' y = rep.int(5:3, c(5L, 5L, 2L)), +#' suit = 2L) +#' df <- rbind(dfb, dfsw, dfsb) +#' df$cfg <- "alquerque" +#' s <- str_piece(df) +#' is.character(s) +#' cat(s, sep = "\n") #' @export str_piece <- function(df, color = NULL, reorient = "none", annotate = FALSE, ..., annotation_scale = NULL, @@ -43,6 +58,7 @@ str_piece_helper <- function(df, color = NULL, reorient = "none", annotate = FAL annotation_scale = NULL, style = "Unicode", xbreaks = NULL, ybreaks = NULL) { annotation_scale <- annotation_scale %||% attr(df, "scale_factor") %||% 1 + color <- color %||% FALSE if (nrow(df) == 0) { return(character(0)) } diff --git a/man/cat_piece.Rd b/man/cat_piece.Rd index e69c920..747be72 100644 --- a/man/cat_piece.Rd +++ b/man/cat_piece.Rd @@ -63,6 +63,21 @@ outputs them using \code{base::cat()}. \code{cat_move()} generates a plaintext diagram for a move within a game. \code{cat_game()} renders an animation of a game in the terminal. } +\examples{ +dfb <- data.frame(piece_side = "board_face", x= 3, y = 3, suit = 3) +dfsw <- data.frame(piece_side = "bit_back", + x = c(1:5, 1:5, 4:5), + y = rep.int(1:3, c(5L, 5L, 2L)), + suit = 6L) +dfsb <- data.frame(piece_side = "bit_back", + x = c(1:5, 1:5, 1:2), + y = rep.int(5:3, c(5L, 5L, 2L)), + suit = 2L) +df <- rbind(dfb, dfsw, dfsb) +df$cfg <- "alquerque" +cat_piece(df) +cat_piece(df, annotate = TRUE) +} \seealso{ \code{\link[=str_piece]{str_piece()}} for just the character vector. See \url{https://github.com/trevorld/game-bit-font} for more information about the \dQuote{Game Bit} family of fonts. } diff --git a/man/str_piece.Rd b/man/str_piece.Rd index 05aa673..352fe06 100644 --- a/man/str_piece.Rd +++ b/man/str_piece.Rd @@ -55,6 +55,22 @@ Character vector for text diagram. \description{ \code{str_piece()} generates plaintext piecepack diagrams. } +\examples{ +dfb <- data.frame(piece_side = "board_face", x= 3, y = 3, suit = 3) +dfsw <- data.frame(piece_side = "bit_back", + x = c(1:5, 1:5, 4:5), + y = rep.int(1:3, c(5L, 5L, 2L)), + suit = 6L) +dfsb <- data.frame(piece_side = "bit_back", + x = c(1:5, 1:5, 1:2), + y = rep.int(5:3, c(5L, 5L, 2L)), + suit = 2L) +df <- rbind(dfb, dfsw, dfsb) +df$cfg <- "alquerque" +s <- str_piece(df) +is.character(s) +cat(s, sep = "\n") +} \seealso{ \code{\link[=cat_piece]{cat_piece()}} for printing to the terminal. See \url{https://github.com/trevorld/game-bit-font} for more information about the \dQuote{Game Bit} family of fonts.