Câu trả lời:
Sử dụng cấu trúc như thế này để thể hiện một cây trong cơ sở dữ liệu:
#Talent
id parent description
1 0 Tackle
2 1 Kick
3 1 Punch
4 3 Fire Punch
Và một bảng khác để thể hiện tài năng có được trên mỗi người dùng
#UserTalent
id user talent
1 4 1
2 4 3
3 4 4
Bạn có thể kiểm tra các phụ thuộc tài năng theo chương trình bằng cách truy vấn bảng tài năng hoàn chỉnh và xây dựng một cây được liên kết. Bạn cũng có thể làm điều đó với SQL nhưng nó sẽ yêu cầu các mục con đệ quy hoặc nhiều truy vấn. Tốt hơn làm điều đó trong mã của bạn.
Nếu có nhiều phụ thuộc, ví dụ như Fire Punch
phụ thuộc vào Punch
AND Immolation
sử dụng hai bảng để biểu thị biểu đồ phụ thuộc:
#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
Tôi sẽ khuyên bạn nên sử dụng một cây trong đó mỗi nút đại diện cho một tài năng / kỹ năng cụ thể. Dựa trên việc người chơi có kiếm được tài năng hay không, tài năng con của nó có thể kiếm được. Ví dụ cấu trúc dữ liệu sau
class Talent {
std::vector<Talent*> children;
bool earned;
};
Để xác định tài năng nào mà người chơi có, bạn lấy tài năng gốc và đi xuống biểu đồ cho đến khi bạn đạt được các nút tài năng nơi kiếm được là sai. Điều này cũng sẽ tiết lộ những tài năng nào có sẵn để có được: tài năng đầu tiên trong mỗi chi nhánh từ tài năng gốc mà kiếm được là sai.
ptr_vector
có thể còn tốt hơn nữa.
Trong trò chơi của tôi, tôi làm như thế này:
Cơ sở dữ liệu:
Reference_talent : chứa một ID duy nhất, tên, hiệu ứng, v.v.
tài năng : id, playerid <- chứa tất cả tài năng người chơi đã "học".
Ingame: (trên máy chủ)
Tôi tải lên tất cả các tham chiếu trong một 'tĩnh' (chỉ đọc) std :: map để tôi có thể truy cập chúng dễ dàng bằng id của họ.
Khi một khách hàng kiểm tra một người chơi, tôi nhận được tất cả các tài năng từ cơ sở dữ liệu và lưu trữ chúng trong một std :: vector để khi tôi cần tính toán các đặc điểm, v.v. Tôi có chúng trong RAM. Tôi cũng gửi đi những tài năng cho khách hàng.
Đó là về điều đó (ngoại trừ việc tiết kiệm những tài năng mới tất nhiên chỉ là một 'CHERTN' trong bảng 'tài năng' + một thông điệp cho khách hàng).
Bạn mô tả nó như là mối quan hệ giữa các trình mở khóa và mở khóa tương tự như trong hướng dẫn này . Tôi đề nghị tìm hiểu thêm về đại số quan hệ và cơ sở dữ liệu. Họ là cách tốt đẹp để mô hình dữ liệu. Nếu bạn học cách truy vấn thông tin từ cơ sở dữ liệu Bạn có thể mô hình hóa dữ liệu khá dễ dàng.
Tôi không biết bạn biết bao nhiêu về mô hình quan hệ. Hướng dẫn đó sẽ giúp bạn với nó.
Tôi cho rằng WoW hoạt động như trong thực tế (ehm), rằng nó là
Đó là mối quan hệ N: N, ngụ ý Bạn cần "người trung gian" một mối quan hệ mới giữa hai tài năng:
(talent who unlocks id, talent who is unlocked)
Bằng cách này, bạn có thể có tài năng A mở khóa B, C và D ((A, B), (A, C), (A, D)) và tài năng Y được mở khóa bởi X, Z và W ((X, Y), ( Z, Y), (W, Y)). Trong ngôn ngữ mệnh lệnh / thủ tục / hướng đối tượng Bạn sẽ thực hiện dưới dạng danh sách / mảng các cặp như ở đó:
var unlocks_unlocked = [[A, B],[A,C],[A,D],[X,Y],[Z,Y],[W,Y]];
Vì vậy, ví dụ "thế giới thực" Bạn có thể có:
... ["running fast", "jumping superhigh"], ["antigravity's child", "jumping superhigh"]
và nó có nghĩa là "nhảy siêu cao" có được sau khi bạn có tài năng "chạy nhanh" và "chống trẻ em".
Gần đây tôi chưa chơi Diablo nhưng có thể là nó chỉ có:
Đó là mối quan hệ 1: N:
You put "is unlocked by this talent's id" variable into talent's structure
như:
var Talent[8] = { "name": "superpower", "unlocked by": "being Clark Kent"};
UserTalent
Bảng của bạn không cần cột autokey.user
vàtalent
có thể là hai cột duy nhất và khóa tổng hợp: chúng sẽ không bao giờ trùng lặp vàid
dù sao bạn cũng sẽ không bao giờ truy vấn .