Відповіді:
Використовуйте подібну структуру для представлення дерева в базі даних:
#Talent
id parent description
1 0 Tackle
2 1 Kick
3 1 Punch
4 3 Fire Punch
І ще одна таблиця для представлення набутих талантів на кожного користувача
#UserTalent
id user talent
1 4 1
2 4 3
3 4 4
Ви можете перевірити наявність залежностей від талантів програмно, запитуючи повну таблицю талантів та будуючи пов’язане дерево. Ви також можете зробити це за допомогою SQL, але це вимагатиме або рекурсивних підселектів, або безлічі запитів. Краще зробіть це у своєму коді.
Якщо є декілька залежностей, наприклад, наприклад, Fire Punch
залежить від Punch
AND, Immolation
використовуйте дві таблиці для представлення графіка залежності:
#Talent
id description
1 Tackle
2 Kick
3 Punch
4 Fire Punch
5 Immolation
#Depedency
id parent child
1 0 1
2 0 5
3 1 2
4 1 3
5 3 4
6 5 4
Я б рекомендував використовувати дерево, де кожен вузол представляє певний талант / вміння. Виходячи з того, заробив гравець талант чи ні, його дитячі таланти можна заробити. Наприклад, наступна структура даних
class Talent {
std::vector<Talent*> children;
bool earned;
};
Щоб визначити, які таланти має гравець, ви берете корінний талант і спускаєтесь по графіку, поки не досягнете вузлів талантів, де зароблений неправдивий. Це також виявить, які таланти доступні для отримання: перший талант у кожній гілці вниз від кореневого таланту, де зароблений помилковий.
ptr_vector
може бути навіть краще.
У своїй грі я роблю це так:
База даних:
reference_talent : містить унікальний ідентифікатор, ім'я, ефект тощо
талант : id, playerid <- містить усі таланти, яких гравці "засвоїли".
Ingame: (на сервері)
Я завантажую всі reference_talents у "статичну" (тільки для читання) std :: карту, щоб я міг легко отримати доступ до них за своїм ідентифікатором.
Коли клієнт перевіряє гравця, я отримую всі таланти з бази даних і зберігаю їх у std :: vector, щоб, коли мені потрібно обчислити характеристики тощо, я маю їх в оперативній пам'яті. Я також розсилаю таланти клієнту.
Це про це (за винятком заощадження нових талантів, звичайно, це просто "ВСТАВКА" в таблиці "талант" + повідомлення клієнту).
Ви описуєте це як відношення між розблокувальними і розблокованими аналогічно, як у цьому підручнику . Я пропоную дізнатися більше про реляційну алгебру та бази даних. Вони є гарним способом моделювання даних. Якщо ви навчитеся запитувати інформацію з бази даних, ви можете легко моделювати дані.
Я не знаю, скільки ви знаєте про моделювання відносин. Цей підручник повинен вам у цьому допомогти.
Я припускаю, що WoW працює як насправді (ем), що це так
Саме відношення N: N означає, що вам потрібно "середня людина", нове відношення між двома талантами:
(talent who unlocks id, talent who is unlocked)
Таким чином, ви можете мати талант A, який розмикає B, C і D ((A, B), (A, C), (A, D)) і талант Y, розблокований X, Z і W ((X, Y), ( Z, Y), (W, Y)). Імперативною / процедурною / об'єктно-орієнтованою мовою ви зробите це як список / масив пар, як там:
var unlocks_unlocked = [[A, B],[A,C],[A,D],[X,Y],[Z,Y],[W,Y]];
Отже, для прикладу "реального світу" Ви можете мати:
... ["running fast", "jumping superhigh"], ["antigravity's child", "jumping superhigh"]
і це означає, що "стрибки надвисокої" отримуються після того, як у вас є таланти "швидкого бігу" і "антигравітації дитини".
Я не грав у Diablo останнім часом, але, можливо, у нього було тільки:
Це відношення 1: N:
You put "is unlocked by this talent's id" variable into talent's structure
подібно до:
var Talent[8] = { "name": "superpower", "unlocked by": "being Clark Kent"};
UserTalent
таблиці немає потреби в стовпці автоматичного ключа.user
і цеtalent
можуть бути лише два стовпчики та складений ключ: вони ніколи не будуть копіями, і ви ніколи неid
запитаєте.