16 진수 그리드를 n 플레이어간에 균등하게 나누는 방법은 무엇입니까?


15

간단한 16 진수 그리드 기반 게임을 만들고 있으며 맵을 플레이어간에 균등하게 나누기를 원합니다. 지도는 무작위로 만들어졌으며, 플레이어들이 상대적으로 작은 면적으로 같은 양의 셀을 갖기를 원합니다. 예를 들어 맵에 4 명의 플레이어와 80 개의 셀이있는 경우 각 플레이어에는 약 20 개의 셀이 있습니다 (정확한 위치에있을 필요는 없음). 또한 각 플레이어는 인접한 셀을 4 개 이하로 가져야합니다. 즉, 맵이 생성 될 때 가장 큰 "청크"는 각각 4 개 이상의 셀이 될 수 없습니다.

나는 이것이 2 ~ 3 명의 플레이어에게 항상 가능하지는 않다는 것을 알고있다 (이것은 "지도 채색"문제와 유사하기 때문에). 그러나 4-8 명의 플레이어가이 문제에 어떻게 접근 할 수 있습니까?


셀룰러 오토마타는 다음과 유사한 간단한 방법입니다. 간단한지도, 4 가지 생물 군계 및이를 배포하는 방법
MichaelHouse

답변:


3

이것이 내가 할 일입니다.

  1. 모든 플레이어를 무작위 플레이어에게 할당하십시오. 큰지도에서는 ​​모든 플레이어에 대해 꽤 많은 수의 타일을 생성 할 가능성이 높으며, 작은지도에서는 ​​약간의 수정이 필요할 수 있습니다.
  2. 너무 큰 청크를 분리하십시오. 가장 쉬운 방법은 모든 타일을 청크로 가져 와서 각 타일을 임의로 할당하는 것입니다.
  3. 불균형 한 수의 셀이있는 경우 (예 : 플레이어 A에 24 개의 셀이 있고, 플레이어 B에 16이있는 경우), 과대 표 된 플레이어에서 저 대표 된 플레이어로 몇 개의 셀을 재 할당합니다.
  4. 청크가 있는지 다시 확인하십시오. 3 단계에서 새로운 청크를 도입 한 경우 2 단계로 돌아가십시오. 그렇지 않으면 멋진 맵입니다!

추신 : 나는이 문제가 불가능하다고 생각하지 않습니다.지도 채색 문제는 상당히 다릅니다 (한 가지 경우 색상-> 타일 할당 대신 모양-> 색상).
Junuxx

나는이 접근법을 꽤 좋아하지만 오랫동안 지역 크기의 균형을 맞추려고 시도 할 가능성이 없습니까?
manabreak

1
@manabreak : 내가 만든 무언가 를 시도 할 수 있습니다. 2 단계를 약간 변경하면 (임의로 재 할당하는 대신 모든 플레이어를 순환하여 재 할당) 상당히 잘 작동합니다. 시간이 있으면 써보도록하겠습니다.
Junuxx

1
그것은 내가 찾던 것을 정확하게 보여줍니다. :)
manabreak 2013 년

1

가정 당신의 hexmap이 n총 세포 및 p플레이어, p <= n이 문제를 해결하기 위해 할 수있는 가장 좋은 방법은 통해, 라운드 로빈 분배 를 통해 셀룰러 오토마타 (CA)을.

초기화

무작위로 (및 / 또는지도 중심으로부터의 거리와 같은 일부 또는 다른 휴리스틱을 사용하여) 각 플레이어의 시작 셀을 선택합니다. 이후 p <= n문제가되지 않습니다.

세포 성 오토마타

16 진수 셀간에 완전한 연결이 필요합니다. 셀 당 6 이웃 배열을 제안합니다.

class Cell
{
   //... other members...
   Cell[6] neighbours = new Cell[6];
}

고정 크기 배열을 사용하면 셀 사이의 지형 방향 개념이 존재할 수 있으며 목록이나 벡터는 그렇지 않습니다. 특정 탐색 작업을 더 쉽게 할 수 있으므로 권장합니다.

