ID:1378492
 
(See the best response by Ter13.)
<b>Code:</b>
<dm>mob
Player
icon='Player.dmi'
verb
Random_Generation()
set category = "Actions"
new/turf/Grass1(usr.loc)
if ()


So, from the code above, I cannot figure out how to check surrounding turfs for what they are. I want to be able to check turfs, so that out of a percent, another type of tile can be placed. So far I've tried the following code, and have had no luck :

Code:
mob
Player
icon='Player.dmi'
verb
Random_Generation()
set category = "Actions"
new/turf/Grass1(usr.loc)
if (usr.loc turf=turf/Grass1)
usr.loc + (0,1,0) = turf/Grass2


Here are all of my turfs.



turf

Turf1
icon='Turf1.dmi'
density=0
Grass1
icon='Grass 1.dmi'
density=0
Grass2
icon='Grass 2.dmi'
Water1
icon='Water 1.dmi'
density=1
dirtwall1
icon='Dirt 1.dmi'
density=1
opacity=1




I've been unable to refer to any tile besides the one the user is standing on, seeing as how new I am to the more advanced coding. (Advanced for me, because I'm new in general.)My goal is to allow for each different turf to be placed down with the verb, in a 25x25 area, having each turf be placed according to the ones next to it. So, if water were down, it'd have a higher chance for water to be created next to it, while retaining a small chance of land being made.
Best response
Random generation is not an easy task. It's going to take some serious research, and it's going to be outside the scope of any post we can make here.

My advice would be to look at the fine article here for an idea of how some techniques are done.

http://www.emanueleferonato.com/2011/05/17/ using-cellular-automata-to-generate-random-land-and-water-ma ps-with-flash/
Thank you very much. I will get to researching right away.
Well random generation is a topic I'm just starting to learn myself, but aside from that there are errors in your code:

if(usr.loc turf=turf/Grass1)
usr.loc + (0,1,0) = turf/Grass2


Before you research procedural generation techniques, you need to research your DM syntax! This code causes compile errors meaning you can't even run the program!

loading scratchpad.dme
stuff.dm:8:error: turf: missing comma ',' or right-paren ')'
scratchpad.dmb - 1 error, 0 warnings


As you can see, it thinks you are missing a comma or parenthesis. It also says the problem is on line 8 (it's probably different in your code cuz I just copied that to a blank .dm file). The compiler is great at telling you the location of an error, but it doesn't necessarily know how to fix the problem - that is up to you. And no adding of commas or parenthesis will fix this code. What's wrong with it? Well, first press F1 and search topics for "if proc"

On that page they give you a very simple example of using an if()

Example:
if(T==1) world << "TRUE"
else world << "FALSE"

Notice that there are two equals sings! In DM, there is a difference between = and ==. A = B means you are telling the computer to set the variable A to whatever is on the other side, in this case B. If you write A == B, you are asking the computer whether A is equal to B or not. So:

if(usr.loc turf=turf/Grass1) //for the if statement
//we need ==

if(usr.loc turf == turf/Grass1) //I like to put spaces
// around operators for easier reading


That is closer, but still not correct. I'm not exactly sure what you meant with "usr.loc turf". The loc var is already a turf, unless you are inside another mob or obj or not on the map at all. I think what you meant is to test the type of the turf usr is standing on. And there's actually a built-in variable for just that:

if(usr.loc turf == turf/Grass1)

if(usr.loc.type == /turf/Grass1) //I also had to add two
// punctuation marks, a period and a slash. The period is
//used to read the 'type' variable belonging to 'loc',
//which itself is a variable read from 'usr'. The slash
//before turf was needed because that's just the way
//the type variable works - it always starts with a slash.


The line right after this is messed up too

usr.loc + (0,1,0) = turf/Grass2


First of all, (0,1,0) doesn't really mean anything. You could find the turf at a given location by using locate(x,y,z). If you wanted to make another grass turf based on the location of the first one, you should use a reference variable when creating the first turf like this:

var/turf/T = new /turf/Grass1(usr.loc)


Then the locate() proc can be used to find a turf one space north of T:

var/turf/anotherT = locate(T.x, T.y + 1, T.z)
anotherT = new /turf/Grass2() //no need for the location
//after new/turf/Grass2 ... we're already setting
//anotherT to a new turf

//you could also achieve the same thing as above like this:
locate(T.x, T.y + 1, T.z) = new /turf/Grass2()

//or

new /turf/Grass2(locate(T.x, T.y + 1, T.z))


I could have put usr there instead of T, but you just never know what will happen to the player or the usr variable, better to find the first turf and then just work off that.



Protip, Magic:

If you are going to be doing random generation of a lot of turfs, my advice would be to not use locate, but rather, to determine the total area you are going to be randomizing, then use block().

From there, you can access turfs by location within the list using standard pos = y*width+x <-> x=pos%width,y=round(pos/width) math.

locate() is relatively slow, whereas indexing an array of turfs is significantly faster.
Of course. I also would not go around creating thousands of new turfs, when modifying the existing turfs is a lot faster.

If Wks60 cannot use the correct syntax with if() and new(), then the topic of random generation is completely over their head.

I don't mean any offence to you WKS, it's just that you really need to fully understand DM syntax in order to do anything. That does not mean memorizing the arguments for every procedure - what it means is that you should understand all of the punctuation, most of the operators, a lot of the built-in variables (especially the ones shared by all atoms), a big handful of the built-in procedures, and a few of the arguments that you will be supplying to those procedures. Since you will not always know this stuff you should hit F1 all the friggin time. I've been messing with DM for several years and I still press F1 about 50 times a day.

EDIT: In case you didn't know Wks, you can highlight a word (or just click so the typing cursor is in the word) and press F1 to quickly search for that in the topics tab.
Of course. I also would not go around creating thousands of new turfs, when modifying the existing turfs is a lot faster.

Most of the overhead actually comes from communicating the new appearances to interested clients, so changing existing turfs is really a moot point.

The issue I'm referring to, is using 10,000 locate() function calls (100x100x1 area) is inherently going to be slower than 10,000 array indexes and a single block() function call due to the nature of how BYOND's internal VM functions.
In response to Ter13
Ter13 wrote:
Most of the overhead actually comes from communicating the new appearances to interested clients, so changing existing turfs is really a moot point.

So are you saying that this:

for(var/turf/T in block(locate(1,1,1), locate(100,100,level)))
T = new whatever()


Would work as fast as this:

for(var/turf/T in block(locate(1,1,1), locate(100,100,level)))
T.icon_state = "whatever"
T.density = 1
T.opacity = 1
T.somethingelse = 42


?

They should be roughly equivalent.

BTW, The top example should be:

new whatever(T)