数独网格的个性化

数独网格的个性化

有人可以给我一些提示以实现以下两项改进吗?

  1. 简单的:我想显示每列和每行的数字位置。这需要在网格的左侧和上方显示数字。

    Sašo Živanović 的回答完成了这个简单部分的工作。

  2. 难的:有时我只需要显示数独的一个矩形部分。要实现这一点需要做哪些更改?

代码

\documentclass{article}
    \usepackage{tikz}
    \usetikzlibrary{backgrounds,shapes}
    \usepackage{graphicx}
    \usepackage{xstring}

% Some customizable styles
    \tikzset {
        highlight/.style = {
            yellow,
            opacity = 0.3
        },
        digit/.style = {
            minimum height = 5mm,
            minimum width = 5mm,
            anchor = center
        },
        circle/.style = {
            draw = green!80!black,
            dotted,
            very thick
        },
        circle number/.style = {
            draw = #1,
            very thick
        },
        cross/.style = {
            red,
            opacity = .5,
            shorten >= 1mm,
            shorten <= 1mm,
            very thick,
            line cap = round
        },
        hint/.style = {
            blue,
            font = \sf,
            minimum width = 3mm,
            minimum height = 3mm
        },
        hint special/.style = {
            blue,
            font = \sf,
            minimum width = 3mm,
            minimum height = 3mm,
            fill=red!20,
            inner sep=0pt,
        },
        hint border/.style = {
            blue,
            font = \sf,
            minimum width = 2mm,
            minimum height = 3mm,
            inner sep=0pt, outer sep=0pt,
            draw=red, thick,
            rounded corners=1pt,
        }
    }

% Modified the \node to give a unique name to each one, which is the
% row number, a dash and the column number. E.g: 1-1, 4-5, etc.
    \newcounter{row}
    \newcounter{col}

    \newcommand\setrow[9]{
        \setcounter{col}{1}
        \foreach \n in {#1, #2, #3, #4, #5, #6, #7, #8, #9} {
            \edef\x{\value{col} - 0.5}
            \edef\y{9.5 - \value{row}}
            \node[digit,name={\arabic{row}-\arabic{col}}] at (\x, \y) {\n};
            \stepcounter{col}
        }
        \stepcounter{row}
    }

% New code -------------------------------------------------------------
    \def\highlightcell#1#2{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-#2.north west) rectangle (#1-#2.south east);
        \end{scope}
    }

    \def\circlecell#1#2{
        \draw[circle] (#1-#2) circle(4mm);
    }

    \def\crosscell#1#2{
        \draw[cross] (#1-#2.north west) -- (#1-#2.south east);
        \draw[cross] (#1-#2.north east) -- (#1-#2.south west);
    }

    \def\highlightrow#1{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-1.north west) rectangle (#1-9.south east);
        \end{scope}
    }

    \def\highlighcolumn#1{
        \begin{scope}[on background layer]
            \fill[highlight] (1-#1.north west) rectangle (9-#1.south east);
        \end{scope}
    }

    \def\highlightrectangle#1#2#3#4{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-#2.north west) rectangle (#3-#4.south east);
        \end{scope}
    }

    \def\hintcell#1#2#3{
        \node at (#1-#2) {\hintbox{#3}};
    }


% Command to circle numbers:
% #1: optional -> circle color
% #2: mandatory -> cell identifier
% #3: mandatory -> name of the cell
    \newcommand\circlenumber[3][red!80!black]{
        \draw[circle number=#1, radius=5mm] (#2) circle node[outer sep=1mm] (#3){};
    }

% UGLY code. Do not read :-)
%  Sorry, it needed to be read to obtain solution :-)
    \def\hintbox#1{
        \resizebox{4.5mm}{4.5mm}{%
            \tikz[scale=0.3]{%
                \def\auxc{0}
                \foreach \m in {1,...,9} {
                    \pgfmathparse{mod(\auxc,3)}
                    \xdef\x{\pgfmathresult}
                    \pgfmathparse{-floor(\auxc/3)}
                    \xdef\y{\pgfmathresult}
                    \xdef\hintprinted{0}
                    \foreach \n/\Style in {#1} {
                        \ifnum\n=\m
                            \IfStrEqCase{\Style}{%
                                {}{\node[hint] at (\x,\y) {\n};}                                
                                {\n}{\node[hint] at (\x,\y) {\n};}
                                {border}{\node[hint border] at (\x,\y) {\n};}                           
                                {special}{\node[hint special] at (\x,\y) {\n};}
                            }
                            \xdef\hintprinted{1}
                        \fi
                    }
                    \ifnum\hintprinted=0
                        \node[hint, opacity=0.1] at (\x,\y) {\m};
                    \fi
                    \pgfmathparse{\auxc+1}
                    \xdef\auxc{\pgfmathresult}
                }
            }%
        }
    }