hexmap을 행당 오프셋과 함께 2D 배열에 저장할 수도 있습니다. 그러나 이것은 셀마다 이웃 배열을 저장하는 것보다 약간 직관적이지 않을 수 있습니다. 다른 모든 행의 기하학적 오프셋 때문입니다.

모든 셀이 이웃에있는 모든 것에 연결되어 있는지 확인하십시오. 전체 헥스 맵을 생성 할 때 행 단위, 셀 단위로이 행을 수행 할 수 있습니다. PS 직사각형이 아닌 경계로 된 16 진수 맵을 원한다면 개별 셀과 해당 셀에 대한 참조를 제거하여 음수 공간을 형성하여 유기적 인 맵 개요를 만들 수 있습니다.

라운드 로빈 배포

의사 코드 :

count number of neutral cells in entire map, minus those starting cells taken by players
while neutral cells remain (or while true)
   for each player
      if player has not yet reached expected territory size in cells
         for each cell already constituting this player's territory
           if territory can grow by one cell into a neutral neighbour
              grow into neighbour
              reduce neutral cell count for entire map by one
              if no more neutral cells remain in map
                 break out of outermost while loop immediately
              else
                 continue to next player immediately
begin game

이 알고리즘은 플레이어의 영토에 여전히 유효한 성장 공간 이있는 경우 각 플레이어에게 라운드 로빈 방식으로 영토를 하나씩 성장시킬 수있는 기회를 제공합니다 . 특정 선수가 더 성장하고 차단하는 경우, 알고리즘은이에도 불구하고 선수들의 영토 계속 증가 할 것입니다 않는 여전히 유효 성장 공간이있다. 한 플레이어가 한도에 도달하자마자 모든 플레이어를 같은 수의 셀로 쉽게 제한 할 수 있지만 원하는 경우 쉽게 알아낼 수 있어야합니다.

이것은 각 플레이어에 대해 최대 크기의 "가정 영토"를 제공합니다. "아일랜드"지역을 추가하고 싶은 경우 해당 플레이어의 셀 수 할당량을 충족하기 위해 플레이어가 성장할 로컬 공간이 부족하면 중립 셀 목록에서 새 시작 셀을 선택할 수 있습니다. 거기에서 같은 "성장"과정을 진행하십시오. 이 방법을 사용하면 임의의 노이즈가 아닌 각 플레이어마다 크기가 크고 일관된 섬 세트가 생깁니다.


알고리즘에 대한 훌륭한 문서와 의사 코드를 제공하지만 이것이 질문자가 요구하는 것과 일치하는지 확실하지 않습니다. 이 질문은 '가장 큰 "청크"는 각각 4 개 이상의 셀을 가질 수 없지만 알고리즘은 가능한 한 큰 연결 그룹을 만듭니다.
fnord

@fnord 아니요, 그렇지 않습니다. 내 대답을 제대로 읽지 못했습니다. 필자는 의사 코드에 명시 적으로 제한을 두었다. "플레이어가 아직 셀의 예상 영역 크기에 도달하지 않은 경우". downvote를 제거하십시오. 귀하의 의견과 의견 수렴이 있기 전의 사례임을 스스로 만족시키기 위해 질문의 개정 이력을 자유롭게 확인하십시오.
엔지니어

이 질문은 "4 개 이하의 인접 셀"을 갖도록 요청하지만 각 사용자가 맵의 예상 부분을 갖도록 요구합니다. 이것은 나에게 e가 Risk 게임이 모든 플레이어의 맵을 무작위로 배분하는 방식과 더 비슷한 것을 찾고 있음을 의미합니다. 귀하의 답변은지도를 "최대 크기의 '홈 지역'"으로 나눕니다. 예상되는 지역 크기 제한에 도달하면 알고리즘이 중지되지만 나중에 텍스트에서 언급하지만 해당 플레이어가 새로운 "섬"을 얻는 방법을 볼 수 없습니다.
fnord

