В общем такого характера проблемка. Все условно, не важно что это будет - юнит, integer, real, то есть от этого можно целиком абстрагироваться. Суть такая - есть 3 (4.5.6.7.8) условных боевых единиц и у каждой есть копия. Нужно чтобы копии пошли атаковать основных героев, но так, чтобы условная копия под номером 6 не пошла атаковать основного героя под номером 6 ни в коем случае. Для примера попытался изобразить на картинке.
У кого какие мысли?

Принятый ответ

respect_gg, можно вобще вот так
  1. записываем в массив номера от 0 до N, где N это число игроков минус один, в ячейки с соответствующими номерами
  2. проходим циклом от N до 0, пусть номер итерации будет i
  3. на каждой итерации получаем случайное число R от 0 до N, Если оно совпало с i, то берем R= i+1 или R=i-1, с учетом границ
  4. меняем местами ячейки R и i
  5. если в ячейку i в результате обмена опять попало число с номером этой ячейки, делаем еще один случайный обмен (тут можно не делать дополнительную проверку на коллизию т.к. коллизия не может на этом этапе возникнуть повторно для этой ячейки)
Если я ничего не напутал - получаем на выходе массив чисел в котором числа не повторяются и не находятся в ячейках совпадающих со своим номером.
Использовать это потом - номер ячейки это один игрок, число в ячейке - другой.
Если нужен учет того что игроки могут иметь номера не идущие подряд (ливеры, компьютеры, просто игроки не использующиеся в этой системе) - нам понадобится дополнительный массив с номерами игроков, чтобы превратить номер ячейки и число в ячейке в реальный номер игрока.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
24
4 года назад
0
respect_gg, я уже описал как решить проблему ливеров...
Нам всего-то надо знать сколько живых игроков, это будет N.
Пусть массив с номерами будет Numbers. Пока оставим его пустым.
Берем второй массив, назовем его Index. В Index записываем айдишники живых игроков, сколько бы их ни было, заодно в процессе вычисляем N и заполняем массив Numbers порядковыми номерами от 0 до N.
Выполняем алгоритм из поста выше.
Результат выполнения алгоритма используем так - проходим циклом от 0 до N, с номером итерации j
Index[Number[j]] - один игрок
Index[j] - второй игрок
0
11
4 года назад
0
prog:
respect_gg, я уже описал как решить проблему ливеров...
Нам всего-то надо знать сколько живых игроков, это будет N.
Пусть массив с номерами будет Numbers. Пока оставим его пустым.
Берем второй массив, назовем его Index. В Index записываем айдишники живых игроков, сколько бы их ни было, заодно в процессе вычисляем N и заполняем массив Numbers порядковыми номерами от 0 до N.
Выполняем алгоритм из поста выше.
Результат выполнения алгоритма используем так - проходим циклом от 0 до N, с номером итерации j
Index[Number[j]] - один игрок
Index[j] - второй игрок
скинул чуваку, который в с++ шарит, он сказал, что нужен 2 мерный массив, а в идеале якобы 3 мерный, типа даже если изначально, как ты выше писал, сместить N на минус 1 шаг, то получится ровно так же, то есть типа коллизия произойдет, но просто на другой ячейке.
Уже фиг знает, 2 вечер подряд голову ломаю :))))
0
24
4 года назад
Отредактирован prog
0
respect_gg, алгоритм рабочий, хоть и требует одной маленькой доработки перед финальным использованием, а твой чувак не шарит и, похоже, ничерта не понял в алгоритме, начиная с того, зачем в нем нужны смещения. Первое "смещение" - N = кол-во игроков -1 нужно потому как нумерация от 0 до N включительно. Второе смещение +1 или -1 на некоторых итерациях нужно чтобы рандом не выдал ту-же ячейку в которой алгоритм находится в текущей итерации, это не более чем дешевое исключение ячейки из диапазона рандома.
Впрочем, поскольку ты даже не попытался реализовать этот алгоритм на практике или разобраться в принципах его работы, а сразу заклеймил его не рабочим - я умываю руки. Это будет мое последнее сообщение в этой теме.
Вот тебе алгоритм для твоего уровня, если нормальный не получается осилить:
Вместо перемешивания сдвигай всех на одно и то же случайное число один раз, с сохранением порядка. Это не так круто как полное перемешивание, но никто и не заметит если сдвиг будет рандомный каждый раз. Естественно, с использованием двух массивов, как я описал выше, чтобы исключить ливеров. Если и до этого не допрешь сам - спроси своего друга якобы шарящего в C++, может хоть с этим он справится.
На всякий случай даже подробно разжую:
Перебираешь игроков, тех кто жив записываешь в массив Index. В результате на выходе получаешь массив, в котором в первой ячейке номер первого живого игрока, во второй - номер второго живого игрока - не и важно какие это игроки по номеру - первый живой может быть пятым, а второй восьмым, тогда первая ячейка будет равна пяти, вторая восьми. Так-же нужно посчитать сколько всего их, живых игроков, это тоже удобно сделать тут, пусть это будет число P. А N, как и раньше, будет P-1.
Каким-угодно способом заполняешь массив Numbers числами от 0 и до N, так чтобы в каждой ячейке изначально был её номер.
Потом один раз берешь случайное число R, оно может быть любым, но важно чтобы оно не было кратным P.
Потом прибавляешь к каждой ячейке Numbers это число - R. Еще раз подчеркиваю - R для всех ячеек одинаковое.
Если в результате число в ячейке больше или равно P, то вычитаешь из него P пока оно не станет меньше P.
На этом заканчиваешь работу с массивом Numbers.
Теперь можно как-то использовать полученный массив, а именно:
Циклом от 0 до N проходим с индексом j
в цикле переменной k присваиваем Number[j]
и получаем номера для двух игроков из массива Index
Index[k] и Index[j]
Этот алгоритм тоже с подвохом, просьба тем кто его заметил не раскрывать карты раньше времени
0
11
4 года назад
0
prog:
respect_gg, алгоритм рабочий, хоть и требует одной маленькой доработки перед финальным использованием, а твой чувак не шарит и, похоже, ничерта не понял в алгоритме, начиная с того, зачем в нем нужны смещения. Первое "смещение" - N = кол-во игроков -1 нужно потому как нумерация от 0 до N включительно. Второе смещение +1 или -1 на некоторых итерациях нужно чтобы рандом не выдал ту-же ячейку в которой алгоритм находится в текущей итерации, это не более чем дешевое исключение ячейки из диапазона рандома.
Впрочем, поскольку ты даже не попытался реализовать этот алгоритм на практике или разобраться в принципах его работы, а сразу заклеймил его не рабочим - я умываю руки. Это будет мое последнее сообщение в этой теме.
Вот тебе алгоритм для твоего уровня, если нормальный не получается осилить:
Вместо перемешивания сдвигай всех на одно и то же случайное число один раз, с сохранением порядка. Это не так круто как полное перемешивание, но никто и не заметит если сдвиг будет рандомный каждый раз. Естественно, с использованием двух массивов, как я описал выше, чтобы исключить ливеров. Если и до этого не допрешь сам - спроси своего друга якобы шарящего в C++, может хоть с этим он справится.
На всякий случай даже подробно разжую:
Перебираешь игроков, тех кто жив записываешь в массив Index. В результате на выходе получаешь массив, в котором в первой ячейке номер первого живого игрока, во второй - номер второго живого игрока - не и важно какие это игроки по номеру - первый живой может быть пятым, а второй восьмым, тогда первая ячейка будет равна пяти, вторая восьми. Так-же нужно посчитать сколько всего их, живых игроков, это тоже удобно сделать тут, пусть это будет число P. А N, как и раньше, будет P-1.
Каким-угодно способом заполняешь массив Numbers числами от 0 и до N, так чтобы в каждой ячейке изначально был её номер.
Потом один раз берешь случайное число R, оно может быть любым, но важно чтобы оно не было кратным P.
Потом прибавляешь к каждой ячейке Numbers это число - R. Еще раз подчеркиваю - R для всех ячеек одинаковое.
Если в результате число в ячейке больше или равно P, то вычитаешь из него P пока оно не станет меньше P.
На этом заканчиваешь работу с массивом Numbers.
Теперь можно как-то использовать полученный массив, а именно:
Циклом от 0 до N проходим с индексом j
в цикле переменной k присваиваем Number[j]
и получаем номера для двух игроков из массива Index
Index[k] и Index[j]
Этот алгоритм тоже с подвохом, просьба тем кто его заметил не раскрывать карты раньше времени
я не в коем случае никого не хочу принизить, я лишь пытаюсь понять как это должно работать. Потому что в целом у меня получается то, что я задумал (через цикл), но в один прекрасный (непонятный) момент он может повести себя странно. Он может до 37 раз (вручную считал) выдавать пары идеально, а на 38 раз весь цикл рушится и приходится заново его запускать. Причем цикл рушится на случайном id, уже проверял - было и 1, и 6, и 4, и 2. То есть как будто хаотично. Хотя до этого все проходит идеально.
Вот ссылка на видео, специально записал, дабы не говорили, что я ничего не пытаюсь сам делать :) youtu.be/KT26LWMI_LY
ПС ESC (то что на видео) это по сути генерация всего, чтобы без лишних вопросов :)

