logicpuzzle.sty
Roll out your own grid-based logic puzzle
As an example we take a look at the package bokkusu.sty
. First, we ignore the LPPL license stuff.
1 2 |
\ProvidesPackage{bokkusu}[2013/03/25 bokkusu.sty v1.2 - Josef Kleber (C) 2013]% \RequirePackage{logicpuzzle}% |
We wrote a package with version number v1.2 and date 2013/03/25 and added a copyright remark. We need to load the code base package logicpuzzle.sty
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
\newcommand*\LP@BK@init@prefix{LP@BK}% \newcommand*\LP@BK@init@package{bokkusu}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{rows}{5}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{columns}{5}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{scale}{1}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{counterstyle}{none}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{color}{black}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{bgcolor}{}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{width}{6.7cm}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{cvoffset}{-38pt}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{title}{}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{titleindent}{0.75cm}% \LP@define@key{\LP@BK@init@prefix}{\LP@BK@init@package}{titlewidth}{5.85cm}% \LP@define@choicekey@fontsize{\LP@BK@init@prefix}{\LP@BK@init@package}{Large}% \ExecuteOptionsX{rows,columns,width,fontsize,scale,color,bgcolor,cvoffset,counterstyle,title,titleindent,titlewidth}% \ProcessOptionsX\relax% \LP@init@counter{\LP@BK@init@prefix}% |
We save the package prefix and name in a macro for easy change. Then we define the options for package bokkusu.sty
and the environment bokkusu
, which are executed afterwards to create the macros for the option values. In the end, we need to initialize the package counters.
1 2 3 4 |
\let\valueH\LP@bottomrow% \let\valueV\LP@leftcolumn% \let\sumH\LP@toprow% \let\sumV\LP@rightcolumn% |
We need numbers around the grid. Therefore, we define some aliases for the existing generic commands.
1 2 3 4 |
\newcommand*\bokkususetup[1]% {% \setkeys{bokkusu.sty}{#1}% }% |
We define \bokkususetup
for resetting the global package options.
Finally, we define the environment bokkusu
.
1 2 3 4 5 6 7 8 9 |
\newenvironment{bokkusu}[1][]% {% \setkeys{bokkusu}{#1}% \LP@set@package{bokkusu}% \LP@set@env@prefix{LP@BK}% \setcounter{LP@BK@rows}{\LP@BK@rows}% \setcounter{LP@BK@columns}{\LP@BK@columns}% \stepcounter{LP@BK@rows}% \stepcounter{LP@BK@columns}% |
We locally set the environment options and the prefix and name of the current puzzle environment. We need to reset the counters for rows
and columns
, as they might have been altered.
1 2 3 4 5 6 7 8 9 |
\begin{minipage}[t]{\LP@BK@width}% \ifthenelse{\equal{\LP@BK@title}{}}% {\par\enspace\par}% empty {\enspace\par\noindent\hspace{\LP@BK@titleindent}\parbox{\LP@BK@titlewidth} {\strut\LP@titleformat\LP@BK@title}\vspace{3mm}\par}% \begin{tikzpicture}[scale=\LP@BK@scale]% \LP@drawbackground{1}{1}{\LP@BK@columns}{\LP@BK@rows}{\LP@BK@bgcolor}% \LP@drawgrid{1}{1}{\LP@BK@columns}{\LP@BK@rows}{1cm}% }% |
We start a minipage with width
. If the user defined a title
, we typeset the title
and add a vertical space. Then, we draw the puzzle with the help of tikz.sty
. We start drawing the background and the grid.
1 2 3 4 5 6 |
{% \end{tikzpicture}% \LP@drawcounter{\LP@BK@counterstyle}% \stepcounter{LP@puzzlecounter}% \end{minipage}% }% |
Finally, we just end the picture for the puzzle. We draw and step the counter. As last action, we need to close the environment minipage
. That’s it. Easy, isn’t it? You just need to copy this skelton and change or add some code for your specific puzzle.
The code
PGF layers
The package defines the following PGF layers: LPdump
, LPbgcolor
, LPbackgroundtwo
, LPbackground
, LPforeground
and LPforegroundtwo
Without specifying a special layer, the standard main
layer is used. The LPbackground
and LPforeground
layers can be accessed with the puzzlebackground
and puzzleforeground
environments. The LPbgcolor
is and should only be used for the background color of the grid.
All layers can also be accessed with the generic PGF method:
1 2 3 |
\begin{pgfonlayer}{layer} ... \end{pgfonlayer}{layer} |
Order: LPdump
-> LPbgcolor
-> LPbackgroundtwo
-> LPbackground
-> main
-> LPforeground
-> LPforegroundtwo
So, if you are in the need to place something behind LPbackground
or in front of LPforeground
, you can use the LPbackgroundtwo
and LPforegroundtwo
layers. You can hide elements like help nodes behind the background color on the LPdump
layer.
Environments
puzzlebackground
1 2 3 |
\begin{puzzlebackground} ... \end{puzzlebackground} |
The environment puzzlebackground
allows you to place elements behind the main
layer on the LPbackground
layer. This is for example usefull for the fillarea
command.
puzzleforeground
1 2 3 |
\begin{puzzleforeground} ... \end{puzzleforeground} |
The environment puzzleforeground
allows you to place elements in front of the main
layer on the LPforeground
layer. This is for example usefull for the framearea
command.
Commands
Initialization
\LP@definekey
1 |
\LP@define@key{prefix}{package}{option}{default} |
With the LP@define@key
command, you can define the options of the package package
and of the environment package
. A prefix
is needed for creating different name spaces.
1 |
\LP@define@key{LP@BS}{battleship}{rows}{5} |
This code snippet defines the option rows
as global option for battleship.sty
and as local option for environment battleship
with the default value 5. This value is stored in \LP@BS@rows
.
\LP@define@choicekey@fontsize
1 |
\LP@define@choicekey@fontsize{prefix}{package}{default} |
With the \LP@define@choicekey@fontsize
command, you can define the choice key option fontsize
of the package package
and of the environment package
. Possible keys are: tiny, scriptsize, footnotesize, small, normalsize, large, Large, LARGE, huge, Huge
\LP@init@counter
1 |
\LP@init@counter{prefix} |
The command \LP@init@counter
defines the counters prefix@rows
and prefix@columns
, initialize them with \prefix@rows
and \prefix@columns
and steps the counters.
Drawing grids
\LP@drawgrid
1 |
\LP@drawgrid{xmin}{ymin}{xmax}{ymax}{step} |
With the \LP@drawgrid
command, you can draw the grid (xmin
,ymin
) to (xmax
,ymax
) with step step
. For drawing the standard puzzle grid the step must be 1cm.
\LP@drawsudokugrid
1 |
\LP@drawsudokugrid |
The command \LP@drawsudokugrid
draws the stnadard Sudoku grid, but just the thicker lines. You will have to overlay the standard grid to get a full Sudoku grid.
\LP@drawbackground
With the \LP@drawbackground
command, you can draw the background color of the grid.
In the grid
\setcell
1 |
\setcell{column}{row}{element} |
With the \setcell
command, you can set element
into cell column
as central node. It is aware of the current values of the surrounding environment options row
rows
, columns
, scale
and fontsize
. Furthermore, a check if element
is within the grid is applied.
\LP@setcellcontent
1 |
\LP@setcellcontent{column}{row}{element} |
The command \LP@setcellcontent
is the generic command to set an arbitrary element
.
\setrow
1 |
\setrow{row}{csv list} |
With the \setrow
command, you can set the contents of a row
. These may be numbers or letters.
\LP@setrowcontents
1 |
\LP@setrowcontents{csv list}{column}{row} |
The command \LP@setrowcontents
is the generic command to set row contents. It does not necessarily start with 1!
\setcolorrow
1 |
\setcolorrow{row}{csv list} |
With the \setcolorrow
command, you can set the contents of a row
. Furthermore, the background of the cell is filled with color LP@c@romannumber
. With the number 0, you can black out the grid cell.
\setcolumn
1 |
\setcolumn{column}{csv list} |
With the \setcolumn
command, you can set the contents of a column
. These may be numbers or letters.
\LP@setcolumncontents
1 |
\LP@setcolumncontents{csv list}{column}{row} |
The command \LP@setcolumncontents
is the generic command to set column contents. It does not necessarily start with 1!
\setcolorcolumn
1 |
\setcolorcolumn{column}{csv list} |
With the \setcolorcolumn
command, you can set the contents of a column
. Furthermore, the background of the cell is filled with color LP@c@romannumber
.
\setrule
1 |
\setrule{column}{row}{csv list} |
With the \setrule
command, you can you can set a calculation rule rule
into the top left corner of cell column
row
. The rule is typeset in inline math mode. You might consider using the \times
and \div
commands.
\fillcell
1 |
\fillcell{column}{row} |
With the \fillcell
command, you can fill cell column
with the color defined with environment option row
color
. It is aware of the current values of the surrounding envionment options rows
, columns
, scale
and color
. Furthermore, a check if the cell is within the grid is applied.
\fillrow
1 |
\fillrow{row}{csv list} |
With the \fillrow
command, you can fill a row
. In csv list
’1’ means ’fill’ and ’0’ means ’don’t fill’. Internally, \fillrow
uses \fillcell
.
\fillcolumn
1 |
\fillcolumn{column}{csv list} |
With the \fillcolumn
command, you can fill a column
. In csv list
’1’ means ’fill’ and ’0’ means ’don’t fill’. Internally, \fillcolumn
uses \fillcell
.
\filldiagonals
1 |
\filldiagonals[color] |
With the filldiagonals
command, you can fill the diagonals with the color specified with the optional argument color
(default: yellow!20). Furthermore, it checks for a quadratic grid, otherwise an error message is issued.
\framearea
1 |
\framearea{color}{tikz path} |
The \framearea
command frames the area given by tikz path
with color color
. The reference for coordinates is the bottom left corner of the cell.
1 |
\framearea{green}{(2,2)--(2,3)--(3,3)--(3,2)--(2,2)} |
This command will color the frame of the grid cell (2,2)
green. You should consider using this command in the puzzleforeground
environment.
\fillarea
1 |
\fillarea{color}{tikz path} |
The \fillarea
command fills the area given by tikz path
with color color
. The reference for coordinates is the bottom left corner of the cell. You should consider using this command in the puzzlebackground
environment.
\colorarea
1 |
\colorarea{color}{tikz path} |
The \colorarea
command fills the area given by tikz path
with color color
– just like \framearea
without frame.
\framepuzzle
1 |
\framepuzzle[color] |
With the \framepuzzle
command, you can frame the grid (thicker line) with the color specified with the optional argument color
(default: black).
\tikzpath
1 |
\tikzpath{coumn}{row}{csv list} |
With the \tikzpath
command, you can easily construct a \tikz
path. You just need to define a starting point column
row
(bottom left corner) and a csv list
with direction indicators relative to the current position..
7: | up left | 8: | up | 9: | up right |
4: | left | 5: | – | 6: | right |
1: | down left | 2: | down | 3: | down right |
1 |
\framearea{green}{\tikzpath{2}{2}{8,6,2,4}} |
This command will frame grid cell (2,2)
green.
\LP@ingrid
1 |
\LP@ingrid{column}{row}{max column}{max row}{package} |
With the \LP@ingrid
command, you can check if an element – that should be placed – is within the grid. Otherwise an error message is issued.
\LP@definecolor
1 |
\LP@definecolor{name}{rgb color} |
With the \LP@definecolor
command, you can define named rgb colors, especially for defining background colors of numbers used in \setcolorrow
and \setcolorcolumn
.
The background color names follow the pattern: LP@c@romannumber
1 |
\LP@definecolor{LP@c@iv}{.55,1,.88} |
This command will define the new background color of number 4!
Around the grid
\LP@leftcolumn
1 |
\LP@leftcolumn{csv list} |
With the \LP@leftcolumn
command, you can set the contents of the column left to the grid. The skyline.sty
package uses for example:
1 |
\let\skylineL\LP@leftcolumn |
\LP@rightcolumn
1 |
\LP@rightcolumn{csv list} |
With the \LP@rightcolumn
command, you can set the contents of the column right to the grid.
\LP@toprow
1 |
\LP@toprow{csv list} |
With the \LP@toprow
command, you can set the contents of the row above the grid.
\LP@bottomrow
1 |
\LP@bottomrow{csv list} |
With the \LP@bottomrow
command, you can set the contents of the row below the grid.
Presentation
\titleformat
1 |
\titleformat{format} |
With the \titleformat
command, you can define the format
of the title. By default, the definition is as follows:
1 |
\titleformat{\centering\Large\color{blue}} |
\puzzlecounter
1 |
\puzzlecounter |
The \puzzlecounter
command provides the counter in textual form to use it for example in \definecounterstyle
.
\setpuzzlecounter
1 |
\setpuzzlecounter{number} |
With the \setpuzzlecounter
command , you can reset the puzzle counter, for example before the solutions.
\definecounterstyle
The command allows you to define your own styles. For example, the style left
is defined as follows:
1 2 3 4 5 6 |
\definecounterstyle{left}{ \begingroup\reversemarginpar\marginnote{ \tikz\node[shape=rectangle,fill=yellow!40,inner sep=7pt, draw,rounded corners=3pt,thick] {\Huge\puzzlecounter};}[\LP@cvoffset]\endgroup} } |
To typeset the counter into the margin we use the command \marginnote
. We need to use the command \reversemarginpar
to set the counter into the left margin. Of course, we must use this command in a group for local scope. Finally we use \puzzlecounter
in a \tikz
node with a vertical offset set with the option cvoffset
.
\LP@drawcounter
1 |
\LP@drawcounter{name} |
The \LP@drawcounter
command draws the counter with counter style name
.
Examples
You can download application examples and their solutions from the project page. The puzzles are originally licensed under .