Відповіді:
Ви спробували Алгоритм Ллойда ? Процедура досить проста і призведе до отримання досить регулярних регіонів (залежно від кількості запущених ітерацій).
Вам не доведеться запускати його дуже довго, щоб створити приємну вигляд карти. Цей приклад вимагав лише трьох ітерацій.
Один простий спосіб ви можете спробувати.
n
шестигранників. Кожен з них розпочне групу.Я не тестував, але це повинно створити острови і дещо уникати довгих тонких брекетів. Також, швидше за все, будуть межі сусідів, але необов'язково кожен з них матиме зв'язок з іншими, що щільність буде залежати від значення n
.
Деякі групи також можуть бути прикуті до інших і досягають розміру менше 20, ви можете забезпечити вирощений простір, нерестуючи стартові шестигранники на мінімальній відстані один від одного.
Тестуйте і підкручуйте за потребою.
Крім того, не пов’язану з цією проблемою, але дуже, дуже корисно працювати з шестигранниками, відвідайте цю сторінку: http://www.redblobgames.com/grids/hexagons/#basics
Вона об'єднує цілу купу шістнадцяткових відомостей в одному місці з приємний візуальний.
Я безумовно думаю, що деякий тип структури графіків зробив би це можливим. В основному створіть край між двома шестигранними вузлами, якщо вони знаходяться поруч один з одним, щоб імітувати всю карту. Однак я не впевнений у точному алгоритмі створення "країни" на цій карті. Річ у тому, що залежно від того, як ви хочете, щоб країна "виглядала", вам знадобляться різні алгоритми.
Я б рекомендував вибрати крапку і виїхати звідти назовні, вибравши випадкову плитку у вашій "країні, що росте", яка має сусідню плитку, яка не входить до країни.
Для вимкнення алгоритмів може використовуватися шаблон стратегії залежно від типу країни, який ви хочете. http://en.wikipedia.org/wiki/Strategy_pattern тобто ви хочете струнку країну узбережжя, як чилі? Або ви хочете чогось більш круглого і вміщеного?
Властивості графіків можуть також дозволяти налаштувати, як виглядає кінець "країни": http://en.wikipedia.org/wiki/Eccentricity_(graph_theory)
Хочете велику країну? Налаштуйте властивості графіка та змушуйте генеровану країну (яка є лише графіком) мати властивості, які надають їй "вигляд", який ви хочете.
І останнє, але не менш важливе, графіки також будуть дуже корисними для визначення меж між країнами. Ви можете побудувати графік, який має зв'язок між двома вузлами, якщо країни межують між собою. Це може бути корисним для певного типу розділів у вашій грі і дозволить вам, можливо, оптимізувати певні речі в подальшому розвитку.
Одне невелике зауваження: ви говорите: "виглядає як карта реального життя із країнами різної форми, але однакових розмірів), але" реальні "країни сильно відрізняються за розмірами навіть у певних регіонах - навіть" великі "країни Європи можуть сильно відрізнятися, наприклад, Франція більше ніж удвічі більша, ніж Італія. Зважаючи на це, очевидно, що є геймплейні регіони, щоб спробувати зберегти розміри приблизно однакові - просто пам’ятайте, що невелика варіація тут, мабуть, хороша річ!
Моїм початковим підходом до проблеми було б "еволюціонувати" (а не "рости") ваші регіони:
Тепер, наскільки ви хочете, запустіть такий псевдокод:
Pick a random hex A from the boundary list;
Pick a random neighbor B of this hex from a different country;
if (A's country has more hexes than B's country has) {
change hex A to belong to B's country;
} else if (B's country has more hexes than A's country has) {
change hex B to belong to A's country;
} else {
flip a coin to decide which to change;
}
if ( the changed hex's old country has become disconnected ) {
undo and reject this move;
} else {
update the boundary list around the changed hex and its neighbors;
}
Це дозволить підтримувати приблизний баланс між розмірами будь-яких двох сусідніх країн, а "відключена" перевірка (що можна зробити за допомогою простого алгоритму заповнення заливів) гарантує, що жодна країна ніколи не розпадається на частини. Оновлення списку кордонів - це операція постійного часу - змінений шестигранник, очевидно, завжди залишатиметься на кордоні, і ви можете просто перевірити його шість сусідів, щоб побачити, чи хтось із них став або прикордонною коміркою (тому що його сусід зараз у інша країна) або перестала бути прикордонною коміркою (оскільки її сусід зараз знаходиться в тій же країні), змінюючи встановлений кордон у міру необхідності.
Для вдосконалення цього підходу ви навіть можете зробити умову, при якій шістнадцятковий змінить трохи рандомізований варіант - замість того, щоб завжди «врівноважувати» дві країни, ви завжди можете робити своп з певною вірогідністю і навіть поступово зменшувати цю ймовірність над час (подібний до процесу охолодження в алгоритмі імітаційного відпалу ), щоб почати змушувати їх бути приблизно однакового розміру.
Зверніть увагу, що це не гарантує, що всі області точно однакового розміру (що неможливо, якщо N все одно не розділяє розмір вашої сітки), і навіть не гарантуватиме, що всі країни знаходяться в межах однієї шестигранної частини один одного в районі; він повинен гарантувати (запускати достатньо ітерацій), що кожна країна не більше ніж на один шестигранник більша або менша, ніж кожен з її безпосередніх сусідів.