@fnord 논리에 결함이 있습니다. 마지막 문장에서, 당신은 나의 알고리즘이 섬 크기에서 멈춘다는 것을 인정하고 n, 그 후에 당신이 "길을 보지 못한다"고 말하면서 "나중에 텍스트로 섬을 얻는 방법"이라고 말함으로써 자신과 모순된다. 질문에 대답하지 않았습니까? 이 일반화 된 알고리즘을 사용하여 셀을 산란하거나 ( n1 로 제한 ) 섬을 생성 할 수 있습니다 (n> 1로 설정). 따라서 하나의 단일 알고리즘에 산란 기능뿐만 아니라 그룹화 기능도 있습니다. 어떻게 이런 일이 않습니다 하지 영업의 질문에 대답? 공감 비가 어떻게 가치가 있습니까?
엔지니어

위의 설명을 편집하고 싶지만 너무 늦습니다. " 알고리즘에 방법이 없습니다 ". 나중에 텍스트에서 개념을 언급합니다.
fnord

0

또 다른 접근 방식은 '공평한'배포이지만 시작한 다음 시뮬레이트 어닐링과 유사한 접근 방식을 사용하여 공정성을 잃지 않고 규칙을 해제하는 것입니다.

  • 그리드의 모든 셀에 색상을 규칙적인 패턴으로 지정하십시오 (예 : 첫 번째 행에 반복되는 '123412341234'패턴, 그 다음에 '341234123412'등). 이지도는 특히 가난 모양의 경우 색상의 비 균일 한 분포로 이어질 수 있지만, 당신이 찾을 수 있어야합니다 그래서, 당신은 고정 된지도로 시작하고 있다는 추정하고있어 일부 그것의 균등 분포 정기적으로 색칠합니다.
  • 그런 다음 원하는만큼 많은 단계에 대해 다음 단계를 반복하십시오 (실제 '완료'기준이 없으므로 실험을 통해 최소의 적절한 단계 수가 무엇인지 알 수 있습니다).
    • 그리드의 두 요소를 무작위로 선택
    • 색상이 같은 경우 다시 시도하십시오 (그렇지 않으면 아무런 의미가 없습니다. 교환 할 때 아무런 문제가 없습니다. 동일한 색상을 칠 확률은 1/4이고 동일한 색상을 칠 확률은 1/16입니다. 두 번 연속해서 다시 시도하지 않아도됩니다)
    • 이 두 요소의 색상을 임시로 교환
    • 교체 후 요소 위치에서 새로 형성된 영역의 크기를 테스트하십시오.
      • 각 요소의 새 지점에서 바깥쪽으로 간단한 홍수 채우기를 수행하여 스왑이 해당 색상의 영역을 얼마나 크게 결정할 수 있습니다.
    • 이 두 지역 중 하나가 임계 값보다 큰 경우 임시 스왑을 실행 취소하십시오. 그렇지 않으면 두 요소의 색상 스왑을 '마침'합니다.

여기서 중요한 점은 두 지점을 교환한다는 사실은 색상의 균형을 맞추지 않으며, 교환을 완료하기 전에 수행 한 테스트로 너무 큰 영역을 만들지 않도록한다는 것입니다. 그리드를 표시 할 방법이 있다면이 프로세스를 시각화하여 반복 된 스왑을 통해 영역을 어떻게 '빌드'하는지 확인할 수도 있습니다.

균등 배분 된 일반 채색으로 시작할 수없는 경우 우연히 채색을 균등하게 분배하는 비슷한 작업을 수행 할 수 있어야합니다. 그런 다음 색상이 과도하게 표현 된 색상 중 하나 인 경우 해당 색상을 불완전하게 표현 된 색상 중 하나로 설정 한 다음 새로운 색상 영역을 너무 크게 생성하지 않는지 확인하십시오.


확률 론적 접근 방식은 비효율적입니다. 단계를 고려한 광산과 같은 접근법의 경우 런타임은 n 개의 맵 셀에 대해 O (n)에 접근합니다. 알고리즘의 경우 O (n * m)입니다. 여기서 m은 섬당 원하는 셀 수 (실제로 각 잠재적 섬에 대해)입니다. 쉽게 예측 가능한 런타임이있는 알고리즘을 목표로하는 것이 가장 좋습니다. 우연히 생성 된 맵을 수정하는 대신 처음부터 깨지거나 우연히 발생하지 않는 맵을 n 단계로 생성하는 것이 좋습니다. 따라서 제어되고 효율적인 프로세스를 유지합니다.
엔지니어
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.