我在PHP中有这个脚本,我使用
while(in_array(array(' x' => $ x,' y' => $ y),$ worldMap)){...}
检查我的worldMap是否已在这些XY位置有空间。 如果为TRUE我随机选择X或Y,WHILE循环再次检查新值,依此类推,IF FALSE我填充生成最后一个XY的worldMap数组。
现在,我试图用C#重写代码,但我得到了一个无限循环。
这是我目前的代码:
public int nbRooms = 10;
private Dictionary<int, Dictionary<string, int>> worldMap = new Dictionary<int, Dictionary<string, int>>();
private Dictionary<string, int> roomXY = new Dictionary<string, int>();
private string[] arrayXY = {"X","Y"};
private int[] arrayNbr = {-1,1};
private int X = 0;
private int Y = 0;
for(int i = 0; i <= nbRooms; i++)
{
while(worldMap.ContainsValue(roomXY))
{
string XorY = arrayXY[Random.Range(0, 2)];
switch(XorY)
{
case "X": X += arrayNbr[Random.Range(0, 2)];
break;
case "Y": Y += arrayNbr[Random.Range(0, 2)];
break;
}
roomXY.Clear();
roomXY.Add("X", X);
roomXY.Add("Y", Y);
}
worldMap.Add(i, roomXY);
}
答案 0 :(得分:0)
ContainsValue对 TValue 使用默认的相等比较器 EqualityComparer.Default ,这是字典中的值类型。 roomXY是一个(引用)字典对象,引用不会通过更改此对象的X和Y坐标进行更改,因此您将遇到无限循环。
答案 1 :(得分:0)
这里的基本问题是,默认情况下,两个引用类型对象之间的比较只是比较引用本身。当您更改roomXY
对象的内容时,您不会更改引用本身(即实际对象保持不变),因此一旦您将对象添加到worldMap
字典一次,它就会当您下次循环检查时,它总是在那里。
非常好地说明为什么在移植代码时移植 intent 非常重要,但不一定是确切的实现,因为语言处理的方式不同。
事实上,根据您发布的代码,在这种情况下,似乎您可能不想在任何地方使用字典类。可以使用字典对象使其工作,但您并没有真正利用这些数据结构的字典性质。看起来你在这里使用字典更多是因为在语义上它们看起来与你在PHP中使用的数据结构类似,但事实上C#提供了可能更合适的其他语言功能。
例如,您可以编写如下代码:
struct Room
{
public readonly int X;
public readonly int Y;
public Room(int x, int y) { X = x; Y = y; }
}
public int nbRooms = 10;
private Room[] worldMap = new Room[nbRooms];
private string[] arrayXY = {"X","Y"};
private int[] arrayNbr = {-1,1};
private int X = 0;
private int Y = 0;
private Room roomXY = new Room(X, Y);
for(int i = 0; i <= nbRooms; i++)
{
while(Array.IndexOf(worldMap, roomXY) >= 0)
{
string XorY = arrayXY[Random.Range(0, 2)];
switch(XorY)
{
case "X": X += arrayNbr[Random.Range(0, 2)];
break;
case "Y": Y += arrayNbr[Random.Range(0, 2)];
break;
}
roomXY = new Room(X, Y);
}
worldMap[i] = roomXY;
}
由于C#默认为值类型(即struct
)实现了相等比较,这将比较roomXY
值的实际内容与worldMap
中的值进行比较
注意:您的原始实现和上面的实现都使用worldMap
数据结构中的线性搜索。对于这里的少数房间(10),这应该没问题。但是你应该意识到,对于更大的数据集,这可能是非常低效的。在这种情况下,您可能希望使用不同的方法来生成此数据(例如,哈希集,较大的地图数据结构中的标记,重排等)。