1010
1111 noise = tcod.noise.Noise(
1212 dimensions=2,
13- algorithm=tcod.NOISE_SIMPLEX ,
14- implementation=tcod.noise.TURBULENCE,
13+ algorithm=tcod.noise.Algorithm.SIMPLEX ,
14+ implementation=tcod.noise.Implementation. TURBULENCE,
1515 hurst=0.5,
1616 lacunarity=2.0,
1717 octaves=4,
3131 samples = noise.sample_ogrid(ogrid)
3232 print(samples)
3333"""
34- from typing import Any , Optional
34+ import enum
35+ import warnings
36+ from typing import Any , Optional , Sequence , Union
3537
3638import numpy as np
3739
4042from tcod ._internal import deprecate
4143from tcod .loader import ffi , lib
4244
43- """Noise implementation constants"""
44- SIMPLE = 0
45- FBM = 1
46- TURBULENCE = 2
45+ try :
46+ from numpy .typing import ArrayLike
47+ except ImportError : # Python < 3.7, Numpy < 1.20
48+ from typing import Any as ArrayLike
49+
50+
51+ class Algorithm (enum .IntEnum ):
52+ """Libtcod noise algorithms.
53+
54+ .. versionadded:: 12.2
55+ """
56+
57+ PERLIN = 1
58+ """Perlin noise."""
59+
60+ SIMPLEX = 2
61+ """Simplex noise."""
62+
63+ WAVELET = 4
64+ """Wavelet noise."""
65+
66+ def __repr__ (self ) -> str :
67+ return f"tcod.noise.Algorithm.{ self .name } "
68+
69+
70+ class Implementation (enum .IntEnum ):
71+ """Noise implementations.
72+
73+ .. versionadded:: 12.2
74+ """
75+
76+ SIMPLE = 0
77+ """Generate plain noise."""
78+
79+ FBM = 1
80+ """Fractional Brownian motion.
81+
82+ https://en.wikipedia.org/wiki/Fractional_Brownian_motion
83+ """
84+
85+ TURBULENCE = 2
86+ """Turbulence noise implementation."""
87+
88+ def __repr__ (self ) -> str :
89+ return f"tcod.noise.Implementation.{ self .name } "
90+
91+
92+ def __getattr__ (name : str ) -> Implementation :
93+ if hasattr (Implementation , name ):
94+ warnings .warn (
95+ f"'tcod.noise.{ name } ' is deprecated,"
96+ f" use 'tcod.noise.Implementation.{ name } ' instead." ,
97+ DeprecationWarning ,
98+ stacklevel = 2 ,
99+ )
100+ return Implementation [name ]
101+ raise AttributeError (f"module { __name__ } has no attribute { name } " )
47102
48103
49104class Noise (object ):
@@ -59,8 +114,9 @@ class Noise(object):
59114
60115 Args:
61116 dimensions (int): Must be from 1 to 4.
62- algorithm (int): Defaults to NOISE_SIMPLEX
63- implementation (int): Defaults to tcod.noise.SIMPLE
117+ algorithm (int): Defaults to :any:`tcod.noise.Algorithm.SIMPLEX`
118+ implementation (int):
119+ Defaults to :any:`tcod.noise.Implementation.SIMPLE`
64120 hurst (float): The hurst exponent. Should be in the 0.0-1.0 range.
65121 lacunarity (float): The noise lacunarity.
66122 octaves (float): The level of detail on fBm and turbulence
@@ -74,21 +130,21 @@ class Noise(object):
74130 def __init__ (
75131 self ,
76132 dimensions : int ,
77- algorithm : int = 2 ,
78- implementation : int = SIMPLE ,
133+ algorithm : int = Algorithm . SIMPLEX ,
134+ implementation : int = Implementation . SIMPLE ,
79135 hurst : float = 0.5 ,
80136 lacunarity : float = 2.0 ,
81137 octaves : float = 4 ,
82- seed : Optional [tcod .random .Random ] = None ,
138+ seed : Optional [Union [ int , tcod .random .Random ] ] = None ,
83139 ):
84140 if not 0 < dimensions <= 4 :
85141 raise ValueError (
86142 "dimensions must be in range 0 < n <= 4, got %r"
87143 % (dimensions ,)
88144 )
89- self ._random = seed
90- _random_c = seed . random_c if seed else ffi . NULL
91- self . _algorithm = algorithm
145+ self ._seed = seed
146+ self . _random = self . __rng_from_seed ( seed )
147+ _random_c = self . _random . random_c
92148 self .noise_c = ffi .gc (
93149 ffi .cast (
94150 "struct TCOD_Noise*" ,
@@ -99,8 +155,35 @@ def __init__(
99155 self ._tdl_noise_c = ffi .new (
100156 "TDLNoise*" , (self .noise_c , dimensions , 0 , octaves )
101157 )
158+ self .algorithm = algorithm
102159 self .implementation = implementation # sanity check
103160
161+ @staticmethod
162+ def __rng_from_seed (
163+ seed : Union [None , int , tcod .random .Random ]
164+ ) -> tcod .random .Random :
165+ if seed is None or isinstance (seed , int ):
166+ return tcod .random .Random (
167+ seed = seed , algorithm = tcod .random .MERSENNE_TWISTER
168+ )
169+ return seed
170+
171+ def __repr__ (self ) -> str :
172+ parameters = [
173+ f"dimensions={ self .dimensions } " ,
174+ f"algorithm={ self .algorithm !r} " ,
175+ f"implementation={ Implementation (self .implementation )!r} " ,
176+ ]
177+ if self .hurst != 0.5 :
178+ parameters .append (f"hurst={ self .hurst } " )
179+ if self .lacunarity != 2 :
180+ parameters .append (f"lacunarity={ self .lacunarity } " )
181+ if self .octaves != 4 :
182+ parameters .append (f"octaves={ self .octaves } " )
183+ if self ._seed is not None :
184+ parameters .append (f"seed={ self ._seed } " )
185+ return f"tcod.noise.Noise({ ', ' .join (parameters )} )"
186+
104187 @property
105188 def dimensions (self ) -> int :
106189 return int (self ._tdl_noise_c .dimensions )
@@ -112,15 +195,16 @@ def dimentions(self) -> int:
112195
113196 @property
114197 def algorithm (self ) -> int :
115- return int (self .noise_c .noise_type )
198+ noise_type = self .noise_c .noise_type
199+ return Algorithm (noise_type ) if noise_type else Algorithm .SIMPLEX
116200
117201 @algorithm .setter
118202 def algorithm (self , value : int ) -> None :
119203 lib .TCOD_noise_set_type (self .noise_c , value )
120204
121205 @property
122206 def implementation (self ) -> int :
123- return int (self ._tdl_noise_c .implementation )
207+ return Implementation (self ._tdl_noise_c .implementation )
124208
125209 @implementation .setter
126210 def implementation (self , value : int ) -> None :
@@ -181,15 +265,15 @@ def __getitem__(self, indexes: Any) -> np.ndarray:
181265 c_input [i ] = ffi .from_buffer ("float*" , indexes [i ])
182266
183267 out = np .empty (indexes [0 ].shape , dtype = np .float32 )
184- if self .implementation == SIMPLE :
268+ if self .implementation == Implementation . SIMPLE :
185269 lib .TCOD_noise_get_vectorized (
186270 self .noise_c ,
187271 self .algorithm ,
188272 out .size ,
189273 * c_input ,
190274 ffi .from_buffer ("float*" , out ),
191275 )
192- elif self .implementation == FBM :
276+ elif self .implementation == Implementation . FBM :
193277 lib .TCOD_noise_get_fbm_vectorized (
194278 self .noise_c ,
195279 self .algorithm ,
@@ -198,7 +282,7 @@ def __getitem__(self, indexes: Any) -> np.ndarray:
198282 * c_input ,
199283 ffi .from_buffer ("float*" , out ),
200284 )
201- elif self .implementation == TURBULENCE :
285+ elif self .implementation == Implementation . TURBULENCE :
202286 lib .TCOD_noise_get_turbulence_vectorized (
203287 self .noise_c ,
204288 self .algorithm ,
@@ -212,7 +296,7 @@ def __getitem__(self, indexes: Any) -> np.ndarray:
212296
213297 return out
214298
215- def sample_mgrid (self , mgrid : np . ndarray ) -> np .ndarray :
299+ def sample_mgrid (self , mgrid : ArrayLike ) -> np .ndarray :
216300 """Sample a mesh-grid array and return the result.
217301
218302 The :any:`sample_ogrid` method performs better as there is a lot of
@@ -248,7 +332,7 @@ def sample_mgrid(self, mgrid: np.ndarray) -> np.ndarray:
248332 )
249333 return out
250334
251- def sample_ogrid (self , ogrid : np . ndarray ) -> np .ndarray :
335+ def sample_ogrid (self , ogrid : Sequence [ ArrayLike ] ) -> np .ndarray :
252336 """Sample an open mesh-grid array and return the result.
253337
254338 Args
0 commit comments