gpt4 book ai didi

c# - 摆脱不必要的循环

转载 作者:太空宇宙 更新时间:2023-11-03 18:29:05 24 4
gpt4 key购买 nike

在我的游戏中,我将进行很多交互,在这些交互中我需要查看玩家是否拥有元素,如果他拥有并且其他情况为真,则执行操作。在下面的代码中描述。

private void SetTinderInPit()
{
MouseState currentMouseState = Mouse.GetState();

if (player.NextToFirePit == true)
{
foreach (Item item in player.PlayerInventory.Items)
{
if (item.ItemName == "tinder")
{
foreach (Item pit in allItemsOnGround)
{
if (pit.ItemName == "firepit" &&
pit.ItemRectangle.Contains(MouseWorldPosition) &&
currentMouseState.LeftButton == ButtonState.Pressed &&
oldMouseState.LeftButton == ButtonState.Released)
{
item.ItemName = "empty";
pit.ItemName = "firepitwithtinder";
pit.Texture = Content.Load<Texture2D>("firepitwithtinder");
}
}
}
}
oldMouseState = currentMouseState;
}
}

如您所见,这看起来很难看,我认为会有更好的方法来做到这一点,但我不确定如何做。由于会有很多此类方法,我想知道实现此目的的最佳方法是什么?

最佳答案

似乎您可以通过使用一些 LINQ 完全摆脱(实际上隐藏)循环:

private void SetTinderInPit()
{
MouseState currentMouseState = Mouse.GetState();

if (player.NextToFirePit)
{
Item tinder = player.PlayerInventory.Items.FirstOrDefault(i => i.ItemName == "tinder");
if (tinder != null)
{
Item firepit = allItemsOnGround.FirstOrDefault(i => i.ItemName == "firepit" && i.ItemRectangle.Contains(MouseWorldPosition));
if (firepit != null &&
currentMouseState.LeftButton == ButtonState.Pressed &&
oldMouseState.LeftButton == ButtonState.Released)
{
tinder.ItemName = "empty";
firepit.ItemName = "firepitwithtinder";
firepit.Texture = Content.Load<Texture2D>("firepitwithtinder");
}
}
oldMouseState = currentMouseState;
}
}

这具有在找到项目时使循环短路的额外优势。它还可以轻松检查名称以外的内容(例如“IsFlammable”或“CanContainFire”属性),因此您可以使用多个项目而不仅仅是“tinder”和“firepit”。

如果您实际上打算移除所有火坑和火种,请使用:

private void SetTinderInPit()
{
MouseState currentMouseState = Mouse.GetState();

if (player.NextToFirePit)
{
foreach (Item tinder in player.PlayerInventory.Items.Where(i => i.ItemName == "tinder")
{
foreach (Item firepit in allItemsOnGround.Where(i => i.ItemName == "firepit"))
{
if (firepit.ItemRectangle.Contains(MouseWorldPosition) &&
currentMouseState.LeftButton == ButtonState.Pressed &&
oldMouseState.LeftButton == ButtonState.Released)
{
tinder.ItemName = "empty";
firepit.ItemName = "firepitwithtinder";
firepit.Texture = Content.Load<Texture2D>("firepitwithtinder");
}
}
}
oldMouseState = currentMouseState;
}
}

快速警告;此代码将移除带有第一个火种的所有火坑,而其他火种则毫发无损。我可以解开循环以删除所有内容,但此函数与提供的函数匹配;此外,我假设这不是预期的行为。

请注意,您在任何地方都不需要 ToList,因为您没有在枚举期间修改集合。您始终可以修改集合中的项目,以下测试证明了这一点:

class IntWrapper
{
public int value;

public IntWrapper(int value)
{
this.value = value;
}
}

class Program
{
static void Main(string[] args)
{
List<IntWrapper> test = new List<IntWrapper>() { new IntWrapper(1), new IntWrapper(2), new IntWrapper(3), new IntWrapper(4), new IntWrapper(5) };

foreach (IntWrapper i in test.Where(i => i.value == 1))
{
i.value = 0;
}

foreach (IntWrapper i in test)
{
Console.WriteLine(i.value);
}

Console.ReadLine();
}
}

关于c# - 摆脱不必要的循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26411187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com