Diablo / WoW 스타일 인재 트리에는 어떤 데이터 구조를 사용해야합니까?


23

월드 오브 워크래프트에서 볼 수있는 것과 비슷한 온라인 RPG를위한 재능 트리 시스템을 구현하려고합니다. 기술을 습득하면 트리에서 그 아래에있는 "계층"이 잠금 해제됩니다.

누구나 데이터베이스 / 코드에서이를 구조적으로 구현하는 가장 좋은 방법을 알고 있습니까?

답변:


13

데이터베이스에서 트리를 나타내려면 다음과 같은 구조를 사용하십시오.

#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에 따라 PunchAND 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

귀하의 UserTalent표는 자동 키 열 필요가 없다. user그리고 talent유일하게 두 개의 열 및 복합 키가 될 수 있습니다 그들은 중복 수 없으며 당신이 쿼리 않습니다 id어쨌든.
doppelgreener

나는 데이터베이스 디자이너가 아니며 나는 이것에 대한 말을 듣고 싶습니다 : 모든 재능이 독특한 이름을 가지고 있다면,이 테이블 디자인에서 다른 모든 숫자 ID 필드를 제거하고 이름을 키로 사용할 수는 없습니다 ( 계단식으로 편집 한 내용이 있습니까?) 그렇게하는 데 상당한 비용이나 이점이 있습니까?
doppelgreener

3
@Jonathan Hobbs : 자동 증가 기본 ID는 항상 삭제 / 업데이트 작업에 적합합니다. 결코 느리지 않지만 종종 빠릅니다. 또한 행 크기는 중요하지 않습니다. 독특한 재능 이름의 경우에도 마찬가지입니다. 좋은 성능을 위해서는 고유 한 정수로만 테이블을 조인해야합니다. en.wikipedia.org/wiki/Database_normalization 등을 참조하십시오 .
Jonas Bötel

감사. 한때 알고 있었던 DB 디자이너는 자동 키가 악의적이며 피해야한다고 말했지만 그 경우에 해당하는지 또는 이유에 대해서는 명확하지 않습니다. 나는 그렇지 않다고 생각합니다.
doppelgreener

다중 사용자 편집 등을 지원하기 때문에 디자이너를위한 데이터베이스가 필요하지 않은 경우 데이터베이스를 사용하여이 데이터를 저장해야하는 실제적인 이유는 없습니다. 그렇지 않으면 방해가됩니다. (또한 DB 제공 키가 아닌 디자이너가 결정한 논리적 이름에 거의 참여하고 싶기 때문에 기본 자동 증가 키를 사용하지 않을 것입니다.)

5

각 노드가 특정 재능 / 기술을 나타내는 트리를 사용하는 것이 좋습니다 . 플레이어가 재능을 얻었는지 여부에 따라 해당 자식 재능을 얻을 수 있습니다. 예를 들어 다음 데이터 구조

class Talent {
    std::vector<Talent*> children;
    bool earned;
};

어떤 재능을 가진 플레이어를 결정하려면, 루트 재능을 가져 와서 획득 한 속성 노드에 도달 할 때까지 그래프를 아래로 내려갑니다. 이것은 또한 어떤 재능을 얻을 수 있는지를 보여줄 것입니다 : 각 지점의 첫 번째 재능은 근본 재능에서 얻은 재능이 거짓입니다.


기본 배열과 크기에 대한 포인터가 있습니까? 자체 소유 한 자체 크기 조정 포인터를 사용하지 마십시오.
DeadMG

으악 ... C / C ++ 믹스 업 및 오류. 내 답변을 업데이트했습니다. 헤드 업 주셔서 감사합니다.
유령

@DeadMG : '자기 자체 크기 조정'이란 정확히 무엇을 의미합니까? 위의 벡터와 같은 것을 언급하고 있습니까, 아니면 다른 것을 생각하고 있었습니까?
Kylotan

부스트 ptr_vector가 더 나을 수도 있습니다.
Zan Lynx

5
트리 구조는 플레이어가 획득했는지 여부와는 완전히 분리되어야하며 전자는 디자이너가 만든 정적 데이터이고 후자는 세이브 게임 또는 DB에 저장된 플레이어 별 데이터입니다.

1

내 게임에서 나는 다음과 같이한다 :

데이터 베이스:

reference_talent : 고유 한 ID, 이름, 효과 등을 포함합니다

talent : id, playerid <-플레이어가 "학습"한 모든 재능을 포함합니다.

인게임 : (서버에서)

모든 reference_talents를 '정적'(읽기 전용) std :: map에로드하여 ID로 쉽게 액세스 할 수 있습니다.

클라이언트가 플레이어를 체크 아웃하면 데이터베이스에서 모든 재능을 가져 와서 std :: vector에 저장하여 특성 등을 계산해야 할 때 RAM에 저장합니다. 또한 재능을 고객에게 전합니다.

그것은 'talent'테이블의 'INSERT'+ 고객에게 보내는 메시지 인 새로운 재능을 제외하고는 제외됩니다.


0

관계형 접근

이 자습서에서와 마찬가지로 잠금 해제 프로그램과 잠금 해제 기능의 관계 로 설명합니다 . 관계형 대수와 데이터베이스에 대해 더 많이 배우는 것이 좋습니다. 데이터를 모델링하는 좋은 방법입니다. 데이터베이스에서 정보를 쿼리하는 방법을 배우면 데이터를 매우 쉽게 모델링 할 수 있습니다.

모델링 관계에 대해 당신이 얼마나 알고 있는지 모르겠습니다. 그 튜토리얼이 도움이 될 것입니다.

하나의 솔루션

와우는 현실에서와 같이 작동한다고 가정합니다 (ehm).

  • 재능은 여러 (다른) 재능을 잠금 해제
  • 재능은 여러 (다른) 재능에 의해 잠금 해제됩니다.

그것은 N : N 관계입니다. 그것은 당신이 "중간자"가 두 재능 사이의 새로운 관계를 필요로한다는 것을 암시합니다 :

(talent who unlocks id, talent who is unlocked)

이런 식으로 당신은 B, C, D ((A, B), (A, C), (A, D))를 잠금 해제하는 재능 A와 X, Z, W ((X, Y)에 의해 잠금 해제 된 재능 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"]

그것은 "빠른 달리기"와 "중력의 아이"재능을 가진 후에 "최고 점프"를 얻는다는 것을 의미합니다.

다른 솔루션

나는 최근에 디아블로를 연주하지 않았지만 그것이있을 수 있습니다 :

  • 재능은 다른 여러 재능을 잠금 해제
  • 하나의 재능으로 재능을 얻을 수 있습니다.

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"};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.