使用LINQ将特定对象与对象列表隔离开来

时间:2010-05-18 09:00:45

标签: c# visual-studio-2008 linq c#-3.0

alt text http://img707.yfrog.com/img707/6250/newpicturer.jpg

我正在尝试让入侵者克隆。在屏幕上以5x6矩阵排列有30个外星人。我需要给予最底层的射击能力。 我正在使用LINQ将外星人分组到基于Location.X的5组,然后对组进行降序排序。然后我需要选择其中一个组(这给了我5组) 并选择组中的第一个外星人并使用它; s坐标来射击。

下面我的代码很有效,但是任何行中的外星人都会快乐地开枪 - 而不仅仅是最底层的。 Pl看下面的代码并告诉我什么是错的。 (r = Random类的一个实例,所有外星人都在一个名为入侵者的列表中)。

 {
           var query = (from inv in invaders
                         group inv by inv.Location.X
                         into invgroup
                         orderby invgroup.Key descending 
                         select invgroup).ToList();

            var invfirst = query[r.Next(query.Count)].First();


                invaderShots.Add(new Shot(
                        new Point(invfirst.Area.X + invfirst.Area.Width / 2, invfirst.Area.Y + invfirst.Area.Height + 5),
                        displayrect, Shot.Direction.Down));

        }

编辑:

Solved.Now它按照大卫B把我推向正确的方向后按要求运作。

下面的最终代码。 鉴于正在进行的大量分组/排序,肯定需要一些改进。如果有人对此有一些建设性的话,我就是耳朵(或眼睛,在这种情况下)。感谢所有帮助过的人。

   List<Invader> firstinvader = invaders.GroupBy(inv => inv.Location.X)
                .Select(g => g.OrderByDescending(inv => inv.Location.Y)).ElementAt(r.Next(5)).ToList();

            firstinvader.Sort(comparerByLocation);
            Invader item = firstinvader[firstinvader.Count -1];

            if(invaderShots.Count < 2)
            {
                invaderShots.Add(new Shot(
                     new Point(item.Area.X + item.Area.Width / 2, item.Area.Y + item.Area.Height / 2),
                     displayrect, Shot.Direction.Down));

            }
            else
            {
                return;

            }

3 个答案:

答案 0 :(得分:1)

您订购群组但未订购入侵者。这可能会这样做:

var query = (from inv in invaders
             group inv by inv.Location.X
             into invgroup
             orderby invgroup.Key descending 
             select invgroup.OrderBy(inv => inv.Location.Y)).ToList();

(您可能希望按顺序降序排列,具体取决于Y是向上还是向下。)

虽然这可行,但我不确定所有这些排序都是理想的...你能不能将入侵者存储在一个数据结构中,这有助于你更容易地做到这一点吗?

答案 1 :(得分:1)

您按Location.X进行分组,我猜这是。然后,您可以按列号订购这些组 - 请注意,这会对进行排序,而不是对组内的项目进行排序。既然您选择了一个随机组,那么您订购它们的事实就无关紧要了。一旦你选择了一个随机组 - 原始外星人的随机列 - 然后你选择了该组的First,但由于外星人没有在这些组中被命令,你就会得到一个随意的外星人。

要解决此问题,您需要确保按高度排序(我猜是Location.Y),以便在您选择First时你随机挑选的那组,它是最底层的外星人。改变

select invgroup).ToList();

select invgroup.OrderBy(inv => inv.Location.Y)).ToList();

(假设你的Y轴朝着正确的方向前进,为了得到你想要的东西!)

答案 2 :(得分:1)

List<Invader> firstInvaders = invaders
  .GroupBy(inv => inv.Location.X)
  .Select(g => g
     .OrderByDescending(inv => inv.Location.Y)
     .First())
  .ToList();

Invader shooter = firstInvaders[r.Next(firstInvaders.Count)];