Розуміння вимог
- Усі гравці мають обмежену кількість суміжних ворогів.
По-перше, ми говоримо про породжені точки гравців, а не поточну позицію гравців у певній точці гри. Тільки позбувшись цього.
Суміжний добре визначений, коли ми говоримо про графік. Ми можемо придумати карту, яка представляє судноплавність на карті - відтепер - «графік».
Якщо у вузла може бути не більше однієї точки нересту, то говорити про те, що вони є "суміжними", має сенс. Примітка: я не буду обмежувати вузли, щоб мати максимум одну єдину нерестову точку з причин, які стануть очевидними пізніше.
Щоб побудувати графік, нам потрібно буде врахувати такі речі, як стіни, мости, сходи, пункти телепортації або навіть розглянути полет, якщо може бути гравець, який може літати. Кожен вузол представляє місце, яке можна подорожувати; кожне з'єднання являє собою можливий рух.
Примітка: знайте розміри та форму вузлів та працюйте з фактично сусідніми вузлами. Не вважайте вузли точкою. Не вважайте з'єднання такими, що мають довжину. Також використовуйте опуклі вузли.
Графік міг бути попередньо складений (карту створив дизайнер); в іншому випадку його можна створити на льоту, якщо карта генерується випадковим чином.
- Усі гравці мають однаковий шанс зустріти суміжних ворогів.
Я припускаю, що вороги - це інші гравці. Знову ж таки, просто відволікти це.
Якщо припустити, що кожен гравець робить випадкову прогулянку, ймовірність знайти гравця в заданій точці - на рівній площі, вільній від перешкод - буде задана (гауссова) функція відстані до точки нересту - відтепер " функція ".
Оскільки ми працюємо над графіком, замість цього будемо анотувати значення на графіку.
- Розмір карти не повинен збільшуватися пропорційно кількості гравців.
Якби у нас було обмеження мати одну нерестову точку на вузол, то для додання більшої кількості гравців нам знадобляться менші вузли. Якщо ми вирішимо графік, перш ніж ми дізнаємося, скільки гравців у нас буде, нам, можливо, доведеться підрозділити вузли для конкретної гри.
- Ці обмеження не застосовуються за допомогою довільних непрохідних пробілів.
Я не збираюся додавати перешкоди для вирішення проблеми. Au contraire , мені потрібно працювати над перешкодами. Якби їх не було, реалізація була б простішою.
Рішення
Ми намагаємось розмістити N нерестових очок таким чином, щоб шанс зустріти іншого гравця в усіх цих ікру рівний.
Ми можемо отримати міру помилки як суму різниць шансів до середнього значення шансів. Ми намагаємося мінімізувати це (насправді ми хочемо зробити це 0).
Для цього нам потрібно знати шанс зустріти гравця на кожному вузлі графіка.
Щоб обчислити цей шанс, почніть з нуля. Оскільки шанс знайти гравця на будь-якому даному вузлі, коли немає гравців, дорівнює нулю. А потім для кожної точки нересту пройдіться по графіку, додавши до анотованого шансу значення функції для поточної точки нересту.
Примітка 1. Додавання або переміщення нерестової точки вплине на шанс зустріти гравця на всій карті.
Примітка 2: Відстеження того, наскільки кожна точка нересту впливає на шанс, полегшить ситуацію.
Примітка 3: Оскільки вузли мають розмір, то наскільки близько ви можете дійти до помилки = нуль, залежить від розміру вузлів. Ви можете бути більш точними, працюючи з діапазонами значень (мінімум і максимальний шанс, залежно від конкретного положення нерестових точок у вузлі).
Розмістіть нерестові точки навмання, після чого почніть переміщувати їх таким чином, щоб помилка стала меншою (розгляньте можливий рух, а якщо причина помилки зменшиться, збережіть її, інакше поверніть її). І продовжуйте робити це, поки ми не зможемо вдосконалити більше (занадто багато ітерацій без поліпшення або помилка дорівнює нулю).
Примітка 4: Під час переміщення точки нересту ви можете скористатися шансом зустріти гравця (виключаючи точку нересту, на яку будете рухатись), щоб випадковим чином вибрати нову позицію для точки нересту, таку позицію, яка має шанс зустріти гравця ближче до середні ймовірніші. Нагадую, що переміщення точки нересту вплине на середнє значення.
Очікувана поведінка полягає в тому, що точка нересту, яка знаходиться занадто близько один до одного, розсувається, а точки нересту, які знаходяться занадто далеко один від одного, наближаються. Поки вони не досягнуть рівноваги.
Якщо у будь-якій заданій ітерації у вас є кілька точок нересту на вузлі (що малоймовірно, оскільки вони мають тенденцію рухатися один від одного, але можливо, якщо у вас достатньо великі вузли), розділіть вузол і продовжуйте розв’язувати. Будь-який поділ вузла є дійсним.
Вищевказане рішення наблизиться до помилки = нуля, але не гарантовано досягне нуля. Ви можете зробити це запустити його, поки він не досягне локального мінімуму ... Теоретично ви можете розділити вузли, щоб зробити його точно нульовим ... Але це еквівалент налаштування координат точки нересту!
Спробуйте імітувати відпал для переміщення нерестової точки у вузлі. Хоча, чесно кажучи, напевно не варто зациклюватися на такому рівні деталізації.
Хочеться дати зрозуміти, що результат для плоскої карти без перешкод не буде рівномірно розподіленими балами. Натомість, якщо карта має краї (тобто, якщо вона не обертається), то буде більше нерестової точки ближче до країв, це тому, що точки в центрі можна дістати з більшої сторони, збільшуючи шанс зустріти інших гравців немає. Таким чином, точки, розташовані далі біля центру, щоб компенсувати.