Вроде получилось - 500 (ровно) нажатий и все четко и ровно youtu.be/ZikqrDRgNYs
А нужно было всего лишь в GetRandomInt(0, MaxPlayers) поменять местами MaxPlayers и 0 и хрен пойми в чем разница :)
0
17
4 года назад
0
Присвой всем число и через логическую переменную с условием, запрети герою с номером атаковать копию или того кого уже атакуют(если это нужно) Можно не число, а любое значение для сканирования героя например - цвет. Описание конечно размыто и условно, но надеюсь мысль была понятна.
0
11
4 года назад
0
world_editor:
Присвой всем число и через логическую переменную с условием, запрети герою с номером атаковать копию или того кого уже атакуют(если это нужно) Можно не число, а любое значение для сканирования героя например - цвет. Описание конечно размыто и условно, но надеюсь мысль была понятна.
Еще раз напишу - только сначала в теории все так просто, как только начнешь это реализовывать, то столкнешься с кучей подводных камней
2
37
4 года назад
Отредактирован ScorpioT1000
2
У меня получилось (с любым числом игроков и областей) - с помощью плейер и юнит групп и фоллбека (для решения бага по незанятым парам)
(карта reforged, отдельно триггеры прикрепил)
prevAttackingUnit не нужен
Загруженные файлы
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.