我正在创建一个迷宫程序,其中的迷宫是随机生成的,用户必须找到一个随机放置的立方体。现在,我希望能够让游戏自行解决,使用 wavefront algorithm , Dijkstra's algorithm ,或 A* algorithm ?
这是生成迷宫墙的代码。
public void GenerateMaze()
{
for (int x = 0; x < mazeWidth; x++)
for (int z = 0; z < mazeHeight; z++)
{
MazeCells[x, z].Walls[0] = true;
MazeCells[x, z].Walls[1] = true;
MazeCells[x, z].Walls[2] = true;
MazeCells[x, z].Walls[3] = true;
MazeCells[x, z].Visited = false;
}
MazeCells[0, 0].Visited = true;
EvaluateCell(new Vector2(0, 0));
}
public void resetMaze()
{
for (int x = 0; x < mazeWidth; x++)
for (int z = 0; z < mazeHeight; z++)
{
MazeCells[x, z].Visited = false;
}
RandomWalls(new Vector2(0, 0));
}
private void EvaluateCell(Vector2 cell)
{
List<int> neighborCells = new List<int>();
neighborCells.Add(0);
neighborCells.Add(1);
neighborCells.Add(2);
neighborCells.Add(3);
while (neighborCells.Count > 0)
{
int pick = rand.Next(0, neighborCells.Count);
int selectedNeighbor = neighborCells[pick];
neighborCells.RemoveAt(pick);
Vector2 neighbor = cell;
switch (selectedNeighbor)
{
case 0: neighbor += new Vector2(0, -1);
break;
case 1: neighbor += new Vector2(1, 0);
break;
case 2: neighbor += new Vector2(0, 1);
break;
case 3: neighbor += new Vector2(-1, 0);
break;
}
if (
(neighbor.X >= 0) &&
(neighbor.X < mazeWidth) &&
(neighbor.Y >= 0) &&
(neighbor.Y < mazeHeight)
)
{
if (!MazeCells[(int)neighbor.X, (int)neighbor.Y].Visited)
{
MazeCells[(int)neighbor.X, (int)neighbor.Y].Visited = true;
MazeCells[(int)cell.X, (int)cell.Y].Walls[selectedNeighbor] = false;
MazeCells[(int)neighbor.X, (int)neighbor.Y].Walls[(selectedNeighbor + 2) % 4] = false;
EvaluateCell(neighbor);
}
}
}
}
//Removes random walls
private void RandomWalls(Vector2 cell)
{
List<int> neighborCells = new List<int>();
neighborCells.Add(0);
neighborCells.Add(1);
neighborCells.Add(2);
neighborCells.Add(3);
while (neighborCells.Count > 0)
{
int pick = rand.Next(0, neighborCells.Count);
int selectedNeighbor = neighborCells[pick];
neighborCells.RemoveAt(pick);
Vector2 neighbor = cell;
switch (selectedNeighbor)
{
case 0: neighbor += new Vector2(0, -1);
break;
case 1: neighbor += new Vector2(1, 0);
break;
case 2: neighbor += new Vector2(0, 1);
break;
case 3: neighbor += new Vector2(-1, 0);
break;
}
//Ensures that end piece is not deleted
if (
(neighbor.X >= 0) &&
(neighbor.X < mazeWidth) &&
(neighbor.Y >= 0) &&
(neighbor.Y < mazeHeight)
)
{
//if cell was not visited
if (!MazeCells[(int)neighbor.X, (int)neighbor.Y].Visited)
{
Random random = new Random();
MazeCells[(int)neighbor.X, (int)neighbor.Y].Visited = true;
//if random number is >= a certain number, removes the walls on both ends
if (random.Next(20) >= 15 && removed <= 100)
{
//MazeCells[(int)neighbor.X, (int)neighbor.Y].Visited = true;
MazeCells[(int)cell.X, (int)cell.Y].Walls[selectedNeighbor] = false;
MazeCells[(int)neighbor.X, (int)neighbor.Y].Walls[(selectedNeighbor + 2) % 4] = false;
removed++;
}
RandomWalls(neighbor);
}
}
}
}
对于缺少注释,我深表歉意,但本质上它是将所有单元格放入一个盒子中,然后撕掉墙壁,以便您可以到达迷宫中的任何单元格。然后我只是移除了一些额外的单元格,这样迷宫就不会让人感到幽闭恐怖。
这是迷宫的图片:
迷宫周围有墙,将玩家留在里面,以防他们很难被看到。通常,您更多地将其视为第一人称视角。
那么,目标:现在,我想让相机找到立方体的位置,以及相机的位置,然后找到两者之间的最短路线。然后,我想让相机慢慢地沿着路线到达那里,直到它碰到立方体。现在,我应该使用哪种算法,以及如何使用。
如果有帮助,此代码几乎完全来自 XNA 4 3D 游戏开发示例 一书。我所做的唯一真正的修改是 RandomWalls() 方法。
最佳答案
我认为波前算法可能有点太复杂而无法用于此问题,因此在我的回答中我将研究其他两种图形搜索算法。
您需要采取的第一步是生成迷宫的图形表示。我认为最简单的方法是:
完成后,您需要分配权重。由于在您的情况下您似乎对一条边或另一条边没有任何偏好,因此为每条边赋予 1 的成本应该没问题。
生成加权图后,您需要对其进行搜索。我认为两个最流行的算法是 Dijkstra's Shortest Path Algorithm和 A*算法。
据我了解,您不知道立方体的放置位置,我认为这意味着您不能使用 A*,因为 A* 以启发式为基础,在这种情况下,它可能是当前节点与目标节点之间的距离,这是您不知道的。
因此,剩下的唯一选择就是最短路径算法。然而,要做到这一点,您需要稍微修改搜索的停止条件,因为您需要检查每个节点代表其内容的方 block 。如果找到您正在寻找的东西,您就会停下来。
另一方面,如果出于某种原因您必须使用负权重,则最短路径 将不再起作用。为此,您将需要使用相同的方法,但是,请使用 Label Correcting Algorithm或 Bellman-Ford Algorithm .
一旦您获得了从源节点到目标节点的最短路径,您就可以提取一系列向量,这些向量将使您从一个方格移动到下一个方格。获得这些向量之后,您应该能够按照 this 中的说明移动相机。 MSDN 教程。
编辑:你问题中的这一行:所以,目标:现在,我希望相机找到立方体的位置让我明白你事先不知道立方体在哪里.如果不是这种情况,那么根据@Gene 的评论,A* 算法将更合适,因为(假设您知道目标在哪里)它会更有效率。
Manhattan distance(见下图)应该很好地作为你算法的启发式部分,因为你似乎不能对角地遍历方 block ,因此,最常见的计算距离的方法(欧几里得) 效果会较差。
关于c# - 波前算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22872950/
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
目录一.加解密算法数字签名对称加密DES(DataEncryptionStandard)3DES(TripleDES)AES(AdvancedEncryptionStandard)RSA加密法DSA(DigitalSignatureAlgorithm)ECC(EllipticCurvesCryptography)非对称加密签名与加密过程非对称加密的应用对称加密与非对称加密的结合二.数字证书图解一.加解密算法加密简单而言就是通过一种算法将明文信息转换成密文信息,信息的的接收方能够通过密钥对密文信息进行解密获得明文信息的过程。根据加解密的密钥是否相同,算法可以分为对称加密、非对称加密、对称加密和非
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume
我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用
什么是Linq聚合方法的ruby等价物。它的工作原理是这样的varfactorial=new[]{1,2,3,4,5}.Aggregate((acc,i)=>acc*i);每次将数组序列中的值传递给lambda时,变量acc都会累积。 最佳答案 这在数学以及几乎所有编程语言中通常称为折叠。它是更普遍的变形概念的一个实例。Ruby从Smalltalk中继承了这个特性的名称,它被称为inject:into:(像aCollectioninject:aStartValueinto:aBlock一样使用。)所以,在Ruby中,它称为inj
1.问题描述使用Python的turtle(海龟绘图)模块提供的函数绘制直线。2.问题分析一幅复杂的图形通常都可以由点、直线、三角形、矩形、平行四边形、圆、椭圆和圆弧等基本图形组成。其中的三角形、矩形、平行四边形又可以由直线组成,而直线又是由两个点确定的。我们使用Python的turtle模块所提供的函数来绘制直线。在使用之前我们先介绍一下turtle模块的相关知识点。turtle模块提供面向对象和面向过程两种形式的海龟绘图基本组件。面向对象的接口类如下:1)TurtleScreen类:定义图形窗口作为绘图海龟的运动场。它的构造器需要一个tkinter.Canvas或ScrolledCanva
我一直在尝试用Ruby实现Luhn算法。我一直在执行以下步骤:该公式根据其包含的校验位验证数字,该校验位通常附加到部分帐号以生成完整帐号。此帐号必须通过以下测试:从最右边的校验位开始向左移动,每第二个数字的值加倍。将乘积的数字(例如,10=1+0=1、14=1+4=5)与原始数字的未加倍数字相加。如果总模10等于0(如果总和以零结尾),则根据Luhn公式该数字有效;否则无效。http://en.wikipedia.org/wiki/Luhn_algorithm这是我想出的:defvalidCreditCard(cardNumber)sum=0nums=cardNumber.to_s.s
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭8年前。Improvethisquestion几年前我去学校学习编程,毕业后我找到了一份系统管理方面的工作,这就是我职业生涯的方向。我想重新开始某种开发,并且一直在“玩”C#和ASP.NET,但我已经听到很多关于其他"new"语言的讨论(新的意思是它们是新的)我)喜欢Ruby和F#。我想我想知道我是否在浪费时间学习主要的MS语言,而不是成为一名通才。很长一段时间没有离开开发社区(如果我曾经离开过的话)让我在潮流中挣扎,我不想落在时代的