\begin{document}

\begin{tikzpicture}[scale=.5]
    \begin{scope}
        \draw (0, 0) grid (9, 9);
        \draw[very thick, scale=3] (0, 0) grid (3, 3);

        \setcounter{row}{1}
        \setrow { }{2}{ }  {5}{ }{1}  { }{9}{ }
        \setrow {8}{ }{ }  {2}{ }{3}  { }{ }{6}
        \setrow { }{3}{ }  { }{6}{ }  { }{7}{ }

        \setrow { }{ }{1}  { }{ }{ }  {6}{ }{ }
        \setrow {5}{4}{ }  { }{ }{ }  { }{1}{9}
        \setrow { }{ }{2}  { }{ }{ }  {7}{ }{ }

        \setrow { }{9}{ }  { }{3}{ }  { }{8}{ }
        \setrow {2}{ }{ }  {8}{ }{4}  { }{ }{7}
        \setrow { }{1}{ }  {9}{ }{7}  { }{6}{ }
    \end{scope}
\end{tikzpicture}

\end{document}

答案1

“困难”的部分(结果证明一点也不难)。

您可以\clip在绘制数独之前使用。网格会提示您必须用于剪辑的值(坐标)。考虑到这(0,0)是数独的左下角和(9,9)右上角,例如:

\clip (0,6) rectangle (9,9);

将剪辑数独的最后一列,而

\clip (0,3) rectangle (9,6);

将剪切中间行。结果如下:

结果

完整代码如下:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\usetikzlibrary{backgrounds,shapes}
%    \usepackage{graphicx}    % These are not required
%    \usepackage{xstring}

% Some customizable styles
    \tikzset {
        highlight/.style = {
            yellow,
            opacity = 0.3
        },
        digit/.style = {
            minimum height = 5mm,
            minimum width = 5mm,
            anchor = center
        },
        circle/.style = {
            draw = green!80!black,
            dotted,
            very thick
        },
        circle number/.style = {
            draw = #1,
            very thick
        },
        cross/.style = {
            red,
            opacity = .5,
            shorten >= 1mm,
            shorten <= 1mm,
            very thick,
            line cap = round
        },
        hint/.style = {
            blue,
            font = \sf,
            minimum width = 3mm,
            minimum height = 3mm
        },
        hint special/.style = {
            blue,
            font = \sf,
            minimum width = 3mm,
            minimum height = 3mm,
            fill=red!20,
            inner sep=0pt,
        },
        hint border/.style = {
            blue,
            font = \sf,
            minimum width = 2mm,
            minimum height = 3mm,
            inner sep=0pt, outer sep=0pt,
            draw=red, thick,
            rounded corners=1pt,
        }
    }

% Modified the \node to give a unique name to each one, which is the
% row number, a dash and the column number. E.g: 1-1, 4-5, etc.
    \newcounter{row}
    \newcounter{col}

    \newcommand\setrow[9]{
        \setcounter{col}{1}
        \foreach \n in {#1, #2, #3, #4, #5, #6, #7, #8, #9} {
            \edef\x{\value{col} - 0.5}
            \edef\y{9.5 - \value{row}}
            \node[digit,name={\arabic{row}-\arabic{col}}] at (\x, \y) {\n};
            \stepcounter{col}
        }
        \stepcounter{row}
    }

% New code -------------------------------------------------------------
    \def\highlightcell#1#2{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-#2.north west) rectangle (#1-#2.south east);
        \end{scope}
    }

    \def\circlecell#1#2{
        \draw[circle] (#1-#2) circle(4mm);
    }

    \def\crosscell#1#2{
        \draw[cross] (#1-#2.north west) -- (#1-#2.south east);
        \draw[cross] (#1-#2.north east) -- (#1-#2.south west);
    }

    \def\highlightrow#1{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-1.north west) rectangle (#1-9.south east);
        \end{scope}
    }

    \def\highlighcolumn#1{
        \begin{scope}[on background layer]
            \fill[highlight] (1-#1.north west) rectangle (9-#1.south east);
        \end{scope}
    }

    \def\highlightrectangle#1#2#3#4{
        \begin{scope}[on background layer]
            \fill[highlight] (#1-#2.north west) rectangle (#3-#4.south east);
        \end{scope}
    }

    \def\hintcell#1#2#3{
        \node at (#1-#2) {\hintbox{#3}};
    }


