使用 Tikz 在六角网格上进行程序随机游走

使用 Tikz 在六角网格上进行程序随机游走

我正在尝试对一组命名的正六边形进行随机游走。我有一个使用 Ti 创建正六边形集合的例程Z shapes.geometric。每个六边形都命名为x-Cy,其中x是它在行内的水平位置,y是行值。行包含元素 0 到 20,行编号为 0-30。这部分代码运行良好(参见https://i.stack.imgur.com/Vk833.jpg)。

我的下一步是让例程沿着顶行随机选择一个节点,然后随机遍历页面,将六边形涂成蓝色。一旦我们到达六边形阵列的边缘(退出地图),例程就应该结束。

我试图通过递归来实现这一点,但 breakforeach 似乎无法跳出并中断我的循环。代码如下。

\foreach \i in {1} {
   \node[waterTile,anchor=corner 1]() at (#1-C#2.corner 1) {}; %make the hex x-Cy a water tile

    \pgfmathtruncatemacro{\nextRiverTileX}{\nextRiverTileX+random(0,2)-1} %randomly move in the x direction
    \pgfmathtruncatemacro{\nextRiverTileY}{\nextRiverTileY+random(0,1)} %randomly move in the y direction

    %if we moved off the map, break the loop
    \ifnum \nextRiverTileX>20 \breakforeach \fi

    \ifnum \nextRiverTileX<0 \breakforeach \fi

    \ifnum \nextRiverTileY>30 \breakforeach \fi

    \ifnum \nextRiverTileY<0 \breakforeach \fi

    %if we didn't move off the map, repeat the process
    \makeRiver{\nextRiverTileX}{\nextRiverTileY}

    %once the loop breaks, break the prior loop
    \breakforeach
}
} %makeRiver

有没有更好的方法来处理这个问题?如前所述,地图创建过程本身运行良好。现在,程序着色给我带来了问题。如果我指定要着色的某些六边形,那就行得通。如果我指定要为六边形着色的行数,那就行得通。但我似乎无法让它重复,直到我们退出地图(即使用基于宏的 breakforeach)。

答案1

已解决问题;breakforeach 需要位于嵌套的 if 块中,以防止再次调用该函数。修复的代码如下:

\newcommand{\makeRiver}[2] { %{x}{y}

    \foreach \i in {1} {
       \node[waterTile,anchor=corner 1]() at (#1-C#2.corner 1) {}; %make the hex x-Cy a water tile

        \pgfmathtruncatemacro{\index}{random(0,1)}
        \ifodd\index
            \pgfmathtruncatemacro{\nextRiverTileX}{\nextRiverTileX+random(0,2)-1} %randomly move in the x direction
        \else
            \pgfmathtruncatemacro{\nextRiverTileY}{\nextRiverTileY+random(0,1)} %randomly move in the y direction
        \fi

        %if we moved off the map, break the loop
        \ifnum  \nextRiverTileX>20 \breakforeach
        \else   \ifnum \nextRiverTileX<0 \breakforeach
                \else   \ifnum \nextRiverTileY>30 \breakforeach
                        \else   \ifnum \nextRiverTileY<0 \breakforeach
                                \else \makeRiver{\nextRiverTileX}{\nextRiverTileY} %if we didn't move off the map, repeat the process
                                \fi
                        \fi
                \fi
        \fi

        %once the loop breaks, break the prior loop
        \breakforeach
    }
} %makeRiver

相关内容