-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
random -> numpy.random #146
Conversation
@@ -9,14 +9,13 @@ def setUp(self): | |||
pass | |||
|
|||
def test_random_point(self): | |||
for seed in [0, 1, 27, 29, 1939, 1982, 2015]: | |||
random.seed(seed) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was very much unnecessary unless the RNG is expected to be of very dubious quality. I chose to simplify it.
I might change some small things about this before uploading the new blessed ancient maps. Once that is done the tests should be fine again. |
It would be nice if somebody could look over the code; I think I touched all that is necessary, but this will need some polish, I presume. |
@@ -8,16 +8,6 @@ class TestBasicMapOperations(unittest.TestCase): | |||
def setUp(self): | |||
pass | |||
|
|||
def test_random_point(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method random_point() isn't used anymore so I removed it (and this test). It was an almost trivial method anyway.
It looks good to me |
|
||
if not step.include_precipitations: | ||
return w | ||
|
||
# Prepare sufficient seeds for the different steps of the generation | ||
rng = numpy.random.RandomState(w.seed) # create a fresh RNG in case the global RNG is compromised (i.e. has been queried an indefinite amount of times before generate_world() was called) | ||
sub_seeds = rng.randint(0, 4294967295, size=100) # sys.maxsize didn't quite work |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the use of this fixed number at all. Does somebody have a better idea? sys.maxint (or whatever it is called) is not available for Python 3; sys.maxsize returns a number that is not compatible with numpy (which takes a uint32).
the mountain generation is quite complicate. We have a mask to avoid overlapping mountains and a system to determine the size of each single mountain which is based on the elevation in the area. I am not sure if it is using the world seed. |
it seems we are not using any seed for the mountains BUT we are using it for the other masks. Basically we assign each pixel to some masks, ~one for biome, and then we draw that pixel accordingly. If any mask change it could affect how mountains are drawn |
I assume you are talking about this: def _draw_a_mountain(pixels, x, y, w=3, h=3):
# mcl = (0, 0, 0, 255) # TODO: No longer used?
# mcll = (128, 128, 128, 255)
mcr = (75, 75, 75, 255)
# left edge
for mody in range(-h, h + 1):
bottomness = (float(mody + h) / 2.0) / w
leftborder = int(bottomness * w)
darkarea = int(bottomness * w / 2)
lightarea = int(bottomness * w / 2)
for itx in range(darkarea, leftborder + 1):
pixels[x - itx, y + mody] = gradient(itx, darkarea, leftborder,
(0, 0, 0), (64, 64, 64))
for itx in range(-darkarea, lightarea + 1):
pixels[x + itx, y + mody] = gradient(itx, -darkarea, lightarea,
(64, 64, 64), (128, 128, 128))
for itx in range(lightarea, leftborder):
pixels[x + itx, y + mody] = (181, 166, 127, 255) # land_color
# right edge
for mody in range(-h, h + 1):
bottomness = (float(mody + h) / 2.0) / w
modx = int(bottomness * w)
pixels[x + modx, y + mody] = mcr Yes, this is complicated.^^ I worked through it a couple of days ago, but there is no directly visible use of something random (and the RNG in |
I will take another look at it tomorrow. We are very close to the goal already.^^ |
… before. Made small changes to seeding etc.
I think I found the cause for the remaining problems: def _mask(world, predicate, factor):
_mask = [[False for x in range(factor * world.width)] for y in
range(factor * world.height)]
for y in range(factor * world.height):
for x in range(factor * world.width):
xf = int(x / factor)
yf = int(y / factor)
if predicate((xf, yf)):
v = len(
world.tiles_around((xf, yf), radius=1,
predicate=predicate))
if v > 5:
_mask[y][x] = v
return _mask Apparently this map only stores integers in Python 2 (???) but floats in Python 3. It was going to be replaced by numpy anyway, I hope that will fix things. EDIT: Maybe Python 2 does not automatically typecast at this position? _mask[y][x] = v / 4 # v is an integer EDIT2: That last assumption seems to be right. I will just add a typecast, assuming that was the intended behaviour. If not, we can change that later.
|
I could use some help with the pyflakes- and manifest-tests since I don't think my changes make them fail. Mindwerks/worldengine-data#5 will take care of the problems with ancient maps. Other than the failing tests, this code is ready and could be reviewed, if anybody has the time. |
@@ -142,7 +140,7 @@ def _find_mountains_mask(world, factor): | |||
radius=3, | |||
predicate=world.is_mountain)) | |||
if v > 32: | |||
_mask[y][x] = v / 4 | |||
_mask[y, x] = v / 4.0 # force conversion to float, Python 2 will *not* do it automatically |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure which behaviour was the intended one here. The ancient map output looks different, I think the mountains are spread a little thinner for the old behaviour int(v/4)
.
Restarting tests after the changes to worldengine data |
I consider this passed.^^ It would be nice if this could be the next merge so I can cross this off my list and move on to finishing another branch (instead of having to come back here and rebase/fix things). |
import random | ||
|
||
|
||
def random_point(width, height): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it could be nice to have methods such as random_point
or perhaps random_land_point
but we could add it later if needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was only used once. Removing it allowed for another numpy-optimization; so for now this function would have been dead code (and since it is fairly simple anyway, rewriting it would be easy).
EDIT: I am talking about this optimization:
https://github.com/Mindwerks/worldengine/pull/146/files#diff-c341fcae944ab9ce9e38ea34a0165badR337
It is a very important one in my opinion.
Looks good to me. I would just leave a possibility to @psi29a to comment on it before merging but it is agreed that this one should be merged soon. A lot of great work on this one, thanks a lot! |
I hope I took proper care of your comments. |
I am satisfied, as I said I would just leave @psi29a the time to comment, if he wishes to do so. If not this is good to go for me. |
Let's start merging stuff |
No need to wait on me... I'm in the middle of moving so I'm MIA for a bit. |
Here the replacement of all uses of the random-module with respective numpy-methods.
Since this is kind of a break with save-compatibility and...everything, I guess, I also took the freedom to include some small changes so they aren't necessary in the future - I will add comments to the code to point them out and explain them.
Notes: