有人可以给我一些提示以实现以下两项改进吗?
简单的:我想显示每列和每行的数字位置。这需要在网格的左侧和上方显示数字。
Sašo Živanović 的回答完成了这个简单部分的工作。
- 难的:有时我只需要显示数独的一个矩形部分。要实现这一点需要做哪些更改?
代码
\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};
}