有没有一种方法可以将“键/值”对添加到“字典”的末尾?

时间:2019-05-03 00:40:13

标签: c# dictionary

当前正在研究一个项目,以在Windows Forms中创建纸牌游戏“ War”。我使用词典来跟踪图像文件以及卡的值。我遇到了一个问题,其中cpuDeck.add(x,y);正在将字典小肠添加到字典的前面而不是后面。

cpuPlayer = cpu的甲板

humanPlayer =人类的甲板

cpuWinnings和humanWinnings是临时词典,用于存储卡,以便在它们返回主词典之前为GUI提取图像

if (cpuPlayer.Values.ElementAt(0) >= humanPlayer.Values.ElementAt(0))
{
    Image x = cpuPlayer.Keys.ElementAt(0);
    int y = cpuPlayer.Values.ElementAt(0);
    Image a = humanPlayer.Keys.ElementAt(0);
    int b = humanPlayer.Values.ElementAt(0);
    cpuPlayer.Remove(x);
    humanPlayer.Remove(a);
    cpuPlayer.Add(x, y);
    cpuPlayer.Add(a, b);
    cpuWinnings.Add(x, y);
    imgcpuwinning.Image = cpuWinnings.Keys.ElementAt(0);
    cpuWinnings.Clear();
}
else if ((humanPlayer.Values.ElementAt(0) > cpuPlayer.Values.ElementAt(0)))
{
    Image x = cpuPlayer.Keys.ElementAt(0);
    int y = cpuPlayer.Values.ElementAt(0);
    Image a = humanPlayer.Keys.ElementAt(0);
    int b = humanPlayer.Values.ElementAt(0);
    cpuPlayer.Remove(x);
    humanPlayer.Remove(a);
    humanPlayer.Add(x, y);
    humanPlayer.Add(a, b);
    humanWinnings.Add(a, b);
    imghumanwinning.Image = humanWinnings.Keys.ElementAt(0);
    humanWinnings.Clear();
}
else
{

}

2 个答案:

答案 0 :(得分:0)

您不应该依赖字典中键的顺序。如果需要订购,则要手动更改元素,应使用OrderedDictionarySortedDictionaryKeyValuePairList

来自documentation

  

出于枚举目的,字典中的每个项目均被视为   代表值的KeyValuePair结构及其   键。物品的退还顺序是不确定的。

字典中元素的顺序是不确定的。因此,不要依赖于将元素添加到字典的顺序来枚举。不能保证。

我希望对您有帮助

答案 1 :(得分:0)

Dictionary<Image, int>不具有下订单的概念。使用SortedDictionary<Image, int>的想法没有意义,因为您仍然无法控制要添加项目的位置-这将基于密钥。

您真正需要的是某种列表,您可以在其中控制添加项目的位置。

您可能想要List<(int Value, Image Image)>甚至Queue<(int Value, Image Image)>。类型(int Value, Image Image)是一个包含两个元素的元组。您目前正在使用KeyValuePair<Image, int>

我将为您推荐一些代码供您使用,但恐怕很难确切知道您要使用呈现的最小代码来做什么。

对于您尝试使用此代码的内容,我也有些困惑:

    cpuWinnings.Add(x, y);
    imgcpuwinning.Image = cpuWinnings.Keys.ElementAt(0);
    cpuWinnings.Clear();

您似乎想在cpuWinnings的末尾添加一个元素,但是您使用了列表的第一项,然后清除了列表。如果您只想清除项目,在末尾添加项目有什么意义?或者,如果您期望.Add(x, y)放在列表的最前面,那么为什么不imgcpuwinning.Image = x;在清除列表之前呢?

我将假设您希望将其添加到列表的末尾。

所以这是代码。首先,我想定义一种方法来说明当前玩家是谁,并减少您拥有的变量数。

让我们创建一个Player enum

public enum Player
{
    Human, Cpu
}

现在,如果您要尝试从列表中选择第一个项目,然后删除该项目,则可能需要Queue。而且我们希望每个HumanCpu玩家都有一个队列。

var player = new Dictionary<Player, Queue<(int Value, Image Image)>>()
{
    { Player.Human, new Queue<(int Value, Image Image)>() },
    { Player.Cpu, new Queue<(int Value, Image Image)>() },
};

在我看来,winnings仅需要一个列表。

var winnings = new Dictionary<Player, List<(int Value, Image Image)>>()
{
    { Player.Human, new List<(int Value, Image Image)>() },
    { Player.Cpu, new List<(int Value, Image Image)>() },
};

对于您的PictureBox元素,您只需要这样做:

var holder = new Dictionary<Player, PictureBox>()
{
    { Player.Human, imghumanwinning },
    { Player.Cpu, imgcpuwinning },
};

现在要选择并从队列中删除第一个元素,请执行以下操作:

(int Value, Image Image) xy = player[Player.Cpu].Dequeue(); //remove first
(int Value, Image Image) ab = player[Player.Human].Dequeue(); //remove first

注意:我从您的代码中保留了xyab变量名,我将它们结合在一起。理想情况下,您应该将这些命名更有意义。

接下来,我们要找出当前玩家是谁:

var currentPlayer = xy.Value >= ab.Value
    ? Player.Cpu
    : Player.Human;

现在处理值很容易:

player[currentPlayer].Enqueue(xy); //add to end of queue
player[currentPlayer].Enqueue(ab); //add to end of queue
winnings[currentPlayer].Add(xy);
holder[currentPlayer].Image = winnings[currentPlayer].First().Image;
winnings[currentPlayer].Clear();

没有if了。

现在,我需要Queue可能是错的,但是它似乎适合您当前的代码。可能您也需要为Queue使用winnings。也许只要List就足够了。您需要为我提供更多详细信息,以便做出更好的答复。

相关问题