Take notice at the below screenshot. I made a land generator and I'm wondering how I can define the large/medium land masses as "Continent1","Continent2","Continent3" and so on and the tinier land masses as "Island1","Island2","Island3" etc.
Note: Islands will be bigger than this, because it will have different size maps. I need to know how to calculate the "large/medium" and "small" and define them as separate masses of land.
1
2
ID:272426
Jul 7 2008, 4:54 pm (Edited on Jul 8 2008, 5:18 am)
|
|
Jul 7 2008, 5:04 pm (Edited on Jul 7 2008, 5:43 pm)
|
|
Datums, as usual, will come in handy here.
|
In response to Popisfizzy
|
|
alright, also. At what point would i go about creating a new datum?
|
In response to Chibi-Gohan0
|
|
Oh, whoops, I forgot to handle that. In that case, alter /land_mass.New() to this:
New(turf/start, b = null, list/l = null) Then do this: proc/get_land_masses() Depending on the size of the generated map, this could get processor intensive (I don't know how to write other searching algorithms, so there may be better ways). I'd throw a sleep(-1) in the for loop, or possible the recursive loop. There's a small chance that you could end up with a large land mass, which would make the recursive loop intensive. |
In response to Popisfizzy
|
|
Sounds great, I'll test later for the intensive loops, but i believe you also forgot one thing. How would I name each mass (name generator or whatever) "Continent1" etc.
Ie it finds a continent and name it "United States of Frankford". (I'm not asking for a name generator, but instead a way to name it, and even search for it.) ...Or can i just use the name variable for that? |
In response to Chibi-Gohan0
|
|
land_mass The tag is set up so you can just use locate() to find the land_mass object. |
In response to Popisfizzy
|
|
Okay, so while its all good and dandy at compile time. I tried it out at runtime and i get this error:
proc name: CheckType (/land_mass/proc/CheckType) runtime error: Cannot write to list.land_mass. proc name: Add (/land_mass/proc/Add) runtime error: type mismatch: cannot compare /list (/list) to 50 and i get it repeatedly. |
In response to Chibi-Gohan0
|
|
Er, whoops. The line in /land_mass.CheckType() should be components.len > [...]
|
In response to Popisfizzy
|
|
Still get a similar error.
runtime error: Cannot write to list.land_mass. proc name: Add (/land_mass/proc/Add) usr: Chibi-Gohan0 (/mob/Player) src: /land_mass (/land_mass) call stack: /land_mass (/land_mass): Add(/list (/list)) /land_mass (/land_mass): GetComponents(Land (11,1,1) (/turf/Land)) /land_mass (/land_mass): New(Land (11,1,1) (/turf/Land), null, null) get land masses() Chibi-Gohan0 (/mob/Player): Generator() |
In response to Chibi-Gohan0
|
|
There's no error listen, so I can't help you. You probably copy/pasted wrong.
|
In response to Popisfizzy
|
|
Popisfizzy wrote:
There's no error listen, so I can't help you. You probably copy/pasted wrong.Alright, Thanks for the help. |
I'll take a more first-principles look at it than Pop here.
Basically, you're trying to find continents on your map. This is the same as a computer-science problem called 'connected components' - you can imagine your map is a graph, where each turf has a 'link' to every other turf you can move to from there - but, importantly, there is no link between a turf and water, because you can't move into water. So you're trying to find out how many sub-maps there are, and how big they are. A simple solution: - Put all the land turfs on your graph in a list. - Step through each turf, find all the turfs reachable from it, and add them to the landmass, then remove them from the list of all turfs - that is one continent - repeat until there are no more turfs left. Labelling something as an 'island' or 'continent' is just a matter of how many turfs there are. Note that this is basically Pop's approach. landmass Uncommented and untested. It should at least compile. It assume your 'land' turf is called '/turf/land', and that water is dense and land is not - this may cause issues with, say, trees or mountains being considered ocean. You should consider implementing an 'isLand()' proc. To name the landmasses this generates, you'll need to extend the landmasses datum. Hopefully this is helpful. Good luck. EDIT: Decided I should probably test it, realised that I'm a bit rusty when I ran headlong into, first, DM lists starting at 1, not 0, and second, not being able to change a list you're looping over. This is a fixed, semi-tested version that you can just drop into a new project and fiddle with the 'test' verb outputs the number of landmasses in the world. Have fun fiddling. |
In response to Jp
|
|
Jp wrote:
'connected components' - you can imagine your map is a graph, where each turf has a 'link' to every other turf you can move to from there - but, importantly, there is no link between a turf and water, because you can't move into water. Did you forget to fill in the link, or was it on purpose? Either way, the topic discussing this should be linked. |
In response to Kaioken
|
|
Errr... actually, I tried to link to the Wikipedia article, and have no idea how that BYOND post is what came out.
|
In response to Jp
|
|
I suppose that'd be because you forgot (or otherwise on accident) to fill the href attribute, and since there is no "http://" in the beginning of the URL, it takes it in as a local path, and since there's nothing there it links to the same page. =P
|
In response to Jp
|
|
While that would do most of what i need, it still misses the point of figuring if its an island or a continent, then naming it, so that i can come back later and look it up under a certain name (it being one list of land mass all under the same name).
|
In response to Chibi-Gohan0
|
|
Those are extensions I left to you. :P.
A quick explanation of how I would go about that - with no code this time, just a description. The 'landmass' datum needs a 'name' var, and the following procedures: getName() setName() getSize() isIsland() isContinent() That do basically what they say on the tin. Getting and setting a name is easy, the 'size' of a landmass can just be the length of its turf list - that's the area of it, basically. Whether it's an island or a continent is a fuzzy question - something for which fuzzy logic would be quite useful - but if you just need a crisp answer, saying that anything below a certain size is an island, everything above is a continent is the easy and obvious way to do it. If you want to be able to get landmasses by name (e.g., continent["europe"]), you'll need to construct an associative list of continent name associated with the continent reference - that's easy enough to do. |
In response to Jp
|
|
hmm i'm not getting it fully. Lets say i have a bunch of land turfs, all of which are all processed though that system. How would i go about getting the datum's info by clicking that turf? When i try doing something similar i always get a turf for a result instead of a the landmass datum.
For example, for(var/landmass) This will allways give me a turf for the output, not the desired datum. and it cant find the datum's name variable Its a compile time error. landmass This is just an example though. |
In response to Chibi-Gohan0
|
|
I added things for you.
landmass |
In response to Jemai1
|
|
That doesn't work.
Click() Land.dm:23:? :warning: statement has no effect Not to mention that in addturfs() you put turf.landmass instead of k.landmass |
1
2