% Command to circle numbers:
% #1: optional -> circle color
% #2: mandatory -> cell identifier
% #3: mandatory -> name of the cell
    \newcommand\circlenumber[3][red!80!black]{
        \draw[circle number=#1, radius=5mm] (#2) circle node[outer sep=1mm] (#3){};
    }

% UGLY code. Do not read :-)
%  Sorry, it needed to be read to obtain solution :-)
    \def\hintbox#1{
        \resizebox{4.5mm}{4.5mm}{%
            \tikz[scale=0.3]{%
                \def\auxc{0}
                \foreach \m in {1,...,9} {
                    \pgfmathparse{mod(\auxc,3)}
                    \xdef\x{\pgfmathresult}
                    \pgfmathparse{-floor(\auxc/3)}
                    \xdef\y{\pgfmathresult}
                    \xdef\hintprinted{0}
                    \foreach \n/\Style in {#1} {
                        \ifnum\n=\m
                            \IfStrEqCase{\Style}{%
                                {}{\node[hint] at (\x,\y) {\n};}                                
                                {\n}{\node[hint] at (\x,\y) {\n};}
                                {border}{\node[hint border] at (\x,\y) {\n};}                           
                                {special}{\node[hint special] at (\x,\y) {\n};}
                            }
                            \xdef\hintprinted{1}
                        \fi
                    }
                    \ifnum\hintprinted=0
                        \node[hint, opacity=0.1] at (\x,\y) {\m};
                    \fi
                    \pgfmathparse{\auxc+1}
                    \xdef\auxc{\pgfmathresult}
                }
            }%
        }
    }



\begin{tikzpicture}[scale=.5]
    \begin{scope}
        \clip (6,0) rectangle (9,9);
        \draw (0, 0) grid (9, 9);
        \draw[very thick, scale=3] (0, 0) grid (3, 3);

        \setcounter{row}{1}
        \setrow { }{2}{ }  {5}{ }{1}  { }{9}{ }
        \setrow {8}{ }{ }  {2}{ }{3}  { }{ }{6}
        \setrow { }{3}{ }  { }{6}{ }  { }{7}{ }

        \setrow { }{ }{1}  { }{ }{ }  {6}{ }{ }
        \setrow {5}{4}{ }  { }{ }{ }  { }{1}{9}
        \setrow { }{ }{2}  { }{ }{ }  {7}{ }{ }

        \setrow { }{9}{ }  { }{3}{ }  { }{8}{ }
        \setrow {2}{ }{ }  {8}{ }{4}  { }{ }{7}
        \setrow { }{1}{ }  {9}{ }{7}  { }{6}{ }
    \end{scope}
\end{tikzpicture}

\vskip 5mm

\begin{tikzpicture}[scale=.5]
    \begin{scope}
        \clip (0,3) rectangle (9,6);
        \draw (0, 0) grid (9, 9);
        \draw[very thick, scale=3] (0, 0) grid (3, 3);

        \setcounter{row}{1}
        \setrow { }{2}{ }  {5}{ }{1}  { }{9}{ }
        \setrow {8}{ }{ }  {2}{ }{3}  { }{ }{6}
        \setrow { }{3}{ }  { }{6}{ }  { }{7}{ }

        \setrow { }{ }{1}  { }{ }{ }  {6}{ }{ }
        \setrow {5}{4}{ }  { }{ }{ }  { }{1}{9}
        \setrow { }{ }{2}  { }{ }{ }  {7}{ }{ }

        \setrow { }{9}{ }  { }{3}{ }  { }{8}{ }
        \setrow {2}{ }{ }  {8}{ }{4}  { }{ }{7}
        \setrow { }{1}{ }  {9}{ }{7}  { }{6}{ }
    \end{scope}
\end{tikzpicture}

\end{document}

答案2

仅简单的部分:添加以下代码。

\foreach \x in {1,2,3,4,5,6,7,8,9} {
  \node[font=\scriptsize] at (\x-0.5,9.5) {\x};
  \node[font=\scriptsize] at (-.5,9.5-\x) {\x};
}

相关内容