2010-05-18 2 views
1

alt text http://img707.yfrog.com/img707/6250/newpicturer.jpgИспользование LINQ для выделения конкретного объекта из списка объектов

Я пытаюсь мою руку на создание клона захватчиками. есть 30 инопланетян, расположенных в матрице размером 5x6 на экране. Мне нужно дать дно самой чужой способность выстрелить. Я использую LINQ, чтобы сгруппировать пришельцев в 5 групп на основе Location.X, а затем отсортировать группы по убыванию. Затем мне нужно выбрать одну из групп (которая дает мне 5 групп) и выбрать первого иностранца в группе и используйте его координату s, чтобы выстрелить.

Мой код ниже, ну, работает, но инопланетяне в ЛЮБОЙ строке весело стреляют - не только самое нижнее. Посмотрите мой код ниже и скажите мне, что случилось. (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)); 

     } 

EDIT:

Solved.Now работает как требуется после того, как David 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; 

      } 
+0

Что случилось с 'r'? –

+0

Этот код работает отлично для меня – Midhat

+0

@jonas Elfstrom: r является экземпляром Random, мне нужно вытащить случайный столбец из группы из 5 столбцов. (игра может стать предсказуемой иначе) – dezkev

ответ

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)]; 
+0

Пробовал тоже, не работает. То, что происходит, заключается в том, что инопланетяне (или захватчики) в первом столбце ТОЛЬКО стреляют, но снова произвольно - не самое нижнее. Настолько неплохое улучшение от моего существующего кода, но по-прежнему нужно немного подстраиваться .. попробует все возможное. – dezkev

+0

после дальнейшей настройки, теперь он работает. См. Редактировать в моем исходном посте для окончательного кода. – dezkev

+0

Должны быть настроены ваши X и Y. –

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 вверх или вниз.)

В то время как это может работать, я не уверен, что все это сортировка все время идеально ... не можете ли вы захватить захватчиков в структуре данных, которая поможет вам сделать это легче?

+0

Извините! попробовал ваш код, но это тоже не работает. Кадры все еще увольняются из разных строк, а не из нижней строки. – dezkev

+0

@dezkev: В чем разница между местоположением и областью в классе захватчика? –

+0

Местоположение - точка (X, Y), где захват рисуется на экране, а область - это свойство, определенное ниже: public Rectangle Area {get {return new Rectangle (Location, Image.Size);}} – dezkev

1

Вы группируете Location.X, который я собираюсь догадаться, это столбец. Затем вы заказываете эти группы по номеру столбца - обратите внимание, что это заказывает группы, а не элементы в пределах групп. Поскольку вы выбираете случайную группу, тот факт, что вы их заказывали, не имеет значения. После того, как вы выбрали случайную группу - случайный столбец оригинальных инопланетян, вы выбираете First группы, но поскольку инопланетяне не упорядочены в пределах групп, вы получаете произвольного инопланетянина.

Чтобы это исправить, вам необходимо убедиться, что группы упорядочены по высоте (Location.Y, я думаю), так что при выборе First группы вы выбираете случайно, это чуждо нижний , Изменение

select invgroup).ToList(); 

в

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

(предполагается, что ваш Y ось идет в правильном направлении, чтобы это дать то, что вы хотите!)

+0

Ось Y является вертикальным. Возможно, мне нужно заказать их после случайного выбора. Как я могу это сделать ? – dezkev

Смежные вопросы