게임에서 임의의 호수와 강을 어떻게 생성 할 수 있습니까?


19

나는 2D 블록 빌딩 게임을 가지고 있으며 무작위로 생성 된 호수와 강을 만들려고합니다. Perlin 노이즈 알고리즘을 살펴 봤지만 무작위로 멋진 결과를 얻을 수 없었습니다.

파이썬 노이즈 라이브러리 를 사용하려고 했지만 맵을 무작위로 만들지 않았습니다.

라이브러리에서 좀 더 무작위로 만들기 위해 누락 된 시드 함수가 있습니까? 좀 더 랜덤하게하려면 어떤 변수를 변경해야합니까? 가능하다면 수학과 파이썬 용어가 적어 기술적으로 덜 답하십시오.

지도는 2D 타일지도입니다. 다음은 다른 알고리즘의 비 랜덤성에 대한 몇 가지 예입니다. 다음 코드는 3 번 연속 출력되었습니다. 옥타브와 주파수를 다음과 같이 무작위로 지정했습니다.freq = 16.0 * random.randint(1, 500000) * 0.000001 + 0.5

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1
1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

위의 출력을 생성 한 코드는 다음과 같습니다.

"""Writes a 256x256 grayscale simplex noise texture file in pgm format
(see http://netpbm.sourceforge.net/doc/pgm.html)
"""
# $Id: 2dtexture.py 21 2008-05-21 07:52:29Z casey.duncan $

import sys
from noise import pnoise2
import random
octaves = random.randint(1, 500000) * 0.000001 + 0.5
freq = 16.0 * octaves
for y in range(30):
    for x in range(40):
        n = int(pnoise2(x/freq, y / freq, 1)*10+3)
        if n>=1:
            n=1
        else:
            n=0
        print n,
    print

더 많은 정보를 부탁드립니다. 이 질문은 현재 상태에서는 대답 할 수 없습니다.
Gustavo Maciel

조금 더 추가했지만 무엇을 알아야합니까?
율리우스

좋은 정보를 추가했지만 조금 더 필요합니다. "매우 무작위 적이 지 않은"이란 무엇입니까? 우리에게 어떤 스크린 샷이 주어진 결과가 무엇인지, 원하는 결과는 무엇입니까? 어떻게 해봤 어? 우리에게 보여줄 코드가 있습니까? 당신의 상황은 무엇입니까? 2D 또는 3D? 타일 ​​또는 다각형? 이 모든 것이 너무 많으면 미안하지만, 나는 단지 돕기 위해 노력하고 있습니다. -1은 내 것이 아니 었습니다. 정보를 제공하지 않으면 질문이 사이트에 적합하지 않게되어 닫힙니다. 다시 한 번 도와 드리려고합니다.
Gustavo Maciel

2
+1, 이제 좋은 질문입니다 :) 나는 perlin 노이즈와 모든 절차 적 생성에는 좋지 않지만 임의의 객체를 시드하고 있습니까? 내가 실수하지 않으면 random.seed()시스템 시간이 시드로 사용됩니다. 그리고 octaves = random.randint(1,500000)*.000001+.5당신은 시도 할 수 있습니다 : octaves = random.random() (같은 결과를 얻으면 0에서 1 사이의 숫자를 얻을 수 있지만 500000 숫자보다 훨씬 더 많은 가능성이 있습니다.)
Gustavo Maciel

Thanks +1 :) :) 1 개의 댓글을 더하려고했지만 할 수 없습니다
Julian

답변:


7

글쎄, 당신은 난수 생성기를 시드 하지 않습니다 . 파이썬에서는 random.seed () 만으로 쉽게 수행 할 수 있습니다 .

그리고 당신도 1과 500000 사이의 숫자를 생성하고 0과 1 사이의 숫자로 만들고 있음을 알 수 있습니다. 그것은 기능적인 방법이지만 500000 가능성에 제한됩니다. random.random()이미 0에서 1 사이의 숫자를 생성하는 것이 더 낫지 만 훨씬 더 많은 가능성이 있습니다! 코드에서 알 수 있듯이 0.5와 1.0 사이의 숫자가 여전히 필요한 경우 다음을 수행 할 수 있습니다.(random.random() * 0.5) + 0.5

최종 코드는 다음과 같아야합니다.

import sys
from noise import pnoise2
import random
random.seed()
octaves = random.random()
# octaves = (random.random() * 0.5) + 0.5
freq = 16.0 * octaves
for y in range(30):
    for x in range(40):
        n = int(pnoise2(x/freq, y / freq, 1)*10+3)
        if n>=1:
            n=1
        else:
            n=0
        print n,
    print

그게 다야!


나는 파종이 그것과 어떤 관련이 있는지 명확하지 않습니다. 시드하지 않더라도 반복되는 난수는 여전히 임의입니다. 시드하지 않는 유일한 증상은 프로그램을 실행할 때마다 동일한 임의 순서 여야합니다 (매번 동일한 시드가 사용된다고 가정).
팀 홀트

1
귀하의 질문에 언급 된 것처럼 동일한 결과를 세 번 연속 으로 얻는다면 랜덤 생성기를 시드하지 않았기 때문일 가능성이 큽니다. 이를보고 문제점을 해결하는지 확인하십시오.
ashes999

아 나는 "3 번 연속으로"비트를 보지 못했다. "더욱 무작위로 만들기 위해 그 라이브러리에 시드 함수가 빠져있다"는 부분을 읽고 있었다. 예 : 비 반복 임의성에 대한 시딩
팀 홀트

8

이것은 특정 프로그래밍 질문에 대한 대답은 아니지만 호수와 강을 만드는 것이 물과 물 사이에 무작위로 물을 배치하는 것이 아니라는 점을 고려하십시오. 지형 높이-호수로 변하는 우울증 (분지) 및 높은 곳에서 낮은 곳으로 흐르는 물에 관한 것입니다.

당신이 호수와 의미를 하천 만들기의 좋은 예를 원하는 경우에, 당신은이 블로그 게시물을 체크 아웃 할 수 -> http://simblob.blogspot.com/2010/09/polygon-map-generation-part-1.html는 그것은이다 당신의 목표가 합리적으로 현실적인 수경법이라면 이런 종류의 것에 대한 좋은 참고 자료.


2

매우 간단합니다. 같은 맵을 3 회 이상 (또는 그 이상) 얻는다면 시드를 무작위 화하지 않았기 때문입니다.

이것은 무엇을 의미 하는가?

컴퓨터는 본질적으로 결정 론적 (비 랜덤)이므로 임의성을 시뮬레이트합니다. 실제로는 반복적으로 무작위입니다 ( "의사 난수 생성기"라고 부릅니다).

어떻게 작동합니까?

난수를 만들 때 "씨"를주는 옵션이 있습니다. 중요한 것은 항상 동일한 시드를 사용하는 경우 항상 동일한 순서로 동일한 순서의 임의의 숫자를 얻게됩니다. 항상. 이것은 좋거나 나쁠 수 있습니다.

귀하의 경우 무작위 생성기를 시드하지 않는 것처럼 보이고 기본적으로 동일한 시드를 얻습니다. 아마 날짜 / 시간의 일부 구성 요소를 사용합니다. 따라서 무작위로 추출하는 것이 좋습니다.

Gusatavo가 그의 답변에서 언급했듯이 random.seed () 를 호출해야합니다 . 문서에는 "X [기본 매개 변수]가 생략되거나 None현재 시스템 시간이 사용됩니다"라고 명시되어 있습니다. 이것으로 충분합니다.

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